Kubernetes HPA 深度解析

3 阅读10分钟

📚 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 选择实际扩到
24 (翻倍)4 (+2)44
48 (翻倍)6 (+2)88
816 (翻倍)10 (+2)1610 (受限于 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 数量一直抖动?

原因

  1. 稳定窗口太短
  2. 指标波动大
  3. 扩缩容阈值太接近

解决方案

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 配置评估

优点 ✅

  1. 双指标保护:CPU + 内存,全面覆盖
  2. 快速扩容:stabilizationWindowSeconds=0,响应迅速
  3. 防止缩容抖动:5 分钟稳定窗口
  4. 合理的扩容速率:100% 翻倍 + 固定增加 2 个

可优化点 ⚠️

  1. CPU request 过低

    # 当前
    requests:
      cpu: "100m"  # ai-gateway
      cpu: "50m"   # ai-iwdrama
    
    # 建议
    requests:
      cpu: "250m"  # 提高到 250m,避免频繁扩容
    
  2. 缩容速率可能过快

    # 当前:每分钟缩减 50%
    # 建议:降低到 25-30%
    policies:
    - type: Percent
      value: 30
      periodSeconds: 90
    
  3. 缺少自定义指标

    # 建议添加 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 中实现弹性伸缩的核心组件,通过合理配置可以:

  1. 提高可用性:自动应对流量波动
  2. 降低成本:按需使用资源
  3. 提升性能:保持最优资源利用率

关键要点

  • 扩容要快,缩容要慢
  • 使用稳定窗口防止抖动
  • 多指标组合使用
  • 定期监控和调优

文档生成时间:2026-01-30 适用版本:Kubernetes 1.23+ HPA API 版本:autoscaling/v2