avatar🌌
TangentTangent Blog

技术博客 | Go & Kubernetes & Linux

技术博客 | Go & Kubernetes & Linux

Overview: KEDA Scale to Zero

Overview: KEDA Scale to Zero ​

KEDA (Kubernetes Event-Driven Autoscaling) can reduce the replica count of workloads (Deployment / StatefulSet, etc.) down to 0 when trigger conditions are not met, saving resources; when events reappear, it scales up automatically. This enhances native HPA: vanilla HPA only works when minReplicas >= 1, while KEDA, driven by external events and maintaining its own HPA, enables “event-aware standby with 0 replicas”.


How it works (high-level flow) ​

  1. You deploy your workload (e.g., Deployment keda-test) and may set the initial replicas to 0.
  2. Create a ScaledObject (or ScaledJob) describing:
    • Target (scaleTargetRef.name)
    • Triggers (triggers)
    • Scaling policies (min/max, desired replicas, etc.)
  3. The KEDA Operator periodically (pollingInterval) polls or pulls events/metrics from the trigger backend.
  4. When the trigger condition is satisfied:
    • If current replicas < desired, KEDA creates/updates a dedicated HPA (typically named <deploymentName>-<hash>), and that HPA pushes replicas up to the target (or adjusts within the range).
  5. When events disappear:
    • After waiting for cooldownPeriod (and no new events during that time), KEDA scales the replicas down to minReplicaCount; if it is 0, it completely stops the Pods.

Key fields (ScaledObject.spec) ​

FieldPurposeNotes
scaleTargetRef.nameThe workload name to bindMust match the Deployment name
pollingIntervalPolling frequency for triggers (seconds)Default 30s; lower is more responsive but costs more resources
cooldownPeriodSeconds to wait before scaling down after triggers stopHelps avoid flapping
minReplicaCountMinimum replicasSet to 0 to truly “scale to zero”
maxReplicaCountMaximum replicasUpper bound of resource usage
triggers[].typeTrigger typee.g., cron, cpu, prometheus, kafka, rabbitmq, etc.
triggers[].metadataTrigger-specific parametersVary by type

Note: If minReplicaCount is not explicitly set, some triggers default to 0 while some versions may default to 1. It’s recommended to explicitly set it to 0 to avoid inconsistent behavior.


Relationship with HPA ​

KEDA creates and manages a “bridge HPA”:

  • Scale up: HPA increases replicas based on metrics injected by KEDA (External / Object metrics).
  • Scale to 0: When metrics vanish and cooldownPeriod elapses, KEDA directly patches the target object’s replicas to 0 (HPA itself won’t proactively set 0).

The Cron trigger in this example ​

scaledobject.yaml:

yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: keda-cron-scaledobject
spec:
  scaleTargetRef:
    name: keda-test
  pollingInterval: 15      # check every 15 seconds
  cooldownPeriod: 30       # wait 30 seconds before scaling down after window ends
  minReplicaCount: 0
  maxReplicaCount: 2
  triggers:
  - type: cron
    metadata:
      timezone: Asia/Shanghai
      start: "0 * * * *"   # start at second 0 each minute, desired replicas = 1
      end:   "30 * * * *"  # stop at second 30 each minute
      desiredReplicas: "1"

Timeline (taking minute 12:00 as an example):

  • 12:00:00 ~ 12:00:30: trigger active, replicas go to 1 (if previously 0).
  • 12:00:30: trigger window ends, cooldownPeriod starts.
  • 12:01:00: 30-second cooldown completes (no new window during it), replicas drop back to 0.
  • 12:01:00 is also the next minute’s start → scales up again (may see 0→1 flapping).

Ways to avoid repeated oscillation at window boundaries:

  1. Set cooldownPeriod to match your start interval and overlap strategy (e.g., shorter than the gap).
  2. Adjust cron expressions so the end isn’t tight to the next start boundary (e.g., set end to 55 * * * * for a wider window).

Scale-to-zero support across common triggers ​

Supported: cron, prometheus (when metric becomes 0 with no load), Kafka / RabbitMQ / Azure Queue / Redis Streams / NATS / PostgreSQL-Lag, and most event-driven triggers. Notes:

  • CPU/memory (native HPA metrics) alone cannot scale to 0 (no metrics when Pod=0). You need external events or a custom metric that reflects “need ≥1 replica”.
  • For HTTP traffic, use the KEDA HTTP Add-on or a gateway/queue-based wake-up approach.

Cold start and optimizations ​

When scaling from 0 to 1:

  1. Image pull (if not cached)
  2. Container start & application initialization
  3. Readiness probe passes (if configured)

Optimizations:

  • Use smaller images / pre-pull images (e.g., DaemonSet prewarming).
  • Shorten application startup path (lazy init where possible).
  • For ultra-low latency endpoints, keep a small always-on instance (minReplicaCount: 1) and split other tasks out.

Troubleshooting tips ​

  1. Check ScaledObject status:
    bash
    kubectl get scaledobject keda-cron-scaledobject -o yaml
    Look at status.conditions and status.scaleTargetKind.
  2. Inspect KEDA operator logs:
    bash
    kubectl logs -n keda -l app=keda-operator
  3. Inspect generated HPA:
    bash
    kubectl get hpa -A | findstr keda-test
  4. Confirm Deployment replicas:
    bash
    kubectl get deploy keda-test -o wide
  5. If not scaling down: still in cooldown? any residual events? is minReplicaCount set to 0?

FAQ ​

QuestionLikely causeFix
Never scales upCron time not reached / timezone mismatchVerify timezone and current cluster time (date -u)
Won’t scale to 0minReplicaCount not 0 / cooldown not finished / events still presentCheck fields and logs
Flapping at boundariesstart/end overlaps with cooldownAdjust window or cooldown
Cold start too slowLarge image / heavy initPrewarm, split, slim down

Best practices at a glance ​

  1. Explicitly set minReplicaCount: 0 and a reasonable maxReplicaCount.
  2. Use a “boolean event” type trigger to represent “need at least 1 replica”, rather than CPU metrics alone.
  3. Tune pollingInterval and cooldownPeriod to balance responsiveness and stability.
  4. Monitor startup latency in production; split out a lightweight always-on service if needed.
  5. Create a regression script to regularly validate: idle → inject event → first-request latency meets SLO.

Summary ​

KEDA scale-to-zero = event-driven + self-managed HPA + explicit minimum replicas of 0. Master the three core parameters (minReplicaCount / pollingInterval / cooldownPeriod) and the characteristics of your triggers to run event-driven workloads safely, elastically, and economically.

Go Generics Usage Tutorial
Kubernetes hostPath Volume Explained
由 Valaxy v1.2.2 驱动|主题-Yunv1.2.2