用队列指标扩缩 Kubernetes AI Worker:HPA 稳定性实战
CPU 指标无法及时反映 AI 队列积压与模型预热。本文用 autoscaling/v2 外部指标建立 backlog 扩缩容,覆盖指标语义、启动延迟、稳定窗口、失效测试和回滚。
本文要点
- 主题聚焦:AI、大模型、DevOps
- 适合人群:独立开发者、全栈工程师、AI 应用开发者
- 核心价值:快速理解背景、实践路径、常见误区和工程建议
异步摘要、Embedding 或批量推理 Worker 在空闲时 CPU 很低,积压出现后又可能先花一分钟加载模型。只按 CPU 扩容会在队列已经超时后才反应;只按队列总长度扩容,如果把已领取任务也重复统计,又会持续过量扩容。队列的投递、确认与死信语义先按 后台任务队列 定义,HPA 只消费一个明确、可复算的容量信号。
先给指标写合同
ai_jobs_ready 只统计指定 queue 中可领取、未被 lease 的任务;另报 ai_work_seconds_outstanding,把 ready 预计耗时与 active lease 剩余耗时相加。否则 ready 归零会触发缩容,仍在运行的长任务却会被 Deployment 选中终止。标签只保留低基数 queue、region 和 workload class,不含租户或请求 ID。
目标 8 表示每副本约 8 个 ready job;工作秒目标则由排队 SLO、单 worker 吞吐与启动时间反推。HPA 对多指标分别计算并取最大副本数,因此 active lease 指标能守住在途容量。
HPA 当前稳定 API 是 autoscaling/v2。外部指标需要集群注册 external.metrics.k8s.io adapter;HPA 不会替你安装、鉴权或校验 adapter。示例:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: ai-worker
namespace: ai
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: ai-worker
minReplicas: 2
maxReplicas: 40
metrics:
- type: External
external:
metric:
name: ai_jobs_ready
selector:
matchLabels:
queue: embedding
target:
type: AverageValue
averageValue: "8"
- type: External
external:
metric:
name: ai_work_seconds_outstanding
selector:
matchLabels:
queue: embedding
target:
type: AverageValue
averageValue: "300"
behavior:
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 600
policies:
- type: Percent
value: 25
periodSeconds: 60
两个 AverageValue 分别约束每副本 ready 数与未完成工作秒,HPA 取较大建议。maxReplicas 仍受 GPU/CPU 配额、数据库连接、模型源站和下游限流约束;GPU 推理容量规划 中的设备数是硬上限。
把冷启动纳入有效容量
新 Pod 在模型未加载完时不提供吞吐,HPA 也不能缩短这段启动时间。为 Worker 配 startup probe 和真实 readiness,指标侧另报 ready worker、启动时长与处理速率;minReplicas 至少覆盖正常流量和一个故障副本。模型很大时先做节点预热,不能提前返回 readiness 成功来掩盖加载。
缩容时 Worker 先停领任务,完成或释放 lease 再退出。稳定窗口、终止宽限、最大任务时长和 lease timeout 必须一致。无法中断或迁移的长任务应把 scaleDown.selectPolicy 设为 Disabled,或改用能按 lease 选择空闲 Pod 的控制器;Deployment 缩容不保证删到空闲副本。
指标 adapter 使用只读账户、查询超时和采样时间;过期值返回错误,不能重复旧低值。监控 adapter 偏差、ready、oldest age、work seconds、active lease 与冷启动,并接入 Prometheus 与 Grafana 可观测性。
对控制环做失效测试
固定到达率加压后停止入队,验证 active lease 未归零前不会缩掉所需容量,随后才降到 minReplicas。记录 backlog 到新 Pod ready 的时延,并用 LLM SLO 监控 检查 oldest age。
直接查看 HPA 条件与原始指标,排除“图表有数据但聚合 API 没数据”:
kubectl describe hpa -n ai ai-worker
kubectl get --raw '/apis/external.metrics.k8s.io/v1beta1/namespaces/ai/ai_jobs_ready?labelSelector=queue%3Dembedding'
kubectl get deployment,pods -n ai -w
然后分别注入 adapter 超时、返回空序列、数值冻结、队列连接失败、一个 Pod 永远启动不了以及下游 429。预期行为是产生明确 HPA condition 和告警,不把“取不到指标”解释为 backlog 为零,也不无限越过 maxReplicas。恢复后控制环应平滑追上真实值,而不是一次缩到最小再扩回。
回滚先冻结已知容量
新指标语义错误时,先导出并停用 HPA,再立即把 Deployment 设为能够承载当前流量的已知副本数;不要把 target 调到极大值来掩盖错误。保存 HPA YAML、adapter 版本和查询结果,修复后从较低 maxReplicas 灰度恢复。
如果错误扩容已经压垮下游,先暂停消费者领取新任务并保留队列数据,按下游可承载速率逐步恢复。队列是缓冲区而不是数据垃圾桶,保留策略、死信和重放流程仍需遵循 消息队列系统设计。只有指标、HPA、Worker drain 和队列幂等四段一起通过故障测试,自动扩缩才可以进入无人值守状态。
延伸阅读
Related