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 控制循环包含以下步骤:
- 获取目标资源当前副本数:从 API Server 读取目标资源(如 Deployment)的
spec.replicas和status.replicas。 - 采集指标数据:根据 HPA 配置的 metric 规格,向 metrics.k8s.io(Resource Metric)、custom.metrics.k8s.io(Custom Metric)或 external.metrics.k8s.io(External Metric)API 发起查询,获取当前 Pod 或对象的指标值。
- 计算期望副本数:将采集到的指标值与 HPA 中定义的“目标值”进行比较,使用核心算法计算出期望的副本数。
- 决策与限速:将期望副本数与当前副本数对比,结合冷却(Cooldown)和容忍度(Tolerance)策略,决定是否执行伸缩。
- 更新目标资源:如果决定伸缩,则通过 API Server 更新目标资源的
spec.replicas。
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 会为每个指标独立计算出一个期望副本数,然后取其中的最大值作为最终的期望副本数。这确保了任何一个指标过载时都会触发扩容。
算法特性: 多指标取最大值的策略意味着“短板效应”——只要有一个指标达到扩容阈值,就会扩容。缩容时则相反,需要所有指标都满足缩容条件才会触发。
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 定义 |