容器HPA弹性伸缩:CPU负载高自动扩容Pod降低负载
流量波动下的副本数难题
容器化部署解决了应用交付与环境一致性的问题,但副本数量该定多少,仍然是很多团队绕不开的运维细节。副本数按峰值配置,低谷期资源闲置;按均值配置,高峰期又会排队、超时甚至雪崩。Kubernetes 提供的 Horizontal Pod Autoscaler(HPA),正是为了把这件事从人工判断变成自动控制。
HPA 的基本工作方式
HPA 是 Kubernetes 内置的水平伸缩控制器,它不创建 Pod,也不修改容器本身,而是持续调整 Deployment、StatefulSet 等工作负载对象中的副本数。当 HPA 观察到指标超过目标值,就上调副本数;指标回落后,再逐步下调。
控制循环与指标来源
- 采集周期:HPA 控制器默认每隔一段时间从指标 API 拉取一次数据,感知负载变化。
- 资源指标:CPU、内存等由 metrics-server 采集,通过 metrics.k8s.io 聚合接口暴露。
- 自定义与外部指标:QPS、队列长度、连接数等可以通过 Prometheus Adapter 等适配器接入,或由 KEDA 等组件驱动。
CPU 使用率的计算基准是 Pod 中容器的 resources.requests,而不是节点总容量。这一点直接决定了 HPA 能否正常工作:如果未设置 requests,CPU 利用率就缺少分母,HPA 无法得出有效的百分比指标。
扩容算法与触发条件
HPA 的副本数计算逻辑可以概括为一个公式:
期望副本数 = ceil( 当前副本数 × 当前指标值 ÷ 期望指标值 )
举例来说,当目标 CPU 利用率设定为 60%,而实测值跑到 90% 时,控制器会按比例计算出更大的副本数,向上取整后应用到工作负载上。新增的 Pod 分摊请求后,单个 Pod 的平均 CPU 使用率随之下降,直到回落到目标值附近。
容差、稳定窗口与扩缩策略
- 容差:当前指标与目标值接近时,HPA 不会频繁调整,避免指标小幅波动引发副本数反复跳动。
- 缩容稳定窗口:缩容比扩容更保守,控制器会回看一段时间内的历史推荐值,取其中较大的一个,防止短时低谷导致副本被过早回收。
- behavior 配置:通过 scaleUp 与 scaleDown 策略,可以分别限制单位时间内的扩缩幅度和冷却时间。
让自动扩容真正生效的关键配置
- 设置合理的 requests:requests 既是调度依据,也是 CPU 利用率的计算基准,取值应贴近应用的真实常态消耗。
- 配置就绪探针:新 Pod 只有通过就绪检查才会进入 Service 后端,否则扩容出来的实例无法分担流量,指标也难以下降。
- 关注启动速度:扩容到指标回落之间存在滞后,应用冷启动慢时,可配合启动探针或预扩容策略缓解。
- 留出节点资源余量:集群若没有可调度资源,HPA 计算出的副本数会因 Pending 而落空,需与集群自动伸缩协同使用。
- 设定副本数上下限:minReplicas 保证基础可用性,maxReplicas 防止异常流量或指标失真时无限扩张。
多指标与自定义指标
CPU 负载是使用最广的伸缩信号,但它并不总是最贴近业务感受的指标。对于 IO 密集型或消息驱动的应用,CPU 可能长期平稳,真正的压力体现在请求延迟或队列积压上。此时可以同时配置多个指标,HPA 会分别计算推荐副本数并取其中最大值执行,从而覆盖更完整的压力场景。
常见误区与排查方向
- 指标一直显示 unknown:通常是 metrics-server 未部署、组件异常,或指标接口未正确注册。
- 副本数频繁抖动:目标值设置过于贴近日常波动区间,可适当放宽容差或延长稳定窗口。
- 扩容后负载不降:检查请求是否真正分发到新 Pod,常见原因是就绪探针缺失、会话粘连或客户端长连接未重建。
- 缩容过快引发超时:为容器配置优雅停止时间,并让应用正确处理终止信号,避免连接被硬切断。
结语
HPA 把"加机器还是加副本"这类判断交给了控制循环,但它的效果高度依赖资源声明、探针配置与指标体系的准确性。把 requests 与探针打好基础,再根据业务特征选择合适的指标,自动扩容才能在流量上涨时及时增加 Pod、摊薄单实例压力,在流量回落后平稳收缩,让资源投入与真实负载保持匹配。