📚 HPA 完整知识体系
一、HPA 工作原理
1.1 架构组件
┌─────────────────────────────────────────────────────────────┐
│ HPA Controller │
│ (kube-controller-manager 的一部分) │
└────────────┬────────────────────────────────────────────────┘
│
│ 每 15s 查询一次指标
▼
┌─────────────────────────────────────────────────────────────┐
│ Metrics Server │
│ (收集节点和 Pod 的 CPU/内存指标) │
└────────────┬────────────────────────────────────────────────┘
│
│ 从 kubelet 获取指标
▼
┌─────────────────────────────────────────────────────────────┐
│ Kubelet │
│ (cAdvisor 收集容器指标) │
└─────────────────────────────────────────────────────────────┘
1.2 扩缩容决策流程
1. HPA Controller 定期检查 (默认 15s)
↓
2. 从 Metrics Server 获取当前指标值
↓
3. 计算期望副本数
desiredReplicas = ceil[currentReplicas * (currentMetricValue / targetMetricValue)]
↓
4. 应用扩缩容策略 (behavior)
↓
5. 检查约束条件
- minReplicas ≤ desiredReplicas ≤ maxReplicas
- PDB 限制
- 稳定窗口期
↓
6. 更新 Deployment.spec.replicas
二、当前 HPA 配置详解
2.1 完整配置文件
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: ai-gateway
labels:
app.kubernetes.io/name: ai-gateway
app.kubernetes.io/component: backend
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: ai-gateway
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 30
- type: Pods
value: 2
periodSeconds: 30
selectPolicy: Max
三、逐行配置解析
3.1 基本配置
apiVersion: autoscaling/v2 # v2 版本支持多指标和高级策略
kind: HorizontalPodAutoscaler
metadata:
name: ai-gateway
spec:
scaleTargetRef: # 要控制的目标
apiVersion: apps/v1
kind: Deployment
name: ai-gateway # 控制 ai-gateway Deployment
说明:HPA 通过修改 Deployment 的 spec.replicas 字段来控制副本数。
3.2 副本数范围
minReplicas: 2 # 最小 2 个副本(保证高可用)
maxReplicas: 10 # 最大 10 个副本(防止无限扩容)
实际行为:
- 即使负载为 0,也保持 2 个 Pod 运行
- 即使负载爆炸,最多只扩到 10 个 Pod
- 如果手动设置
kubectl scale deployment ai-gateway --replicas=15,HPA 会在下次检查时改回 ≤10
3.3 指标配置(Metrics)
CPU 指标
metrics:
- type: Resource # 资源类型指标
resource:
name: cpu # CPU 指标
target:
type: Utilization # 使用率类型
averageUtilization: 70 # 目标:平均 70% CPU 使用率
计算公式:
当前所有 Pod 的平均 CPU 使用率 = Σ(每个 Pod 的 CPU 使用量) / Σ(每个 Pod 的 CPU request)
期望副本数 = ceil(当前副本数 × (当前平均使用率 / 目标使用率))
示例场景:
当前状态:
- 副本数:2
- Pod1 CPU: 350m (request: 100m) → 350%
- Pod2 CPU: 250m (request: 100m) → 250%
- 平均使用率:(350% + 250%) / 2 = 300%
计算:
期望副本数 = ceil(2 × (300 / 70)) = ceil(8.57) = 9
结果:扩容到 9 个副本
内存指标
- type: Resource
resource:
name: memory # 内存指标
target:
type: Utilization
averageUtilization: 80 # 目标:平均 80% 内存使用率
多指标策略:
- HPA 会分别计算每个指标的期望副本数
- 取最大值作为最终副本数
- 例如:CPU 算出需要 5 个,内存算出需要 7 个 → 最终扩到 7 个
3.4 扩缩容行为(Behavior)- 核心机制
缩容策略(ScaleDown)
behavior:
scaleDown:
stabilizationWindowSeconds: 300 # 稳定窗口:5 分钟
稳定窗口作用:
- 在过去 5 分钟内,HPA 会记录所有建议的副本数
- 取这 5 分钟内的最大值作为缩容目标
- 防止抖动:避免负载短暂下降就立即缩容
示例时间线:
时间 当前副本 瞬时建议 5分钟最大值 实际操作
14:00 10 10 10 -
14:01 10 8 10 不缩容(5分钟内最大是10)
14:02 10 7 10 不缩容
14:03 10 6 10 不缩容
14:04 10 6 10 不缩容
14:05 10 6 10 不缩容
14:06 10 6 8 缩到 8(14:01的10已过期)
policies:
- type: Percent # 百分比策略
value: 50 # 每次最多缩减 50%
periodSeconds: 60 # 每 60 秒评估一次
缩容速率限制:
- 每 60 秒最多缩减当前副本数的 50%
- 例如:10 个副本 → 最多缩到 5 个(一次)
缩容时间线示例:
时间 当前副本 目标副本 实际操作
14:00 10 2 缩到 5(最多减50%)
14:01 5 2 缩到 3(最多减50%,5×0.5=2.5,向上取整)
14:02 3 2 缩到 2(最多减50%,3×0.5=1.5,向上取整)
扩容策略(ScaleUp)
scaleUp:
stabilizationWindowSeconds: 0 # 无稳定窗口,立即扩容
为什么扩容不需要稳定窗口?
- 负载突增需要快速响应
- 扩容的成本低于服务不可用的成本
- 缩容有稳定窗口兜底,不会频繁抖动
policies:
- type: Percent # 策略1:百分比
value: 100 # 每次最多扩容 100%(翻倍)
periodSeconds: 30 # 每 30 秒评估一次
- type: Pods # 策略2:固定数量
value: 2 # 每次最多增加 2 个 Pod
periodSeconds: 30 # 每 30 秒评估一次
selectPolicy: Max # 选择策略:取最大值
多策略选择机制:
selectPolicy: Max→ 取两个策略中扩容更快的那个selectPolicy: Min→ 取两个策略中扩容更慢的那个selectPolicy: Disabled→ 禁用扩容
扩容速率计算示例:
| 当前副本 | 策略1 (100%) | 策略2 (+2) | Max 选择 | 实际扩到 |
|---|---|---|---|---|
| 2 | 4 (翻倍) | 4 (+2) | 4 | 4 |
| 4 | 8 (翻倍) | 6 (+2) | 8 | 8 |
| 8 | 16 (翻倍) | 10 (+2) | 16 | 10 (受限于 maxReplicas) |
四、HPA 计算实战演练
场景 1:CPU 负载突增
初始状态:
- 副本数:2
- CPU request:100m/Pod
- 当前 CPU 使用:
- Pod1: 90m (90%)
- Pod2: 85m (85%)
- 平均使用率:87.5%
计算:
期望副本数 = ceil(2 × (87.5 / 70)) = ceil(2.5) = 3
扩容策略检查:
- 策略1:2 × 100% = 4 个
- 策略2:2 + 2 = 4 个
- Max(4, 4) = 4
但计算结果只需要 3 个,所以扩到 3 个
场景 2:内存负载更高
同时检查内存:
- 内存 request:512Mi/Pod
- 当前内存使用:
- Pod1: 480Mi (93.75%)
- Pod2: 460Mi (89.84%)
- 平均使用率:91.8%
计算:
期望副本数 = ceil(2 × (91.8 / 80)) = ceil(2.3) = 3
多指标决策:
- CPU 建议:3 个
- 内存建议:3 个
- 取 Max(3, 3) = 3
最终:扩到 3 个副本
场景 3:负载下降后缩容
当前状态:
- 副本数:10
- CPU 平均使用率:30%
- 内存平均使用率:40%
计算:
- CPU 期望:ceil(10 × (30 / 70)) = 5
- 内存期望:ceil(10 × (40 / 80)) = 5
- 取 Max(5, 5) = 5
缩容策略检查:
- 最多缩减 50%:10 × 0.5 = 5
- 稳定窗口:过去 5 分钟内最大建议是 5
时间线:
14:00 - 10 个副本,建议 5 个,记录到窗口
14:01 - 10 个副本,建议 5 个,窗口内最大=10(14:00之前的记录)
...
14:05 - 10 个副本,建议 5 个,窗口内最大=5
14:05 - 执行缩容到 5 个
五、HPA 常见问题与优化
5.1 为什么 Pod 数量一直抖动?
原因:
- 稳定窗口太短
- 指标波动大
- 扩缩容阈值太接近
解决方案:
behavior:
scaleDown:
stabilizationWindowSeconds: 600 # 增加到 10 分钟
policies:
- type: Percent
value: 25 # 降低缩容速率到 25%
periodSeconds: 120 # 增加评估周期到 2 分钟
5.2 为什么 HPA 不工作?
排查步骤:
# 1. 检查 HPA 状态
kubectl get hpa ai-gateway -n ai-platform-prod
# 2. 查看详细信息
kubectl describe hpa ai-gateway -n ai-platform-prod
# 3. 检查 Metrics Server
kubectl top nodes
kubectl top pods -n ai-platform-prod
# 4. 查看 HPA 事件
kubectl get events -n ai-platform-prod --field-selector involvedObject.name=ai-gateway
常见错误:
❌ unable to get metrics for resource cpu
→ Deployment 没有设置 resources.requests
❌ missing request for cpu
→ Pod 的 CPU request 未设置
❌ failed to get cpu utilization
→ Metrics Server 未安装或异常
5.3 CPU vs 内存指标选择
| 指标 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| CPU | 计算密集型应用 | 响应快,波动明显 | 可能频繁抖动 |
| 内存 | 内存密集型应用 | 稳定 | 缩容慢(内存不会立即释放) |
| 自定义指标 | 业务指标(QPS、延迟) | 更贴近业务 | 需要额外组件 |
建议:
- Web 服务:CPU 70% + 自定义 QPS
- 缓存服务:内存 80%
- 队列消费者:自定义队列长度
六、高级 HPA 配置
6.1 基于自定义指标扩缩容
metrics:
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "1000" # 每个 Pod 处理 1000 QPS
需要组件:
- Prometheus Adapter
- ServiceMonitor 采集指标
6.2 基于外部指标
metrics:
- type: External
external:
metric:
name: queue_messages_ready
selector:
matchLabels:
queue: "tasks"
target:
type: AverageValue
averageValue: "30" # 每个 Pod 处理 30 条消息
适用场景:
- 消息队列长度
- 数据库连接数
- 外部 API 响应时间
6.3 多阶段扩缩容策略
behavior:
scaleUp:
policies:
# 阶段1:快速扩容(前 2 分钟)
- type: Percent
value: 100
periodSeconds: 15
# 阶段2:稳定扩容(2 分钟后)
- type: Percent
value: 50
periodSeconds: 60
selectPolicy: Max
stabilizationWindowSeconds: 120 # 2 分钟后切换策略
七、当前 HPA 配置评估
优点 ✅
- 双指标保护:CPU + 内存,全面覆盖
- 快速扩容:stabilizationWindowSeconds=0,响应迅速
- 防止缩容抖动:5 分钟稳定窗口
- 合理的扩容速率:100% 翻倍 + 固定增加 2 个
可优化点 ⚠️
-
CPU request 过低:
# 当前 requests: cpu: "100m" # ai-gateway cpu: "50m" # ai-iwdrama # 建议 requests: cpu: "250m" # 提高到 250m,避免频繁扩容 -
缩容速率可能过快:
# 当前:每分钟缩减 50% # 建议:降低到 25-30% policies: - type: Percent value: 30 periodSeconds: 90 -
缺少自定义指标:
# 建议添加 QPS 指标 - type: Pods pods: metric: name: http_requests_per_second target: type: AverageValue averageValue: "500"
八、HPA 最佳实践总结
8.1 配置原则
✅ DO:
- 设置合理的 minReplicas(≥2 保证高可用)
- CPU request 设置为实际使用的 50-70%
- 扩容快、缩容慢
- 使用稳定窗口防抖动
- 多指标组合使用
❌ DON'T:
- minReplicas = 1(单点故障)
- 不设置 resources.requests
- 扩缩容阈值太接近(如 CPU 70% 扩容,65% 缩容)
- 同时手动修改 replicas(会被 HPA 覆盖)
8.2 监控指标
# 查看 HPA 推荐的副本数
kubectl get hpa ai-gateway -o jsonpath='{.status.desiredReplicas}'
# 查看当前指标值
kubectl get hpa ai-gateway -o jsonpath='{.status.currentMetrics}'
# 查看扩缩容历史
kubectl get events --field-selector involvedObject.name=ai-gateway
8.3 HPA 与其他组件配合
| 组件 | 配合方式 | 注意事项 |
|---|---|---|
| PDB | 限制最小可用副本 | PDB.minAvailable 应 < HPA.minReplicas |
| VPA | 垂直扩缩容 | 不要同时使用 VPA 和 HPA 的 CPU/内存指标 |
| Cluster Autoscaler | 节点扩缩容 | HPA 扩容后可能触发 CA 添加节点 |
| Resource Quota | 命名空间资源限制 | 确保 Quota 足够 HPA 扩容 |
九、企业级 HPA 配置模板
9.1 Web 服务(推荐配置)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-service
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-service
minReplicas: 3
maxReplicas: 20
metrics:
# CPU 指标
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
# 内存指标
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
# 自定义 QPS 指标
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "1000"
behavior:
scaleDown:
stabilizationWindowSeconds: 600 # 10 分钟
policies:
- type: Percent
value: 25
periodSeconds: 120
- type: Pods
value: 1
periodSeconds: 120
selectPolicy: Min # 缩容保守
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 30
- type: Pods
value: 4
periodSeconds: 30
selectPolicy: Max # 扩容激进
9.2 队列消费者(推荐配置)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: queue-consumer
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: queue-consumer
minReplicas: 2
maxReplicas: 50
metrics:
# 基于队列长度
- type: External
external:
metric:
name: rabbitmq_queue_messages_ready
selector:
matchLabels:
queue: "tasks"
target:
type: AverageValue
averageValue: "30" # 每个 Pod 处理 30 条消息
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 200 # 可以 3 倍扩容
periodSeconds: 15
- type: Pods
value: 10 # 或者直接加 10 个
periodSeconds: 15
selectPolicy: Max
十、HPA 故障排查清单
10.1 HPA 不扩容
# 1. 检查 HPA 状态
kubectl get hpa -n <namespace>
# 2. 查看详细信息
kubectl describe hpa <hpa-name> -n <namespace>
# 3. 检查 Metrics Server
kubectl get apiservice v1beta1.metrics.k8s.io -o yaml
# 4. 检查 Pod 指标
kubectl top pods -n <namespace>
# 5. 检查 Deployment 的 resources.requests
kubectl get deployment <name> -n <namespace> -o yaml | grep -A 5 resources
10.2 HPA 频繁抖动
# 1. 查看 HPA 事件
kubectl get events -n <namespace> --field-selector involvedObject.name=<hpa-name>
# 2. 查看指标历史
kubectl get hpa <hpa-name> -n <namespace> --watch
# 3. 调整稳定窗口
# 增加 stabilizationWindowSeconds
# 4. 调整阈值
# 拉大扩缩容阈值差距
10.3 HPA 不缩容
# 1. 检查 PDB 限制
kubectl get pdb -n <namespace>
# 2. 检查稳定窗口
# 查看 stabilizationWindowSeconds 是否过长
# 3. 检查是否有手动设置 replicas
kubectl get deployment <name> -n <namespace> -o yaml | grep replicas
总结
HPA 是 Kubernetes 中实现弹性伸缩的核心组件,通过合理配置可以:
- 提高可用性:自动应对流量波动
- 降低成本:按需使用资源
- 提升性能:保持最优资源利用率
关键要点:
- 扩容要快,缩容要慢
- 使用稳定窗口防止抖动
- 多指标组合使用
- 定期监控和调优
文档生成时间:2026-01-30 适用版本:Kubernetes 1.23+ HPA API 版本:autoscaling/v2