容器水平伸缩(Horizontal Pod Autoscaler,HPA)是实现工作负载弹性伸缩的主要方式,为了提高 HPA 对工作负载伸缩的稳定性,保障业务长稳运行,本文对 HPA 的实践进行了梳理和总结。
HPA 需要选择合适的指标并配置合理的伸缩阈值,保证业务负载伸缩及时准确。
容器服务控制台目前已经提供了 CPU、内存、网络、GPU 等 HPA 常用指标的配置能力,可以满足大部分使用场景。详情请参见:
对于特定场景,还可以通过 自定义指标伸缩 的形式提高伸缩的及时性和准确性。其中:
container_memory_rss
而非默认的container_memory_working_set_bytes
。DCGM_FI_PROF_SM_ACTIVE
。说明
容器服务中的常见指标,请参见 指标参考。
当集群配置并接入了 VMP 工作区,可以通过 PromQL 查询工作负载资源使用情况,进而评估 HPA 配置的指标阈值。
以 CPU 指标为例,查询和观察工作负载下 Pod 的资源使用情况可以分为两种类型:
avg(rate(container_cpu_usage_seconds_total{cluster="cxxx",namespace="xxx",pod=~"xxx-.*",pod!="",container!=""}[1m]))
。max(sum(rate(container_cpu_usage_seconds_total{cluster="cxxx",namespace="xxx",pod=~"xxx-.*",pod!="",container!=""}[1m])) by (pod))
。对于非核心负载,考虑到对资源成本的平衡,可以使用 Pod 资源用量的最大值评估 HPA 伸缩阈值。对于核心负载,从稳定性的角度出发,建议使用 Pod 资源用量的平均值评估 HPA 伸缩阈值。
HPA 为了避免因为工作负载的业务指标波动而频繁伸缩,使用容差限制伸缩行为。
HPA 的容差由集群控制面参数定义,默认取值为10%(即 0.1),当工作负载的指标变化量相较阈值未超过容差时,HPA 不会进行伸缩操作。以 CPU 指标为例,取利用率阈值为 80%,则 HPA 实际产生作用的伸缩行为是:
80*(1+0.1)=88
,扩容工作负载。80*(1-0.1)=72
,缩容工作负载。HPA 支持配置多个指标,只要至少一个指标可以正常获取,那么 HPA 就可以正常对工作负载进行伸缩,提高伸缩的稳定性。
当 HPA 同时使用多个指标时,多个指标会独立计算预期副本数,HPA 会取最大值对工作负载进行伸缩,保障伸缩的及时性。
HPA 通过修改工作负载的预期副本数实现弹性伸缩,HPA 支持配置伸缩规则实现细粒度的伸缩行为管控。
伸缩规则的配置和使用参见 通过控制台配置指标伸缩。
当 HPA 未显式配置伸缩规则时,HPA 会使用默认的伸缩规则,此时扩容和缩容操作会共享静默时间,即每次进行伸缩时都会以过去 5 分钟内根据工作负载指标所计算出的最大副本数为基准进行,这意味着如果工作负载出现过短暂的异常过载,此时如果 HPA 计算过预期副本数,那么 HPA 就会在接下来的 5 分钟为工作负载持续扩容大量副本。这些扩容出的副本虽然之后也会被 HPA 自动回收,但在扩容过程中可能造成以下两方面的影响:
为了避免工作负载因为异常过载而持续扩容大量副本,所有 HPA 都应显式配置伸缩规则,使得扩容行为和缩容行为可以互相独立的进行控制。对于运行特征尚不明确的工作负载可以显式配置 HPA 的默认伸缩规则:
behavior: scaleDown: stabilizationWindowSeconds: 300 policies: - type: Percent value: 100 periodSeconds: 15 scaleUp: stabilizationWindowSeconds: 0 policies: - type: Percent value: 100 periodSeconds: 15 - type: Pods value: 4 periodSeconds: 15 selectPolicy: Max
HPA 的预期副本数由指标计算,伸缩规则用于控制从工作负载的当前副本数逐步伸缩到预期副本数的速率。
工作负载以倍数形式扩容,比如当指标上升时立即触发扩容,副本数以1->9->81->729->...
进行变化,配置如下:
behavior: scaleUp: stabilizationWindowSeconds: 0 policies: - type: Percent value: 900 periodSeconds: 15 selectPolicy: Max
工作负载以整数形式扩容,比如扩容提供 300 秒的持续观察时间,副本数以1->3->5->7->...
进行变化,配置如下:
behavior: scaleUp: stabilizationWindowSeconds: 300 policies: - type: Pods value: 2 periodSeconds: 15 selectPolicy: Max
工作负载先以倍数形式扩容,再以整数形式扩容,比如副本数以1->9->81->161->...
进行变化,配置如下:
behavior: scaleUp: stabilizationWindowSeconds: 0 policies: - type: Percent value: 900 periodSeconds: 15 - type: Pods value: 80 periodSeconds: 15 selectPolicy: Min
工作负载以百分比数形式缩容,比如当前副本数为100
,当指标下降时立即触发,副本数以100->1
进行变化,配置如下:
behavior: scaleDown: stabilizationWindowSeconds: 300 policies: - type: Percent value: 100 periodSeconds: 15 selectPolicy: Max
工作负载以整数形式缩容,比如当前副本数为7
,提供 300 秒的持续观察时间,副本数以7->5->3->1
进行变化,配置如下:
behavior: scaleDown: stabilizationWindowSeconds: 300 policies: - type: Pods value: 2 periodSeconds: 15 selectPolicy: Max
工作负载先以百分比形式缩容,再以整数形式缩容,比如当前副本数为100
,副本数以100->60->36->21->...
进行变化,配置如下:
behavior: scaleDown: stabilizationWindowSeconds: 300 policies: - type: Percent value: 40 periodSeconds: 15 - type: Pods value: 15 periodSeconds: 15 selectPolicy: Max
HPA 主要有autoscaling/v2beta2
和autoscaling/v2
两个 API 版本,并且两个版本是兼容的,但是在 Kubernetes ≥ 1.26 版本时,autoscaling/v2beta2
将遭到废弃,因此建议用户统一使用autoscaling/v2
稳定版本。
同一个工作负载可以配置多个 HPA,但是这很容易导致不可预见的行为或冲突,因此建议单个工作负载只配置一个对应的 HPA 进行水平伸缩。
CronHPA 的工作方式受同一工作负载的 HPA 影响:
智能伸缩(IHPA) 提供了 DryRun 模式,用户可以在 HPA 正常工作的同时为工作负载配置 IHPA,在 IHPA 稳定运行并满足工作负载伸缩需求时,切换 IHPA 工作模式并删除原有的 HPA。
HPA 用于对工作负载水平伸缩,VPA 用于对工作负载垂直伸缩,两者使用场景不同,不建议在同一工作负载下同时配置 HPA 和 VPA。