Kubernetes 自动扩缩容:HPA、VPA 和 Cluster Autoscaler 的边界
把 requests 写对、HPA 行为调稳、VPA 做推荐、CA 能补容量,让扩缩容可预测而不是“抽风”。
扩缩容是一套“系统的系统”。如果你觉得它不稳,常见原因是:
- requests 不准(分母错)
- 多个控制器在打架(HPA/VPA/发布/surge 同时发生)
- 集群容量层(Cluster Autoscaler/节点池)跟不上
这篇 tips 给一个可落地的稳定扩缩容思路。
三层扩缩容:先搞清楚谁负责什么
- HPA(Horizontal Pod Autoscaler):改副本数(replicas)
- VPA(Vertical Pod Autoscaler):改/推荐 requests(有些模式也能自动改)
- Cluster Autoscaler:改节点数(加/减节点)
想要稳定,需要三层对齐:指标、requests、容量与启动时间。
Step 0:requests 是地基(不写或写错,一切都不准)
很多扩缩容逻辑都以 requests 为基础:
- HPA 的 CPU utilization 常用:
当前 CPU / requests.cpu - 调度器靠 requests 放置 Pod
- Cluster Autoscaler 看到 Pod Pending 才会补节点(Pending 常由 requests 触发)
因此第一步永远是:所有容器都要有合理 requests。
HPA 基础例子(CPU 利用率)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api
namespace: app
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api
minReplicas: 3
maxReplicas: 30
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
含义:
- 平均 CPU 接近 requests 的 60% 时保持稳定
- 高于 60% 倾向扩容,低于 60% 倾向缩容
但注意:如果 requests 不准,这个“60%”没有意义。
防止抖动:stabilization window 与 scaling policy
HPA v2 支持行为配置,用来避免“上上下下”:
behavior:
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 20
periodSeconds: 60
思路是:
- 扩容尽量快(应对突发)
- 缩容慢一点(避免流量小波动导致频繁缩容)
指标选择:CPU 不是万能
CPU 利用率适合:
- 典型无状态 Web/API
但对这些类型往往不准:
- 队列 worker(更适合 backlog/lag)
- 内存型服务(CPU 低但内存持续升)
- I/O 型服务(瓶颈不在 CPU)
更靠谱的做法是选择贴近业务负载的指标:
- 队列深度、消费滞后
- RPS/并发连接数
- 关键路径延迟(谨慎,避免反馈环)
结论:
用“能代表负载”的指标扩容,而不是只看资源消耗。
冷启动与 readiness:扩了也不一定立刻有用
扩容增 Pod,但 Pod 变成可用需要时间:
- 拉镜像
- 启动(JVM warmup、迁移、缓存)
- readiness 通过
如果启动慢,HPA 扩容再快也救不了峰值。
你可能需要:
- 提高
minReplicas - 提前预热镜像(节点缓存)
- 对启动慢服务加
startupProbe - 合理的 scaleUp policy
Cluster Autoscaler:容量层的关键
HPA 扩容后,如果节点不够,Pod 会 Pending。Cluster Autoscaler 需要能识别并补节点。
如果 CA 不工作,常见原因:
- affinity/nodeSelector 让 Pod 只能去不存在的节点池
- requests 太大,没有任何节点规格能容纳
- 节点池 max size/配额到顶
- PDB/约束导致缩容逻辑受限(与 scale-down 相关)
排查 Pending:
kubectl get pod -n <ns> | rg -n "Pending"
kubectl describe pod -n <ns> <pod> | rg -n "FailedScheduling|Insufficient"
VPA:即使只做推荐也很有价值
当前 VPA 常见模式包括:
Off:只生成推荐,不修改 PodInitial:只在 Pod 创建时设置 requestsRecreate:通过重建 Pod 应用更新InPlaceOrRecreate:优先原地调整,失败时重建,需要集群支持原地资源调整InPlace:只尝试原地调整,不主动驱逐,需要对应 Feature Gate
Auto 已弃用,应改成明确的更新模式。
建议路径:
- 先用
Off观察推荐并校正 requests - 再用
Initial降低运行中变更风险 - 集群支持原地调整后,再评估
InPlaceOrRecreate或InPlace
HPA + VPA 一起用:避免打架
如果 HPA 以 CPU utilization 扩容,而 VPA 频繁改 CPU requests:
- 分母变了,HPA 会突然改变判断
- 容易产生“看起来负载没变,但副本数在变”的现象
实践上常见组合:
- HPA 用 CPU 或业务指标控制副本数
- VPA 用来推荐/调整 内存 requests(或以 Initial 模式周期性更新)
内存扩缩容要谨慎
HPA 也能按内存指标扩缩,但内存通常是滞后指标:
- 缓存增长导致内存上升,但扩容并不一定能立刻缓解
- 缩容后缓存重建反而变慢
如果确实要用内存指标:
requests.memory必须贴近真实峰值,否则百分比目标没有意义- 缩容窗口拉长,避免缓存刚重建就被缩容
- 把内存当成保护性指标,而不是唯一扩容信号
更常见的稳妥方式:
- HPA 按 CPU/RPS 扩容
- VPA 优化内存 requests
- 缩容保守(长 stabilization window)
队列和流任务:按业务积压扩容
队列驱动的 Pod,CPU 利用率通常不能反映真实压力。优先观察:
- 未处理消息数或队列深度
- consumer lag 或消费组滞后
- 每个消费者平均处理时长
KEDA 这类事件驱动方案适合按积压扩容,也能在业务允许时缩到 0。核心在于选择能反映业务负载的指标。
分阶段上线
- 为应用容器、sidecar 和 initContainer 补齐合理的 requests。
- 先启用 HPA,目标值保守,缩容速度放慢。
- 用压测或真实峰值记录 Pod 从创建到 Ready 的时间线。
- 确认 Cluster Autoscaler 能补节点,节点池配额和调度约束没有卡点。
- 最后启用 VPA 推荐,根据稳定窗口逐步校正 requests。
排障:HPA/指标为什么不工作
看 HPA 状态:
kubectl get hpa -n <ns>
kubectl describe hpa -n <ns> <hpa>
常见提示:
- 无法获取指标(metrics pipeline 问题)
- 缺 requests(HPA 无法计算 utilization)
- 频繁 scale events(需要 behavior 调整或指标换更贴近负载)
指标管道
HPA 读不到指标就不会工作。分别确认:
- 资源指标:metrics-server 已安装,
kubectl top pod能返回数据。 - 自定义/外部指标:Prometheus adapter 或其他指标适配器暴露了 HPA 引用的指标名。
Requests 与 QoS
requests 缺失或严重偏大,都会让扩缩容失真。检查 Deployment、initContainer 和 sidecar 的每一段资源配置。
上线前先做一次扩容演练
自动扩缩容“看起来正常”直到第一次真实高峰。生产前至少确认:
- 增加 Pod 需要多久:镜像拉取、启动、readiness。
- 增加节点需要多久:Cluster Autoscaler、节点池供应、网络挂载。
- 服务在容量爬坡期是否还能承接部分流量。
如果节点供应要 3-5 分钟,可能需要提高 minReplicas、预热节点池,或加快 scaleUp 策略。稳定的扩缩容需要同时对齐启动时间、指标延迟和容量供应。
上线前自检
- requests 对齐真实负载(别拍脑袋)
- HPA 缩容保守,避免抖动
- 指标链路可靠(metrics-server/adapter)
- Cluster Autoscaler 能满足调度约束并有容量余量
- 用 VPA 推荐持续修正 requests
常见问题
Q: HPA 和 VPA 怎么选?
A: HPA 负责副本数,VPA 负责 requests 的校准。两者可以用于同一工作负载,但如果 HPA 按 CPU utilization 扩容,就不要让 VPA 频繁修改 CPU requests;可先使用 VPA Off 或只调整内存。
Q: 为什么 HPA 会抖动?
A: 指标延迟和激进策略会导致反复伸缩。加 stabilization window、放慢 scale down,并调准目标值。
Q: 一定要装 metrics-server 吗?
A: CPU/内存的 HPA 需要 metrics-server;自定义指标需要指标管道(如 Prometheus + adapter)。