K8s集群HPA不生效?从指标采集到扩容策略的排错流程
HPA(Horizontal Pod Autoscaler,水平Pod自动扩缩容)不生效时,先别急着改副本数或重建控制器。
绝大多数情况是指标链路断了:metrics-server 没跑起来、Pod 没写资源 requests、或者指标 API 返回不了数据。
按下面顺序逐层验证,能快速缩小问题范围。
先确认 HPA 当前到底卡在哪一步
执行两条命令,先看 HPA 状态和目标指标:
kubectl get hpa -A
kubectl describe hpa -n <命名空间>
重点看 TARGETS 列和 describe 末尾的 Events。
如果 TARGETS 显示 ,说明指标采集失败;
如果显示 0%/50% 但 CPU 实际很高,说明指标源和实际负载不一致;
如果 TARGETS 正常但副本数不动,问题在扩容策略或副本上限。
这一步决定后面查哪条链路。
检查 metrics-server 是否正常提供指标
HPA 默认依赖 metrics-server 提供 CPU、内存指标。
先确认它存在且 Ready:
kubectl get deployment metrics-server -n kube-system
kubectl get apiservice v1beta1.metrics.k8s.io
apiservice 的 AVAILABLE 应为 True。
再直接查询指标接口:
kubectl top pods -n <命名空间>
kubectl top nodes
如果 kubectl top 报 error: Metrics API not available,说明 metrics-server 没就绪或网络不通。
常见原因是 metrics-server 启动参数缺少 --kubelet-insecure-tls(测试环境自签证书场景),或节点 10250 端口被安全组、防火墙拦截。
检查 Pod 日志:
kubectl logs -n kube-system deploy/metrics-server --tail=100
日志里出现 dial tcp ...:10250: connect: connection refused 或 x509 证书错误,就对应上面的原因处理。
资源 requests 没写,HPA 算不出利用率
HPA 计算 CPU 利用率的方式是:实际使用量 ÷ requests。
如果 Pod 模板里没有设置 resources.requests.cpu,HPA 会报 missing request for cpu,TARGETS 显示 unknown。
检查工作负载:
kubectl get deployment <名称> -n <命名空间> -o yaml | grep -A6 resources
正确的片段应类似:
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
补上 requests 后需要滚动更新 Pod,HPA 才能重新计算。
注意:requests 设得过大,利用率分母变大,HPA 可能迟迟不触发;
设得过小则容易频繁扩容。
建议先用 kubectl top pods 观察真实用量再定值。
核对 HPA 的 minReplicas、maxReplicas 和指标阈值
配置本身也会让 HPA “看起来没反应”。
查看:
kubectl get hpa <名称> -n <命名空间> -o yaml
逐个确认:
minReplicas和maxReplicas是否相等,相等时不会扩容;scaleTargetRef的 name 和 apiVersion 是否指向真实工作负载;metrics里的averageUtilization阈值是否设得过高,比如 90%,导致长期不触发;- 是否配置了
behavior.scaleUp的stabilizationWindowSeconds,窗口太长会延迟扩容动作。
另外,如果集群启用了多个指标源(如 Prometheus Adapter 提供自定义指标),要确认 HPA 引用的指标名和适配器暴露的名称完全一致,大小写和命名空间都不能错。
排错时容易踩的几个坑
只重启 HPA 不重启工作负载:补了 requests 后没重新创建 Pod,旧 Pod 依然缺 requests,指标继续 unknown。
在无 metrics-server 的集群硬等:有些托管集群默认不装 metrics-server,需要手动部署或开启组件,否则 HPA 永远不会工作。
忽略节点资源不足:HPA 想扩容但节点没有可调度资源,Pod 会 Pending。
用 kubectl describe pod 看事件,必要时配合 Cluster Autoscaler 或手动扩容节点。
指标采集延迟误判:metrics-server 默认采集间隔约 15 秒,HPA 控制器也有同步周期,压测后立刻查可能还没反映,建议观察 1 到 2 分钟再判断。
验证扩容是否真正生效
在测试环境制造 CPU 压力,观察副本变化:
kubectl run load-test --image=busybox -it --rm -- sh -c "while true; do :; done"
kubectl get hpa <名称> -n <命名空间> -w
正常情况下 TARGETS 利用率上升,REPLICAS 逐步增加。
停止压力后,受缩容稳定窗口影响,副本会在几分钟内回落。
若始终不变,回到前一步确认 Events 里的最新报错。
常见疑问
HPA 显示 unknown 但 kubectl top 正常,是什么原因?
多半是 HPA 引用的指标名不匹配或工作负载缺少 requests,指标源正常不代表 HPA 能算出利用率。
自定义指标 HPA 不扩容怎么查?
先确认 Adapter 的 APIService 可用,再用 kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1 查看已注册指标,核对名称后再看 HPA Events。
HPA 和 VPA 能同时用吗?
不建议对同一工作负载同时用 CPU 维度的 HPA 和 VPA,两者会互相干扰,容易造成反复扩缩容。
处理服务器K8s集群HPA排错时,按“HPA状态 → metrics-server → requests → HPA配置 → 事件复查”这条链路走,基本能覆盖大多数不扩容场景。
改完配置后记得重新创建 Pod 并留出指标采集时间,再做最终验证。