2. HPA 工作原理:控制循环、指标采集周期与目标副本数计算算法

Horizontal Pod Autoscaler(HPA)是 Kubernetes 实现工作负载弹性伸缩的核心控制器。理解 HPA 的内部运行机制,是正确配置自定义 metric 触发器的前提。本章深入剖析 HPA 的三个关键环节:控制循环、指标采集周期以及目标副本数计算算法。

2.1 HPA 控制循环

HPA 作为一个独立的控制器,运行在 kube-controller-manager 进程中。它采用周期性、事件驱动的工作模式,每个周期称为一次“调谐(Reconcile)”。

核心要点: HPA 不直接管理 Pod,而是通过更新其目标资源(Deployment、StatefulSet 等)的 spec.replicas 字段来触发伸缩。实际的 Pod 创建/删除由 ReplicaSet 控制器或 StatefulSet 控制器执行。

一次完整的 HPA 控制循环包含以下步骤:

  1. 获取目标资源当前副本数:从 API Server 读取目标资源(如 Deployment)的 spec.replicas 和 status.replicas。
  2. 采集指标数据:根据 HPA 配置的 metric 规格,向 metrics.k8s.io(Resource Metric)、custom.metrics.k8s.io(Custom Metric)或 external.metrics.k8s.io(External Metric)API 发起查询,获取当前 Pod 或对象的指标值。
  3. 计算期望副本数:将采集到的指标值与 HPA 中定义的“目标值”进行比较,使用核心算法计算出期望的副本数。
  4. 决策与限速:将期望副本数与当前副本数对比,结合冷却(Cooldown)和容忍度(Tolerance)策略,决定是否执行伸缩。
  5. 更新目标资源:如果决定伸缩,则通过 API Server 更新目标资源的 spec.replicas。
HPA 控制循环流程图 HPA 控制循环(调谐周期) 获取当前副本数 采集指标数据 计算期望副本数 决策与限速 更新目标资源 循环周期 默认:15 秒 --horizontal-pod-autoscaler-sync-period 可配置:10s ~ 30s

2.2 指标采集周期与数据源

HPA 的指标采集并非与控制循环完全同步。指标数据由独立的 Metrics Server(资源指标)或 Adapter(自定义/外部指标)负责采集和聚合,HPA 通过 API 查询这些聚合后的数据。

指标类型 API 端点 采集组件 默认采集周期 数据新鲜度
Resource Metric metrics.k8s.io Metrics Server 60 秒(kubelet 汇总) 通常 ≤ 60 秒
Custom Metric custom.metrics.k8s.io Custom Metrics Adapter(如 Prometheus Adapter) 30 ~ 60 秒(取决于 Adapter 配置) 通常 ≤ 120 秒
External Metric external.metrics.k8s.io External Metrics Adapter(如 AWS/GCP Adapter) 60 ~ 300 秒(取决于外部系统) 通常 ≤ 300 秒
实践建议: 自定义 metric 的采集周期直接影响 HPA 的响应速度。如果业务流量突增在 10 秒内,而指标采集周期为 60 秒,HPA 可能需要 60~75 秒才能感知到变化。对于延迟敏感的场景,应缩短 Adapter 的采集间隔,并配合 --horizontal-pod-autoscaler-sync-period 参数使用。

2.3 目标副本数计算算法

HPA 的核心算法基于一个简单的比例公式,但针对多指标、多 Pod 的情况进行了扩展和优化。

2.3.1 单指标、单 Pod 的基础公式

对于单个 Pod 的单个指标(如 CPU 使用率),期望副本数的计算公式为:

期望副本数 = ceil[ 当前副本数 × ( 当前指标值 / 目标指标值 ) ]

例如:当前 2 个 Pod,当前 CPU 使用率平均为 80%,目标值为 50%。

期望副本数 = ceil[ 2 × ( 80% / 50% ) ] = ceil[ 2 × 1.6 ] = ceil[ 3.2 ] = 4

2.3.2 多 Pod 场景:取平均值

当目标资源有多个 Pod 时,HPA 会先计算所有 Pod 的当前指标值的平均值,再代入公式:

平均指标值 = sum(Pod_i 的指标值) / Pod 数量
期望副本数 = ceil[ 当前副本数 × ( 平均指标值 / 目标指标值 ) ]

2.3.3 多指标场景:取最大值

当 HPA 配置了多个指标(如 CPU + QPS)时,HPA 会为每个指标独立计算出一个期望副本数,然后取其中的最大值作为最终的期望副本数。这确保了任何一个指标过载时都会触发扩容。

算法特性: 多指标取最大值的策略意味着“短板效应”——只要有一个指标达到扩容阈值,就会扩容。缩容时则相反,需要所有指标都满足缩容条件才会触发。
多指标期望副本数计算流程 多指标 HPA 期望副本数计算 当前副本数 = 4 指标 1: CPU 平均 75% / 目标 50% 指标 2: QPS 平均 1200 / 目标 1000 计算期望副本数 ceil(4 × 75/50) = 6 计算期望副本数 ceil(4 × 1200/1000) = 5 取最大值 max(6, 5) = 6

2.3.4 容忍度与冷却机制

为了防止指标抖动导致频繁伸缩(即“抖动”或“乒乓效应”),HPA 引入了两个关键机制:

  • 容忍度(Tolerance):默认值为 0.1(10%)。只有当 |期望副本数 - 当前副本数| / 当前副本数 > 容忍度 时,才会触发伸缩。例如,当前 10 个 Pod,计算出的期望副本数为 10.8,由于 (10.8 - 10) / 10 = 0.08 < 0.1,HPA 不会执行扩容。
  • 冷却(Cooldown):通过 --horizontal-pod-autoscaler-downscale-stabilization-window(默认 5 分钟)控制缩容冷却。HPA 会记录过去一段时间内计算出的所有期望副本数,并取其中的最大值作为实际缩容目标,避免因瞬时指标下降而过度缩容。
常见误区: 冷却机制只作用于缩容。扩容没有内置冷却窗口,但容忍度机制和指标采集周期会间接限制扩容频率。如果希望限制扩容速度,可以通过 behavior.scaleUp.stabilizationWindowSeconds 字段(HPA v2)进行配置。

2.4 算法总结与关键参数

参数/机制 默认值 作用 配置位置
控制循环周期 15 秒 HPA 控制器调谐频率 kube-controller-manager --horizontal-pod-autoscaler-sync-period
容忍度 0.1 (10%) 避免微小波动触发伸缩 硬编码,不可配置
缩容稳定窗口 300 秒 缩容冷却,取窗口内最大期望值 --horizontal-pod-autoscaler-downscale-stabilization-window
指标采集周期 60 秒(资源指标) Metrics Server/Adapter 采集频率 Metrics Server 启动参数或 Adapter 配置
多指标策略 取最大值 确保任一指标过载时扩容 HPA spec.metrics 定义