KEDA 缩容为 0(Scale to Zero)功能概述
KEDA (Kubernetes Event-Driven Autoscaling) 在触发条件不满足时,可以将工作负载(Deployment / StatefulSet 等)副本数降到 0,以节省资源;当事件再次出现时再自动拉起(扩容)。这是对原生 HPA 的增强:原生 HPA 只能在 minReplicas >= 1 时工作,而 KEDA 通过外部事件驱动 + 自己维护的 HPA,实现了 “事件感知 + 0 副本待机”。
工作机制简要流程
- 你部署业务(如本例
Deployment keda-test),可将初始副本设为 0。 - 创建
ScaledObject(或ScaledJob)描述:- 目标(
scaleTargetRef.name) - 触发器(triggers)
- 缩放策略(min/max、副本期望值等)
- 目标(
- KEDA Operator 周期性(
pollingInterval)向对应触发器后端轮询或拉取事件/指标。 - 当触发条件满足:
- 如果当前副本 < 期望,KEDA 创建/更新一个 专属 HPA(命名通常为
<deploymentName>-<hash>),HPA 促使副本上升到目标值(或在区间内调节)。
- 如果当前副本 < 期望,KEDA 创建/更新一个 专属 HPA(命名通常为
- 当事件消失:
- 等待
cooldownPeriod后(同时无新事件),KEDA 将副本降为minReplicaCount;若其为 0,则彻底停掉 Pod。
- 等待
关键字段说明(ScaledObject.spec)
| 字段 | 作用 | 备注 |
|---|---|---|
scaleTargetRef.name | 绑定的工作负载名称 | 需与 Deployment 名一致 |
pollingInterval | 轮询触发器频率(秒) | 默认 30s;更低更实时但更耗资源 |
cooldownPeriod | 触发停止后等待再缩容的秒数 | 避免抖动 |
minReplicaCount | 最低副本数 | 设为 0 才能真正 “scale to zero” |
maxReplicaCount | 最高副本数 | 资源上限控制 |
triggers[].type | 触发器类型 | 如 cron, cpu, prometheus, kafka, rabbitmq 等 |
triggers[].metadata | 触发器特定参数 | 依类型不同 |
注意:
minReplicaCount若未显式设置,一些触发器默认为 0,一些版本可能默认为 1,建议 显式写 0 以免行为不一致。
与 HPA 的关系
KEDA 创建并管理一个 “桥接 HPA”:
- 扩容阶段:HPA 依据 KEDA 注入的指标(
External/Object类型)拉升副本。 - 缩容到 0:当指标消失,且过了
cooldownPeriod,KEDA 直接 Patch 目标对象副本为 0(HPA 本身不会主动设 0)。
本例 Cron 触发器说明
scaledobject.yaml:
yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: keda-cron-scaledobject
spec:
scaleTargetRef:
name: keda-test
pollingInterval: 15 # 每 15 秒检查一次
cooldownPeriod: 30 # 结束后等 30 秒再缩容
minReplicaCount: 0
maxReplicaCount: 2
triggers:
- type: cron
metadata:
timezone: Asia/Shanghai
start: "0 * * * *" # 每分钟 0 秒开始,期望副本=1
end: "30 * * * *" # 每分钟 30 秒后停止
desiredReplicas: "1"时间线(以 12:00 分钟为例):
- 12:00:00 ~ 12:00:30:触发有效,副本调到 1(若已有 0)。
- 12:00:30:触发窗口结束,开始等待
cooldownPeriod。 - 12:01:00:30 秒冷却完成(期间无新窗口),副本降回 0。
- 12:01:00 同时又是下一分钟的启动点 → 再次扩容(存在 0→1 抖动)。
避免窗口边界重复震荡的方法:
- 将
cooldownPeriod设为 < 启动间隔与窗口重叠策略相适应。 - 调整 cron 表达式让时间段不与下一次 start 边界紧贴(比如 end 设为
55 * * * *,窗口更大)。
常见触发器对 scale to zero 支持概览
支持:cron, prometheus 指标(无负载时=0), Kafka / RabbitMQ / Azure Queue / Redis Streams / NATS / PostgreSQL-Lag 等大多数事件触发器。 注意:
- CPU/内存(HPA 内置 metrics) 直接使用时无法 scale 到 0(因为 Pod=0 时无指标);需借助外部事件或自定义指标反映“是否需要 ≥1 副本”。
- HTTP 场景可用 KEDA HTTP Add-on 或网关延迟队列方案来唤醒。
冷启动与优化
当从 0 扩到 1:
- Pod 镜像拉取(若本地无缓存)
- 容器启动 & 应用初始化
- 就绪探针通过(若设置)
优化手段:
- 使用小镜像 / 预拉取镜像(DaemonSet 预热)。
- 缩短应用启动路径(lazy init)。
- 将需要快速响应的极低延迟接口放入常驻副本(设置
minReplicaCount: 1)与其它任务分离。
排障建议
- 查看 ScaledObject 状态:bash关注
kubectl get scaledobject keda-cron-scaledobject -o yamlstatus.conditions、status.scaleTargetKind。 - 检查 KEDA operator 日志:bash
kubectl logs -n keda -l app=keda-operator - 查看生成的 HPA:bash
kubectl get hpa -A | findstr keda-test - 确认 Deployment 副本:bash
kubectl get deploy keda-test -o wide - 若未缩容:是否仍在 cooldown;是否有残留事件;
minReplicaCount是否写 0。
常见问题 (FAQ)
| 问题 | 可能原因 | 处理 |
|---|---|---|
| 一直不扩容 | cron 时间未到 / 时区不匹配 | 校验 timezone 与当前集群时间 (date -u) |
| 不缩到 0 | minReplicaCount 不是 0 / cooldown 未结束 / 仍有事件 | 排查字段与日志 |
| 边界时刻震荡 | start 与 end / cooldown 重叠 | 调整窗口或 cooldown |
| 冷启动太慢 | 镜像大 / init 逻辑重 | 预热、拆分、瘦身 |
最佳实践速览
- 明确写出
minReplicaCount: 0与合理的maxReplicaCount。 - 对“是否需要至少 1 副本”使用“布尔事件”式触发器,而不是 CPU 指标。
- 设置适当
pollingInterval和cooldownPeriod,平衡响应与抖动。 - 生产中监控启动耗时,必要时拆出一个常驻轻量服务。
- 编写回归脚本定期验证:停机→事件注入→首请求延迟是否满足 SLO。
小结
KEDA 的缩容为 0 = 事件驱动 + 自管 HPA + 显式最小副本 0。掌握三个核心参数(minReplicaCount / pollingInterval / cooldownPeriod)与触发器特性,即可安全、弹性和经济地运行事件驱动工作负载。