3. HPA工作原理与配置

HorizontalPodAutoscaler(HPA)是 Kubernetes 中最常用的工作负载水平扩缩容控制器。它并不直接“感知”业务压力,而是通过一个周期性控制循环,从指标来源获取当前值,与用户设定的目标值比较,再按算法计算出期望副本数,最后写入目标工作负载的 scale 子资源。理解这条链路,是正确配置 HPA 并排查“不扩容”“扩过头”“频繁抖动”等问题的前提。

控制器循环:一次调谐做了什么

HPA 控制器由 kube-controller-manager 中的 horizontalpodautoscaler 控制器实现,默认每 15 秒执行一次调谐(可通过 --horizontal-pod-autoscaler-sync-period 调整)。每次循环大致经历以下阶段:

  1. 获取目标对象:读取 HPA 的 scaleTargetRef,定位 Deployment、StatefulSet 或 ReplicaSet 等可伸缩对象。
  2. 采集指标:从 metrics API 获取当前指标值。资源指标(CPU、内存)由 metrics-server 提供,自定义指标由 Prometheus Adapter 等适配器提供。
  3. 计算期望副本数:按扩缩容算法得到 desiredReplicas。
  4. 应用行为策略:根据 behavior 中的稳定窗口、扩缩容速率限制,对期望值进行修正。
  5. 写入 scale 子资源:更新目标对象的副本数,并回写 HPA 的 status(当前副本、期望副本、当前指标值、条件等)。

如果指标缺失或不可用,HPA 不会立即缩容,而是保持当前副本数并记录事件,避免因监控抖动导致误缩容。

指标聚合:从 Pod 到工作负载

HPA 的指标来源分为三类:Resource(CPU、内存)、Pods(自定义 Pod 指标)、Object/External(对象指标与外部指标)。以最常用的 CPU 利用率为例,计算过程是:先取目标工作负载下所有就绪 Pod 的 CPU 使用量,再除以这些 Pod 的 CPU request 之和,得到平均利用率。因此,没有设置 CPU request 的 Pod 无法参与 CPU 利用率计算,HPA 会报 missing request for cpu 并停止扩缩容。

指标聚合还涉及“就绪”与“未就绪”Pod 的处理:默认情况下,未就绪 Pod 会被忽略;如果配置了 --horizontal-pod-autoscaler-initial-readiness-delay 和 --horizontal-pod-autoscaler-cpu-initialization-period,新 Pod 在启动初期会被特殊对待,避免冷启动阶段拉高平均值。

扩缩容算法:期望副本数怎么算

HPA 的核心公式为:

desiredReplicas = ceil[currentReplicas × (currentMetricValue / desiredMetricValue)]

例如,当前 4 个副本,CPU 平均利用率 80%,目标 50%,则期望副本数为 ceil(4 × 80/50) = ceil(6.4) = 7。若当前值低于目标值,公式同样适用,但结果会小于当前副本数,从而触发缩容。

算法还包含容差机制:默认 --horizontal-pod-autoscaler-tolerance=0.1,即当前指标与目标值的比值在 0.9~1.1 之间时,认为“足够接近”,不触发扩缩容。这能有效抑制指标微小波动带来的副本抖动。

当多个指标同时配置时,HPA 会分别计算每个指标的期望副本数,取其中最大值作为最终期望值,保证所有指标都能被满足。

行为策略:控制扩缩容的速度与节奏

从 Kubernetes 1.18 起,HPA 支持 behavior 字段,用于精细控制扩缩容行为。它分为 scaleUp 和 scaleDown 两部分,每部分可配置:

  • stabilizationWindowSeconds:稳定窗口。缩容时默认 300 秒,表示在窗口内取历史期望副本数的最大值,避免指标短暂下降就立即缩容。
  • selectPolicy:当多条策略匹配时选择 Max、Min 或 Disabled。
  • policies:速率限制策略,例如每 60 秒最多扩容 4 个 Pod 或 100% 副本数。

下面是一个典型配置:扩容允许较快,缩容则保守,稳定窗口 5 分钟,每分钟最多缩 1 个 Pod。

behavior:
  scaleUp:
    stabilizationWindowSeconds: 0
    policies:
    - type: Percent
      value: 100
      periodSeconds: 60
  scaleDown:
    stabilizationWindowSeconds: 300
    policies:
    - type: Pods
      value: 1
      periodSeconds: 60
    selectPolicy: Min

常见配置项与排查要点

一个可用的 HPA 至少需要正确设置 scaleTargetRef、minReplicas、maxReplicas 和 metrics。常见问题包括:目标对象没有设置 resource request、metrics-server 未就绪、指标适配器未注册、HPA 与 VPA 同时操作同一工作负载导致冲突。排查时可用 kubectl describe hpa 查看事件与当前指标,用 kubectl get hpa -w 观察副本变化。

HPA 控制循环与扩缩容决策链 指标来源 metrics-server(CPU/内存) Prometheus Adapter(自定义) 指标聚合 就绪 Pod 平均利用率 忽略未就绪 / 冷启动 扩缩容算法 ceil(当前 × 当前值/目标值) 容差 ±10% 抑制抖动 行为策略 稳定窗口 速率限制 目标工作负载(Deployment / StatefulSet) scale 子资源:spec.replicas HPA status 回写 currentReplicas / desiredReplicas / 指标值 下一轮调谐(默认 15s) 示例:4 副本 × 80% / 50% = 6.4 → ceil = 7 副本;若比值在 0.9~1.1 内则保持当前副本数

掌握这条链路后,配置 HPA 就不再是“填几个字段”,而是围绕指标可用性、算法容差、行为窗口和速率限制做系统性设计。实际生产中,建议先用 kubectl top pods 确认指标可读,再逐步调整 stabilizationWindowSeconds 与 policies,观察 kubectl get hpa -w 的副本变化是否符合预期。