KEDA (Kubernetes Event-driven Autoscaling) WITH CRON
The Midnight Madness: A DevOps Scenario
The clock strikes 20:55. You are on a Zoom call with your DevOps team, and the silence is deafening. In exactly five minutes, at 21:00, the massive "Flash Sale" campaign begins. The marketing team has been pushing this for weeks, and push notifications are about to go out to millions of users.
Normally, your system is protected by the standard Kubernetes HPA (Horizontal Pod Autoscaler). The logic is simple and reactive: Traffic increases -> CPU usage spikes -> HPA detects the spike -> New Pods are requested.
But at 21:00:01, the scenario you fear unfolds: The traffic doesn't climb like a gentle ramp; it hits like a vertical wall.
In the critical 2-3 minutes it takes for HPA to wake up, request resources, and for new pods to pull images and reach "Ready" status, chaos ensues:
* Existing pods are crushed under the load, spiraling into CrashLoopBackOff.
* Users clicking "Add to Cart" are greeted with 503 Service Unavailable errors.
* Twitter starts flooding with complaints.
As you watch the monitoring dashboard, waiting helplessly for the new pods to spin up, you ask yourself: "We knew the exact time of the sale. Why did we wait for the traffic to hit us? Why weren't we there before the users?"
This is where the standard "Reactive" HPA fails. You need a "Proactive" solution. You need scaling based on the clock, not just the CPU.
Enter KEDA (Kubernetes Event-Driven Autoscaling) and the Cron Scaler. In this guide, we will teach your Kubernetes cluster to say, "Wake up at 20:55 and be ready for the storm."
What is KEDA ?
KEDA (Kubernetes Event-driven Autoscaling) is an open-source project that provides event-driven autoscaling capabilities in your Kubernetes environment. KEDA extends Kubernetes' HPA (Horizontal Pod Autoscaler) system, allowing you to scale your applications based on metrics beyond CPU and memory.
[Image of KEDA architecture diagram]
Table of Contents
- Prerequisites
- Installation
- Installation with Helm
- Installation with YAML
- Scaling with Cron
- Creating a ScaledObject
- Troubleshooting
- Contributing
- License
Prerequisites
- Kubernetes cluster (v1.16+)
kubectlCLI- (Optional) Helm 3
- Cluster admin privileges
Installation
Installation with Helm
# Add Helm repository
helm repo add kedacore [https://kedacore.github.io/charts](https://kedacore.github.io/charts)
helm repo update
# Create KEDA namespace
kubectl create namespace keda
# Install KEDA
helm install keda kedacore/keda --namespace keda
Installation with YAML
# Install the latest version
kubectl apply -f https://github.com/kedacore/keda/releases/download/v2.11.0/keda-2.11.0.yaml
Verify the installation:
Expected output:
NAME READY STATUS RESTARTS AGE
keda-operator-7c8d65d96d-bzmqp 1/1 Running 0 30s
keda-operator-metrics-apiserver-7d9fd868b5-kvppj 1/1 Running 0 30s
Scaling with Cron
Creating a ScaledObject
ScaledObject is the core component KEDA uses to scale Kubernetes deployments.
- Create a sample deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: cron-app
namespace: test
labels:
app: cron-app
spec:
replicas: 1
selector:
matchLabels:
app: cron-app
template:
metadata:
labels:
app: cron-app
spec:
containers:
- name: cron-app
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: cron-app-service
namespace: test
spec:
ports:
- port: 80
targetPort: 80
selector:
app: cron-app
Expected output:
- Define a ScaledObject:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: cron-app-scaledobject
namespace: test
spec:
scaleTargetRef:
name: cron-app
minReplicaCount: 1
maxReplicaCount: 20
triggers:
- type: cron
metadata:
# Timezone
timezone: "Europe/Amsterdam"
# Scaling start time (e.g., starts every day at 08:45)
start: "45 8 * * *"
# Scaling end time (e.g., ends every day at 08:50)
end: "50 8 * * *"
# Desired number of pods during this time range
desiredReplicas: "20"
Expected output:
NAME SCALETARGETKIND SCALETARGETNAME MIN MAX READY ACTIVE FALLBACK PAUSED TRIGGERS AUTHENTICATIONS AGE
cron-app-scaledobject apps/v1.Deployment cron-app 1 20 True Unknown False Unknown 18s
When the clock hits 08:45, the ScaledObject will activate and begin scaling the related service during the specified time range.
Expected output when the ScaledObject is triggered:
NAME READY STATUS RESTARTS AGE
cron-app-5df76bc88b-67krr 1/1 Running 0 7m8s
cron-app-5df76bc88b-fqffn 0/1 Pending 0 0s
cron-app-5df76bc88b-fqffn 0/1 Pending 0 0s
cron-app-5df76bc88b-8llrz 0/1 Pending 0 0s
cron-app-5df76bc88b-qk8qw 0/1 Pending 0 0s
cron-app-5df76bc88b-fqffn 0/1 ContainerCreating 0 0s
cron-app-5df76bc88b-qk8qw 0/1 ContainerCreating 0 0s
cron-app-5df76bc88b-8llrz 0/1 ContainerCreating 0 0s
cron-app-5df76bc88b-6ltbp 0/1 ContainerCreating 0 0s
cron-app-5df76bc88b-dbkzx 0/1 ContainerCreating 0 0s
cron-app-5df76bc88b-smfnl 0/1 ContainerCreating 0 0s
cron-app-5df76bc88b-29854 0/1 ContainerCreating 0 0s
cron-app-5df76bc88b-8llrz 1/1 Running 0 2s
cron-app-5df76bc88b-fqffn 1/1 Running 0 3s
cron-app-5df76bc88b-smfnl 0/1 Pending 0 0s
cron-app-5df76bc88b-smfnl 1/1 Running 0 2s
cron-app-5df76bc88b-6ltbp 1/1 Running 0 3s
cron-app-5df76bc88b-dbkzx 1/1 Running 0 4s
...
k get pod -n test
NAME READY STATUS RESTARTS AGE
cron-app-5df76bc88b-29854 1/1 Running 0 69s
cron-app-5df76bc88b-67krr 1/1 Running 0 9m20s
cron-app-5df76bc88b-6ltbp 1/1 Running 0 69s
cron-app-5df76bc88b-8llrz 1/1 Running 0 84s
cron-app-5df76bc88b-9mxl8 1/1 Running 0 54s
cron-app-5df76bc88b-c9lrj 1/1 Running 0 54s
cron-app-5df76bc88b-dbkzx 1/1 Running 0 69s
...
Expected output after the specified time range ends:
cron-app-5df76bc88b-c9lrj 1/1 Terminating 0 9m16s
cron-app-5df76bc88b-jnpm6 1/1 Terminating 0 9m16s
cron-app-5df76bc88b-8llrz 1/1 Terminating 0 9m46s
cron-app-5df76bc88b-fqffn 1/1 Terminating 0 9m46s
cron-app-5df76bc88b-67krr 1/1 Terminating 0 17m
cron-app-5df76bc88b-pxwn4 1/1 Terminating 0 9m1s
cron-app-5df76bc88b-mk6d2 1/1 Terminating 0 9m1s
cron-app-5df76bc88b-xxhz9 1/1 Terminating 0 9m1s
...
cron-app-5df76bc88b-67krr 0/1 Completed 0 17m
cron-app-5df76bc88b-pxwn4 0/1 Completed 0 9m3s
cron-app-5df76bc88b-mk6d2 0/1 Completed 0 9m3s
cron-app-5df76bc88b-9mxl8 0/1 Completed 0 9m18s
cron-app-5df76bc88b-jnpm6 0/1 Completed 0 9m18s
cron-app-5df76bc88b-xxhz9 0/1 Completed 0 9m3s
...
Troubleshooting
To troubleshoot KEDA issues:
# Check KEDA operator logs
kubectl logs -l app=keda-operator -n keda
# Check metrics server logs
kubectl logs -l app=keda-metrics-apiserver -n keda
# Check ScaledObject status
kubectl describe scaledobject cron-app-scaledobject -n test
# Check HPA status
kubectl get hpa -n test
kubectl describe hpa keda-hpa-cron-app-scaledobject -n test
Contributing
To contribute to the KEDA project, you can submit a pull request via GitHub.
License
KEDA is distributed under the Apache 2.0 licance.