说明:本文由 Codex 根据作者提供的主题、素材与公开资料辅助生成,属于 AI 生成/整理内容,非作者原创。请读者自行甄别并交叉验证。
HPA 是什么#
HPA 是 Horizontal Pod Autoscaler,也就是水平 Pod 自动扩缩容。
它做的事情很明确:
根据指标变化,自动调整某个工作负载的副本数。它通常作用在 Deployment、ReplicaSet、StatefulSet 这类支持 scale 子资源的对象上。
HPA 不负责:
- 修改单个 Pod 的 CPU 或内存 request。
- 增加或减少节点数量。
- 判断业务是否真的健康。
- 替应用解决启动慢、连接耗尽、数据库瓶颈等问题。
可以先用一句话记住:
HPA 调 Pod 数量,VPA 调 Pod 资源规格,Cluster Autoscaler 调节点数量。HPA 的控制循环#
HPA Controller 会周期性执行控制循环:
1. 找到 HPA 绑定的 scaleTargetRef
2. 读取目标对象当前副本数
3. 从 metrics API 读取指标
4. 按算法计算期望副本数
5. 通过 scale 子资源更新目标对象 replicas典型链路是:
metrics-server / custom metrics adapter / external metrics adapter
↓
metrics.k8s.io / custom.metrics.k8s.io / external.metrics.k8s.io
↓
HPA Controller
↓
Deployment scale subresource
↓
ReplicaSet
↓
Pod所以 HPA 不工作时,排查重点通常是:
- HPA 对象是否写对。
- 目标对象是否支持 scale。
- metrics API 是否可用。
- Pod 是否有资源 request。
- 当前指标是否真的超过阈值。
基本计算公式#
HPA 的核心公式可以理解为:
期望副本数 = ceil(当前副本数 × 当前指标值 / 目标指标值)比如:
当前副本数:3
目标 CPU 利用率:60%
当前平均 CPU 利用率:90%
期望副本数 = ceil(3 × 90 / 60) = 5如果当前平均 CPU 只有 30%:
期望副本数 = ceil(3 × 30 / 60) = 2实际控制过程中还会受到这些因素影响:
minReplicas和maxReplicas。- 控制器同步周期。
- 扩缩容容忍区间。
- 缺失指标和未 Ready Pod 的保守处理。
- scaleUp / scaleDown 行为策略。
- 稳定窗口,尤其是缩容稳定窗口。
所以看到 HPA 没有立刻扩缩容,不一定代表它坏了。
CPU 利用率和 request 的关系#
最常见的 HPA 配置是按 CPU 利用率扩缩容。
这里的利用率不是节点 CPU 使用率,而是相对于 Pod 容器 resources.requests.cpu 的比例。
例如容器配置:
resources:
requests:
cpu: 500m如果当前使用 250m,则利用率大约是 50%。
如果没有设置 CPU request,HPA 很难计算 CPU utilization 类型指标。
这是 HPA 排查里最常见的问题之一:
HPA 使用 CPU utilization 时,Pod 必须有 CPU request。一个 autoscaling/v2 示例#
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
behavior:
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50
periodSeconds: 60这份配置表达的是:
- 副本数最少 2,最多 10。
- 平均 CPU 利用率目标是 60%。
- 扩容可以比较快。
- 缩容会参考 300 秒稳定窗口,避免刚降下来又升上去。
指标来源#
HPA 支持多类指标。
| 指标类型 | API | 典型来源 | 场景 |
|---|---|---|---|
| Resource | metrics.k8s.io | metrics-server | CPU、Memory |
| Pods | custom.metrics.k8s.io | Prometheus Adapter 等 | 每个 Pod 的业务指标 |
| Object | custom.metrics.k8s.io | Prometheus Adapter 等 | Ingress QPS、队列长度等 |
| External | external.metrics.k8s.io | 外部指标适配器 | 云队列长度、消息积压、第三方指标 |
Resource 指标适合入门,但它不一定最符合业务。
例如:
- Web 服务可以考虑 QPS、并发请求数、P95 延迟等指标。
- Worker 可以考虑队列长度、消息积压时间。
- 推理服务可以考虑 GPU 利用率、请求排队时间。
不过越接近业务的指标,越要注意指标延迟、噪声和扩缩容后的反馈时间。
HPA、Deployment 和滚动更新#
HPA 通常和 Deployment 一起使用。
关系是:
HPA 修改 Deployment.spec.replicas
Deployment 控制 ReplicaSet
ReplicaSet 创建或删除 Pod如果同时有人手动执行:
kubectl scale deployment web --replicas=3HPA 仍会在下一轮控制循环里根据指标重新调整副本数。
所以启用 HPA 后,不建议再把副本数当成完全手工维护的值。
更好的做法是:
- GitOps 或 YAML 中保留 HPA 配置。
- Deployment 中给一个合理初始 replicas。
- 运行后由 HPA 接管波动范围。
什么时候适合 HPA#
适合:
- 无状态 Web 服务。
- 可以水平扩展的 API 服务。
- 消费队列的 Worker。
- 流量有明显峰谷的服务。
- 扩容后能较快分担压力的服务。
不太适合:
- 单副本强状态服务。
- 启动非常慢的服务。
- 扩容不能改善瓶颈的服务,例如数据库已经成为瓶颈。
- 对连接状态极其敏感,且没有优雅下线能力的服务。
- 指标延迟很大或波动很剧烈的场景。
HPA 的前提是:
增加 Pod 副本,确实能提升处理能力。如果瓶颈在数据库、锁、外部 API、磁盘 IO,HPA 只会增加更多等待者。
和 Cluster Autoscaler 的关系#
HPA 只负责创建更多 Pod。
如果集群节点资源不够,新 Pod 会 Pending。
这时需要 Cluster Autoscaler 或类似节点扩容机制把 Node 加进来。
链路是:
指标升高
↓
HPA 增加 replicas
↓
新 Pod Pending,因为节点资源不足
↓
Cluster Autoscaler 增加节点
↓
调度器把 Pod 放到新节点所以线上自动扩容通常是组合拳:
HPA + 合理 requests/limits + Cluster Autoscaler + PodDisruptionBudget + 优雅退出常见排查命令#
# 查看 HPA 当前状态
kubectl get hpa
kubectl describe hpa web
# 查看目标 Deployment
kubectl get deploy web
kubectl describe deploy web
# 查看 Pod 资源指标
kubectl top pod -l app=web
kubectl top pod -A
# 直接检查 metrics API
kubectl get --raw /apis/metrics.k8s.io/v1beta1/pods
kubectl get --raw /apis/metrics.k8s.io/v1beta1/nodes
# 查看 metrics-server
kubectl -n kube-system get deploy metrics-server
kubectl -n kube-system logs deploy/metrics-server --tail=100kubectl describe hpa 很关键,它会显示当前指标、目标指标、无法扩缩容的原因和事件。
常见问题#
HPA 显示 unknown#
常见原因:
- metrics-server 没有安装或不可用。
- Pod 缺少 CPU request。
- metrics API 聚合层异常。
- 目标对象没有可读指标。
CPU 很高但不扩容#
检查:
- 是否超过
maxReplicas。 - HPA 指标类型是不是写成了
AverageValue或Utilization。 - Pod 是否有 CPU request。
- 当前平均值是否真的超过目标值。
- HPA 是否处在稳定窗口或策略限制内。
扩容了但服务仍然慢#
HPA 只说明 Pod 数量增加了,不说明系统瓶颈消失了。
继续看:
- 应用启动时间。
- readinessProbe 是否过早放流量。
- 数据库连接池。
- 下游 API 限流。
- 队列消费速度。
- 节点资源和调度情况。
频繁扩缩容#
可以调整:
- 指标选择,避免过于抖动的指标。
behavior.scaleDown.stabilizationWindowSeconds。- scaleUp / scaleDown policies。
- minReplicas,保留基础容量。
- 应用缓存和连接预热策略。
总结#
HPA 的本质是一个控制器:
观察指标 -> 计算期望副本数 -> 更新 scale 子资源。它非常适合无状态、可水平扩展、指标反馈及时的服务。
但它不是容量治理的全部。真正稳定的自动扩缩容,需要同时处理资源 request、指标体系、节点扩容、应用启动、优雅退出和下游瓶颈。