更新时间:2024-12-18 GMT+08:00

工作负载伸缩原理

HPA工作原理

HPA(Horizontal Pod Autoscaler)是用来控制Pod水平伸缩的控制器,HPA周期性检查Pod的度量数据,计算满足HPA资源所配置的目标数值所需的副本数量,进而调整目标资源(如Deployment)的replicas字段。

想要做到自动弹性伸缩,先决条件就是能感知到各种运行数据,例如集群节点、Pod、容器的CPU、内存使用率等等。而这些数据的监控能力Kubernetes也没有自己实现,而是通过其他项目来扩展Kubernetes的能力,Kubernetes提供PrometheusMetrics Server插件来实现该能力:

  • Prometheus是一套开源的系统监控报警框架,能够采集丰富的Metrics(度量数据),目前已经基本是Kubernetes的标准监控方案。
  • Metrics Server是Kubernetes集群范围资源使用数据的聚合器。Metrics Server从kubelet公开的Summary API中采集度量数据,能够收集包括了Pod、Node、容器、Service等主要Kubernetes核心资源的度量数据,且对外提供一套标准的API。

使用HPA(Horizontal Pod Autoscaler)配合Metrics Server可以实现基于CPU和内存的自动弹性伸缩,再配合Prometheus还可以实现自定义监控指标的自动弹性伸缩。

HPA主要流程如图1所示。

图1 HPA流程图

HPA的核心有如下2个部分:

  • 监控数据来源

    最早社区只提供基于CPU和Mem的HPA,随着应用越来越多搬迁到K8s上以及Prometheus的发展,开发者已经不满足于CPU和Memory,开发者需要应用自身的业务指标,或者是一些接入层的监控信息,例如:Load Balancer的QPS、网站的实时在线人数等。社区经过思考之后,定义了一套标准的Metrics API,通过聚合API对外提供服务。

    • metrics.k8s.io: 主要提供Pod和Node的CPU和Memory相关的监控指标。
    • custom.metrics.k8s.io: 主要提供Kubernetes Object相关的自定义监控指标。
    • external.metrics.k8s.io:指标来源外部,与任何的Kubernetes资源的指标无关。
  • 扩缩容决策算法

    HPA controller根据当前指标和期望指标来计算缩放比例,计算公式如下:

    desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]

    例如当前的指标值是200m,目标值是100m,那么按照公式计算期望的实例数就会翻倍。那么在实际过程中,可能会遇到实例数值反复伸缩,导致集群震荡。为了保证稳定性,HPA controller从以下几个方面进行优化:

    • 冷却时间:在1.11版本以及之前的版本,社区引入了horizontal-pod-autoscaler-downscale-stabilization-window和horizontal-pod-autoScaler-upscale-stabilization-window这两个启动参数代表缩容冷却时间和扩容冷却时间,这样保证在冷却时间内,跳过扩缩容。1.14版本之后引入延迟队列,保存一段时间内每一次检测的决策建议,然后根据当前所有有效的决策建议来进行决策,从而保证期望的副本数尽量小的发生变更,保证稳定性。
    • 忍受度:可以看成一个缓冲区,当实例变化范围在忍受范围之内的话,保持原有的实例数不变。

      首先定义ratio = currentMetricValue / desiredMetricValue

      当|ratio – 1.0| <= tolerance时,则会忽略,跳过scale。

      当|ratio – 1.0| > tolerance时, 就会根据之前的公式计算期望值。

      当前社区版本中默认值为0.1。

HPA是基于指标阈值进行伸缩的,常见的指标主要是 CPU、内存,也可以通过自定义指标,例如QPS、连接数等进行伸缩。但是存在一个问题:基于指标的伸缩存在一定的时延,这个时延主要包含:采集时延(分钟级) + 判断时延(分钟级) + 伸缩时延(分钟级)。这个分钟级的时延,可能会导致应用CPU飚高,响应时间变慢。为了解决这个问题,CCE提供了定时策略,对于一些有周期性变化的应用,提前扩容资源,而业务低谷时,定时回收资源。