HPA 是 K8S 的一大利器. 通过 HPA, 我们可以让服务的 pod 数量根据特定指标自动增加或减少, 使得在高峰期有足够的资源服务请求, 在低峰期又可以避免占用过多的资源. 同时, 在 SOA 架构下, 我们也习惯通过 HPA 来避免劳心劳力的为每个微服务计算所需的资源.
HPA 的几个关键参数:
以下案例就指定了 demo 的最小 pod 数量为 2, 最大为 8.
spec:
maxReplicas: 8
minReplicas: 2
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: demo
targetCPUUtilizationPercentage: 250
targetCPUUtilizationPercentage 是旧版本 API 中的字段, 指定了所有 pod 的 CPU 平均使用率高于 250% 是进行扩容, 低于 250% 时进行缩容. 当以 CPU 使用率为扩容缩容的标准时, 我们需要注意对应数值是与 usage/request 比较, 而不是 usage/limit. 即分子是实际使用的 CPU 时间, 分母是在 deployment 中申请的 CPU 时间.
HPA 计算所需 pod 数量的公式比较直观:
desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]
在上述案例中, desireMetricValue 为 250.
如果实际 CPU 使用率为 320, 当前 pod 数量为 4, 则 desiredReplicas = ceil[4 * (320/ 250)], 即 5.12 向上取整的结果 6.
在实际计算中, HPA 会额外区分出 unreadyPod, missingPod 和 ignoredPod, 并根据初步计算结果选择忽视某些类型的 pod 指标再次计算, 突出一个稳. 具体逻辑可以参考 calcPlainMetricReplicas, 简单而言:
最后需要注意的是, 当开启了 HPA 后, 我们不应该再设置 deployment 的 spec.replicas. 否则, 当你发布时, K8S 会按照 spec.replicas 来计算诸如 rolling update 的步骤, 导致一些非预期的行为. 比如说, spec.replicas 为 6, HPA 的范围为 2 到 25, 当前实际 pod 数量为 20, 则一旦发布, 大概率会出现 14 个以上的 pod 同时被销毁, 导致服务用户请求的资源锐减, 业务出现抖动.