avatar🌌
TangentTangent Blog

技术博客 | Go & Kubernetes & Linux

技术博客 | Go & Kubernetes & Linux

KEDA 缩容为 0(Scale to Zero)功能概述

KEDA 缩容为 0(Scale to Zero)功能概述 ​

KEDA (Kubernetes Event-Driven Autoscaling) 在触发条件不满足时,可以将工作负载(Deployment / StatefulSet 等)副本数降到 0,以节省资源;当事件再次出现时再自动拉起(扩容)。这是对原生 HPA 的增强:原生 HPA 只能在 minReplicas >= 1 时工作,而 KEDA 通过外部事件驱动 + 自己维护的 HPA,实现了 “事件感知 + 0 副本待机”。


工作机制简要流程 ​

  1. 你部署业务(如本例 Deployment keda-test),可将初始副本设为 0。
  2. 创建 ScaledObject(或 ScaledJob)描述:
    • 目标(scaleTargetRef.name)
    • 触发器(triggers)
    • 缩放策略(min/max、副本期望值等)
  3. KEDA Operator 周期性(pollingInterval)向对应触发器后端轮询或拉取事件/指标。
  4. 当触发条件满足:
    • 如果当前副本 < 期望,KEDA 创建/更新一个 专属 HPA(命名通常为 <deploymentName>-<hash>),HPA 促使副本上升到目标值(或在区间内调节)。
  5. 当事件消失:
    • 等待 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 抖动)。

避免窗口边界重复震荡的方法:

  1. 将 cooldownPeriod 设为 < 启动间隔与窗口重叠策略相适应。
  2. 调整 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:

  1. Pod 镜像拉取(若本地无缓存)
  2. 容器启动 & 应用初始化
  3. 就绪探针通过(若设置)

优化手段:

  • 使用小镜像 / 预拉取镜像(DaemonSet 预热)。
  • 缩短应用启动路径(lazy init)。
  • 将需要快速响应的极低延迟接口放入常驻副本(设置 minReplicaCount: 1)与其它任务分离。

排障建议 ​

  1. 查看 ScaledObject 状态:
    bash
    kubectl get scaledobject keda-cron-scaledobject -o yaml
    关注 status.conditions、status.scaleTargetKind。
  2. 检查 KEDA operator 日志:
    bash
    kubectl logs -n keda -l app=keda-operator
  3. 查看生成的 HPA:
    bash
    kubectl get hpa -A | findstr keda-test
  4. 确认 Deployment 副本:
    bash
    kubectl get deploy keda-test -o wide
  5. 若未缩容:是否仍在 cooldown;是否有残留事件;minReplicaCount 是否写 0。

常见问题 (FAQ) ​

问题可能原因处理
一直不扩容cron 时间未到 / 时区不匹配校验 timezone 与当前集群时间 (date -u)
不缩到 0minReplicaCount 不是 0 / cooldown 未结束 / 仍有事件排查字段与日志
边界时刻震荡start 与 end / cooldown 重叠调整窗口或 cooldown
冷启动太慢镜像大 / init 逻辑重预热、拆分、瘦身

最佳实践速览 ​

  1. 明确写出 minReplicaCount: 0 与合理的 maxReplicaCount。
  2. 对“是否需要至少 1 副本”使用“布尔事件”式触发器,而不是 CPU 指标。
  3. 设置适当 pollingInterval 和 cooldownPeriod,平衡响应与抖动。
  4. 生产中监控启动耗时,必要时拆出一个常驻轻量服务。
  5. 编写回归脚本定期验证:停机→事件注入→首请求延迟是否满足 SLO。

小结 ​

KEDA 的缩容为 0 = 事件驱动 + 自管 HPA + 显式最小副本 0。掌握三个核心参数(minReplicaCount / pollingInterval / cooldownPeriod)与触发器特性,即可安全、弹性和经济地运行事件驱动工作负载。

Go 语言泛型使用教程
Kubernetes hostPath 卷详解
由 Valaxy v1.2.2 驱动|主题-Yunv1.2.2