HPA控制器算法

HPA 控制器与聚合 API 获取到 Pod 性能指标数据之后,基于下面的算法计算出目标 Pod 副本数量,与当前运行的 Pod 副本数量进行对比,决定是否需要进行扩缩容操作:

1
2
desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]
即当前副本数 * (当前指标值/期望的指标值),将结果向上取整

以 CPU 请求数量为例,如果用户设置的期望指标值为 100m,当前实际使用的指标值为 200,则结果得到期望的 Pod 副本数量应为两个(200/100=2)。如果设置的期望指标值为 50m,计算结果为 0.5,则向上取整为 1,得到目标 Pod 副本数量应为 1 个。当结果计算与 1 非常接近时,可以设置一个容忍度让系统不做扩缩容操作。容忍度通过 kube-controller-manager 服务的启动参数 --horizontal-pod-autoscaler-tolerance 进行设置,默认值为 0.1(即 10%),表示基于上述算法得到的结果在 [-10% + 10% ] 区间内,即 [ 0.9 - 1.1],控制器都不会进行扩缩容操作。

也可以将期望指标值设置为指标的平均值类型,例如 targetAverageValue 或 targetAverageUtilization,此时当前指标值的算法为所有 Pod 副本当前指标值的总和除以 Pod 副本数量得到的平均值。此外,存在几种 Pod 异常的情况,如下所述。

  • Pod 正在被删除:将不会计入目标 Pod 副本数量。

  • Pod 的当前指标值无法获得:本次探测不会将这个 Pod 纳入目标 Pod 副本数量,后续的探测会被重新纳入计算范围。

  • 如果指标类型是 CPU 使用率,则对于正在启动但是还未达到 Ready 状态的 Pod,也暂时不会纳入目标副本数量范围。可以通过 kube-controller-manager 服务的启动参数 --horizontal-pod-autoscaler-initial-readiness-delay 设置首次探测 Pod 是否 Ready 的延时时间,默认值为 30s。另一个启动参数 --horizontal-pod-autoscaler-cpu-initialization-period 用于标记刚启动一定时间内的 Pod 为 ignoredPod,实时获取不到信息的 Pod 被标记为 missingPod,默认为5min。

在计算 “当前指标值/期望的指标值” 时将不会包括上述这些异常 Pod。当存在缺失指标的 Pod 时,系统将更保守地重新计算平均值。系统会假设这些 Pod 在需要缩容时消耗了期望指标值的 100%,在需要扩容时消耗了期望指标值的 0%,这样可以抑制潜在额扩缩容操作。此外,如果存在未达到 Ready 状态的 Pod,并且系统原来会在不考虑缺失指标或 NotReady 的 Pod 情况下进行扩展,则系统仍会保守地假设这些 Pod 消耗期望指标值的 0%,从而进一步抑制扩容操作。如果在 HPA 中设置了多个指标,系统就会对每个指标都执行上面的算法,在全部结果中以期望副本数的最大值为最终结果。如果这些指标中的任意一个都无法转换为期望的副本数(例如无法获取指标的值),系统就会跳过扩缩容操作。最后,在 HPA 控制器执行扩缩容操作之前,系统会记录扩缩容建议信息。控制器会在操作时间窗口中考虑所有的建议信息,并从中选择得分最高的建议。这个值可通过 kube-controller-manager 服务的启动参数 --horizontal-pod-autoscaler-downscale-stabilization-window 进行配置,默认值为 5min。这个配置可以让系统更为平滑地进行缩容操作,从而消除短时间内指标值快速波动产生的影响。