KEDA (Kubernetes Event-Driven Autoscaling) Cheatsheet¶
Installation¶
| Platform/Method | Command |
|---|---|
| Helm (Recommended) | helm repo add kedacore https://kedacore.github.io/charts && helm repo update && helm install keda kedacore/keda --namespace keda --create-namespace |
| YAML Manifest | kubectl apply --server-side -f https://github.com/kedacore/keda/releases/download/v2.12.0/keda-2.12.0.yaml |
| Specific Version | helm install keda kedacore/keda --namespace keda --create-namespace --version 2.12.0 |
| macOS (Prerequisites) | brew install kubectl helm |
| Windows (Prerequisites) | choco install kubernetes-cli kubernetes-helm |
| OpenShift OperatorHub | Navigate to: Operators → OperatorHub → Search "KEDA" |
| Upgrade Existing | helm upgrade keda kedacore/keda --namespace keda |
| Uninstall | helm uninstall keda --namespace keda |
Verification Commands¶
| Command | Description |
|---|---|
kubectl get pods -n keda |
Check KEDA components are running |
kubectl get crd \| grep keda.sh |
Verify KEDA CRDs are installed |
kubectl get deployment keda-operator -n keda |
Check KEDA operator deployment |
kubectl get apiservice v1beta1.external.metrics.k8s.io |
Verify metrics API service |
Basic Commands¶
ScaledObject Management¶
| Command | Description |
|---|---|
kubectl get scaledobjects |
List all ScaledObjects in current namespace |
kubectl get so |
List ScaledObjects (short form) |
kubectl get scaledobjects -A |
List ScaledObjects across all namespaces |
kubectl get scaledobjects -n production |
List ScaledObjects in specific namespace |
kubectl describe scaledobject <name> |
Show detailed information about a ScaledObject |
kubectl get scaledobject <name> -o yaml |
View ScaledObject YAML configuration |
kubectl get scaledobjects -w |
Watch ScaledObject status changes in real-time |
kubectl delete scaledobject <name> |
Delete a ScaledObject |
kubectl edit scaledobject <name> |
Edit ScaledObject configuration |
kubectl apply -f scaledobject.yaml |
Create/update ScaledObject from file |
ScaledJob Management¶
| Command | Description |
|---|---|
kubectl get scaledjobs |
List all ScaledJobs in current namespace |
kubectl get sj |
List ScaledJobs (short form) |
kubectl get scaledjobs -A |
List ScaledJobs across all namespaces |
kubectl describe scaledjob <name> |
Show detailed information about a ScaledJob |
kubectl get scaledjob <name> -o yaml |
View ScaledJob YAML configuration |
kubectl delete scaledjob <name> |
Delete a ScaledJob |
kubectl get jobs |
View Jobs created by ScaledJob |
kubectl logs job/<job-name> |
View logs from ScaledJob-created Job |
Authentication Management¶
| Command | Description |
|---|---|
kubectl get triggerauthentication |
List TriggerAuthentications |
kubectl get ta |
List TriggerAuthentications (short form) |
kubectl describe triggerauthentication <name> |
Show TriggerAuthentication details |
kubectl get clustertriggerauthentication |
List ClusterTriggerAuthentications |
kubectl get cta |
List ClusterTriggerAuthentications (short form) |
kubectl delete triggerauthentication <name> |
Delete a TriggerAuthentication |
kubectl create secret generic <name> --from-literal=key=value |
Create secret for TriggerAuthentication |
Monitoring and Status¶
| Command | Description |
|---|---|
kubectl get hpa |
View HPAs created by KEDA |
kubectl describe hpa keda-hpa-<name> |
Show HPA details for scaled resource |
kubectl get events --sort-by='.lastTimestamp' |
View recent scaling events |
kubectl logs -n keda deployment/keda-operator -f |
Follow KEDA operator logs |
kubectl logs -n keda deployment/keda-operator-metrics-apiserver -f |
Follow metrics server logs |
kubectl top pods |
View current pod resource usage |
kubectl get deployment <name> |
Check current replica count |
Advanced Usage¶
Advanced ScaledObject Operations¶
| Command | Description |
|---|---|
kubectl annotate scaledobject <name> autoscaling.keda.sh/paused-replicas=3 |
Pause autoscaling at specific replica count |
kubectl annotate scaledobject <name> autoscaling.keda.sh/paused-replicas- |
Resume autoscaling (remove pause) |
kubectl patch scaledobject <name> -p '{"spec":{"minReplicaCount":5}}' |
Update minimum replica count |
kubectl patch scaledobject <name> -p '{"spec":{"maxReplicaCount":50}}' |
Update maximum replica count |
kubectl get scaledobject <name> -o jsonpath='{.status.conditions}' |
View ScaledObject status conditions |
kubectl get scaledobject <name> -o jsonpath='{.status.externalMetricNames}' |
View external metric names |
kubectl get scaledobject <name> -o jsonpath='{.status.scaleTargetKind}' |
View target resource kind |
KEDA Operator Management¶
| Command | Description |
|---|---|
kubectl scale deployment keda-operator -n keda --replicas=2 |
Scale KEDA operator for HA |
kubectl rollout restart deployment/keda-operator -n keda |
Restart KEDA operator |
kubectl rollout status deployment/keda-operator -n keda |
Check operator rollout status |
kubectl get deployment -n keda -o wide |
View KEDA component details |
helm show values kedacore/keda |
View available Helm configuration options |
helm get values keda -n keda |
View current Helm installation values |
helm upgrade keda kedacore/keda -n keda --set operator.replicaCount=2 |
Update KEDA configuration |
Metrics and Debugging¶
| Command | Description |
|---|---|
kubectl get --raw /apis/external.metrics.k8s.io/v1beta1 |
Query external metrics API |
kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1/namespaces/default/s0-<metric>" |
Query specific external metric |
kubectl describe apiservice v1beta1.external.metrics.k8s.io |
Check metrics API service status |
kubectl logs -n keda -l app=keda-operator --tail=100 |
View recent operator logs |
kubectl logs -n keda -l app=keda-operator-metrics-apiserver --tail=100 |
View recent metrics server logs |
kubectl get events -n keda |
View KEDA namespace events |
kubectl describe hpa -A \| grep -A 10 "keda-hpa" |
View all KEDA-managed HPAs |
Multi-Trigger and Complex Scenarios¶
| Command | Description |
|---|---|
kubectl get scaledobject <name> -o jsonpath='{.spec.triggers[*].type}' |
List all trigger types for a ScaledObject |
kubectl get scaledobject <name> -o jsonpath='{.status.health}' |
Check health status of triggers |
kubectl get scaledobject <name> -o jsonpath='{.status.lastActiveTime}' |
View last active time |
kubectl get scaledobject <name> -o jsonpath='{.status.currentReplicas}' |
View current replica count |
kubectl get scaledobject <name> -o jsonpath='{.status.desiredReplicas}' |
View desired replica count |
Configuration¶
Basic ScaledObject Configuration¶
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: my-scaledobject
namespace: default
spec:
scaleTargetRef:
name: my-deployment # Target deployment name
minReplicaCount: 0 # Minimum replicas (0 for scale-to-zero)
maxReplicaCount: 10 # Maximum replicas
pollingInterval: 30 # Seconds between metric checks
cooldownPeriod: 300 # Seconds to wait after last trigger
triggers:
- type: prometheus # Scaler type
metadata:
serverAddress: http://prometheus:9090
metricName: http_requests_total
threshold: '100'
query: sum(rate(http_requests_total[2m]))
ScaledObject with Multiple Triggers¶
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: multi-trigger-scaler
spec:
scaleTargetRef:
name: api-deployment
minReplicaCount: 1
maxReplicaCount: 50
triggers:
- type: prometheus
metadata:
serverAddress: http://prometheus:9090
threshold: '100'
query: sum(rate(http_requests_total[2m]))
- type: cpu
metricType: Utilization
metadata:
value: "70"
- type: memory
metricType: Utilization
metadata:
value: "80"
ScaledObject with Advanced HPA Behavior¶
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: advanced-scaling
spec:
scaleTargetRef:
name: worker-deployment
minReplicaCount: 2
maxReplicaCount: 100
advanced:
restoreToOriginalReplicaCount: true
horizontalPodAutoscalerConfig:
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50 # Scale down max 50% at a time
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100 # Scale up max 100% at a time
periodSeconds: 15
- type: Pods
value: 5 # Or add max 5 pods at a time
periodSeconds: 15
selectPolicy: Max # Use the policy that scales faster
triggers:
- type: kafka
metadata:
bootstrapServers: kafka:9092
consumerGroup: my-group
topic: events
lagThreshold: '10'
ScaledJob Configuration¶
apiVersion: keda.sh/v1alpha1
kind: ScaledJob
metadata:
name: batch-processor
spec:
jobTargetRef:
parallelism: 1
completions: 1
backoffLimit: 3
template:
spec:
containers:
- name: processor
image: myapp:latest
command: ["./process"]
restartPolicy: Never
pollingInterval: 30
maxReplicaCount: 10
successfulJobsHistoryLimit: 5
failedJobsHistoryLimit: 5
scalingStrategy:
strategy: "default" # or "custom", "accurate"
triggers:
- type: rabbitmq
metadata:
queueName: jobs
host: amqp://guest:guest@rabbitmq:5672
queueLength: '5'
TriggerAuthentication with Secret¶
apiVersion: v1
kind: Secret
metadata:
name: rabbitmq-secret
type: Opaque
stringData:
connection-string: "amqp://user:password@rabbitmq:5672"
---
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: rabbitmq-auth
spec:
secretTargetRef:
- parameter: host
name: rabbitmq-secret
key: connection-string
ClusterTriggerAuthentication with Pod Identity¶
apiVersion: keda.sh/v1alpha1
kind: ClusterTriggerAuthentication
metadata:
name: aws-credentials
spec:
podIdentity:
provider: aws-eks # or aws-kiam, azure, gcp
identityId: arn:aws:iam::123456789012:role/keda-role
Helm Installation Values¶
# values.yaml for Helm installation
operator:
replicaCount: 2 # HA setup
metricsServer:
replicaCount: 2 # HA setup
serviceAccount:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/keda-role
resources:
operator:
limits:
cpu: 1000m
memory: 1000Mi
requests:
cpu: 100m
memory: 100Mi
metricServer:
limits:
cpu: 1000m
memory: 1000Mi
requests:
cpu: 100m
memory: 100Mi
prometheus:
operator:
enabled: true
podMonitor:
enabled: true
metricServer:
enabled: true
podMonitor:
enabled: true
Common Use Cases¶
Use Case 1: RabbitMQ Queue-Based Scaling¶
Scale a worker deployment based on RabbitMQ queue depth:
# Create secret with RabbitMQ credentials
kubectl create secret generic rabbitmq-secret \
--from-literal=host='amqp://user:password@rabbitmq.default.svc.cluster.local:5672'
# Create TriggerAuthentication
kubectl apply -f - <<EOF
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
name: rabbitmq-auth
spec:
secretTargetRef:
- parameter: host
name: rabbitmq-secret
key: host
EOF
# Create ScaledObject
kubectl apply -f - <<EOF
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: rabbitmq-scaler
spec:
scaleTargetRef:
name: worker-deployment
minReplicaCount: 0
maxReplicaCount: 30
triggers:
- type: rabbitmq
metadata:
protocol: amqp
queueName: tasks
mode: QueueLength
value: '5'
authenticationRef:
name: rabbitmq-auth
EOF
# Monitor scaling
kubectl get scaledobject rabbitmq-scaler -w
kubectl get hpa
kubectl get deployment worker-deployment
Use Case 2: Kafka Consumer Group Lag Scaling¶
Scale Kafka consumers based on consumer group lag:
# Create ScaledObject for Kafka
kubectl apply -f - <<EOF
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: kafka-consumer-scaler
spec:
scaleTargetRef:
name: kafka-consumer
minReplicaCount: 1
maxReplicaCount: 50
triggers:
- type: kafka
metadata:
bootstrapServers: kafka.default.svc.cluster.local:9092
consumerGroup: my-consumer-group
topic: events
lagThreshold: '10'
offsetResetPolicy: latest
EOF
# Check scaling status
kubectl describe scaledobject kafka-consumer-scaler
kubectl get hpa keda-hpa-kafka-consumer-scaler
# View external metrics
kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1/namespaces/default/s0-kafka-my-consumer-group" | jq
Use Case 3: Prometheus Metrics-Based Scaling¶
Scale based on custom Prometheus metrics:
# Create ScaledObject with Prometheus trigger
kubectl apply -f - <<EOF
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: prometheus-scaler
spec:
scaleTargetRef:
name: api-server
minReplicaCount: 2
maxReplicaCount: 20
triggers:
- type: prometheus
metadata:
serverAddress: http://prometheus.monitoring.svc.cluster.local:9090
metricName: http_requests_per_second
threshold: '100'
query: |
sum(rate(http_requests_total{job="api-server"}[2m]))
EOF
# Verify Prometheus connectivity
kubectl logs -n keda deployment/keda-operator | grep prometheus
# Test scaling
kubectl get scaledobject prometheus-scaler -o jsonpath='{.status}'
Use Case 4: Cron-Based Scheduled Scaling¶
Scale workloads based on time schedules:
# Create ScaledObject with cron trigger for business hours
kubectl apply -f - <<EOF
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: scheduled-scaler
spec:
scaleTargetRef:
name: business-app
minReplicaCount: 1
maxReplicaCount: 1
triggers:
- type: cron
metadata:
timezone: America/New_York
start: 0 8 * * 1-5 # 8 AM Mon-Fri
end: 0 18 * * 1-5 # 6 PM Mon-Fri
desiredReplicas: "10"
- type: cron
metadata:
timezone: America/New_York
start: 0 18 * * 1-5 # 6 PM Mon-Fri
end: 0 8 * * 1-5 # 8 AM Mon-Fri
desiredReplicas: "2"
EOF
# Monitor scheduled scaling
kubectl get scaledobject scheduled-scaler -w
kubectl get events --field-selector involvedObject.name=scheduled-scaler
Use Case 5: AWS SQS Queue Processing with ScaledJob¶
Process AWS SQS messages using batch jobs:
# Create ClusterTriggerAuthentication with AWS IAM
kubectl apply -f - <<EOF
apiVersion: keda.sh/v1alpha1
kind: ClusterTriggerAuthentication
metadata:
name: aws-credentials
spec:
podIdentity:
provider: aws-eks
EOF
# Create ScaledJob for SQS processing
kubectl apply -f - <<EOF
apiVersion: keda.sh/v1alpha1
kind: ScaledJob
metadata:
name: sqs-processor
spec:
jobTargetRef:
template:
spec:
containers:
- name: processor
image: my-sqs-processor:latest
env:
- name: QUEUE_URL
value: https://sqs.us-east-1.amazonaws.com/123456789012/my-queue
restartPolicy: Never
pollingInterval: 30
maxReplicaCount: 10
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
triggers:
- type: aws-sqs-queue
authenticationRef:
name: aws-credentials
kind: ClusterTriggerAuthentication
metadata:
queueURL: https://sqs.us-east-1.amazonaws.com/123456789012/my-queue
queueLength: '5'
awsRegion: us-east-1
EOF
# Monitor job creation
kubectl get scaledjob sqs-processor
kubectl get jobs -l scaledjob.keda.sh/name=sqs-processor
kubectl logs job/<job-name>
Best Practices¶
-
Start with Conservative Limits: Begin with
minReplicaCount: 1and moderatemaxReplicaCountvalues. Test scale-to-zero (minReplicaCount: 0) only after validating your application handles cold starts gracefully. -
Configure Appropriate Polling and Cooldown: Set
pollingInterval(default 30s) based on your metric source's update frequency. Use longercooldownPeriod(default 300s) for workloads with variable traffic to prevent flapping. -
Use TriggerAuthentication for Secrets: Never hardcode credentials in ScaledObject specs. Always use
TriggerAuthenticationorClusterTriggerAuthenticationwith Kubernetes secrets or pod identity providers (AWS IAM, Azure AD, GCP Workload Identity). -
Implement HPA Behavior Policies: For production workloads, configure
advanced.horizontalPodAutoscalerConfig.behaviorto control scale-up/scale-down rates. Prevent aggressive scaling with stabilization windows and percentage-based policies. -
Monitor KEDA Components: Deploy KEDA operator and metrics server with at least 2 replicas for high availability. Enable Prometheus monitoring and set up alerts for KEDA component health and scaling failures.
-
Set Resource Limits: Always define resource requests and limits for both KEDA components and scaled workloads. This prevents resource contention and ensures predictable scaling behavior.
-
Use Fallback Configuration: Configure
fallback.replicasandfallback.failureThresholdto maintain service availability when external metric sources are unavailable. This prevents scaling to zero during metric source outages. -
Test Scaling Behavior: Before production deployment, test scaling under load using the pause annotation (
autoscaling.keda.sh/paused-replicas) to validate trigger thresholds and observe scaling patterns without affecting live traffic. -
Namespace Isolation: Use separate namespaces for different environments (dev, staging, prod) and apply appropriate RBAC policies. Use
ClusterTriggerAuthenticationfor shared credentials across namespaces. -
Version Control ScaledObjects: Store all KEDA resources in Git alongside application manifests. Use GitOps tools (ArgoCD, Flux) to manage KEDA configurations and ensure consistency across environments.
Troubleshooting¶
| Issue | Solution |
|---|---|
| ScaledObject not creating HPA | Check KEDA operator logs: kubectl logs -n keda deployment/keda-operator. Verify scaleTargetRef points to existing deployment/statefulset. Ensure deployment has valid selector labels. |
| Pods not scaling to zero | Verify minReplicaCount: 0 is set. Check if HPA exists: kubectl get hpa. Ensure no other HPAs target the same deployment. Review trigger conditions: kubectl describe scaledobject <name>. |
| Metrics not available | Check metrics server: kubectl get apiservice v1beta1.external.metrics.k8s.io. View metrics server logs: kubectl logs -n keda deployment/keda-operator-metrics-apiserver. Verify trigger authentication is configured correctly. |
| Authentication failures | Verify secret exists: kubectl get secret <name>. Check TriggerAuthentication references correct secret and keys. For pod identity, ensure service account has proper IAM/Azure AD annotations. Test credentials manually. |
| Scaling too aggressive/slow | Adjust pollingInterval (how often metrics are checked). Configure H |