通过kubectl
执行autoscale
命令kubectl autoscale deployment nginx-deployment --cpu-percent=30 --min=7 --max=8
后,HorizontalController会接收到HorizontalPodAutoscaler
新增消息,最终会执行HorizontalController.reconcileAutoscaler
方法。该方法是控制器的核心逻辑,其执行过程如下:
- 通过
hpa
的属性获取对应资源(可以是Deployment
也可以是其他)的Scale
中的分片数信息; - 进行逻辑判断:
- 若当前分片数为0但最小分片数不为0,则不进行自动扩容;
- 若当前分片数大于
hpa
定义的最大分片数则将目标分片数(desiredReplicas
)设置成最大分片数; - 若当前分片数小于
hpa
定义的最小分片数则将目标分片数设置成该最小分片数; - 都不满足的话则执行第三步跟据
Metrics
信息计算需要部署的分片数
- 执行
HorizontalController.computeReplicasForMetrics
方法计算目标分片数:- 定义
hpa
时可以定义多个指标维度的扩缩容策略,比如cpu
等。因此这里会按每个指标信息依次计算目标分片数,最后取最大值作为最终的目标值; - 对于指标(
MetricSpec
),k8s
对齐进行了分类,主要分为四类,没类的计算方式也不同:- Object: 描述
k8s
对象,如hits-per-second
; - Pods: 描述目标中每个
Pod
信息,如transactions-processed-per-second
,而这些值在比较前会进行求平均; - Resource:是
k8s
中一个知名度量信息,在request
和limit
中进行定义的资源; - External:拓展指标信息,来自于
k8s
集群之外的信息。- 下面以
Resource
为例,来讲解其计算过程(HorizontalController.computeStatusForResourceMetric
):
- 下面以
- 最终调用的是
ReplicaCalculator
分片计算器的GetRawResourceReplicas
方法; - 首先,通过
metricsClient
查询每个Pod
的Metrics
信息; - 进行以下条件判断和计算目标分片数
- 首先计算当前测量的
metric
的平均值和目标值的比例(usageRatio
); - 若没有未就绪的
pod
且当前指标大于目标值时:- 当差值在10%(默认
可容忍值
)之内,则直接返回原值; - 若大于10%时,则返回分片数:
usageRatio
乘以当前Pod
数;
- 当差值在10%(默认
- 如有
Pod
未收集到指标信息- 当
usageRatio
小于0,将未收集到的指标设置零时为目标值
; - 若
usageRatio
大于0,将未收集的指标设置零时为0
;- 当
usageRatio
大于0,将所有未就绪的Pod
指标设置为0
- 对修改过的数据重新计算
usageRatio
; - 当新的
usageRatio<1.1
(0.1是容忍度)或者oldUageRatio<1&&newUsageRatio>1
或者oldUageRatio>1&&newUsageRatio<1
时,直接返回原值; - 否则返回
newUsageRatio
乘以所有pod
数量(也及以newUsageRatio
比例来扩容)
- 当
- 当
- 首先计算当前测量的
- 并不是计算出来就用这个值,还需要对伸缩速率做一次调整(
normalizeDesiredReplicas
):- 根据历史值来调整该值(
stabilizeRecommendation
):HPA
中保存每次计算结果和时间戳,timestampedRecommendation
;HPA
启动时会设置一个窗口期downscaleStabilisationWindow
(默认5min
)- 找到窗口期之内历史计算结果,若历史推荐分片数比当前推荐的大,则覆盖当前的
- 速率限制(
convertDesiredReplicasWithRules
)- 防止扩容过快,限制最大不能超过当前实例数的两倍;
- 获取目标分片数时,若与原值不相等则通过
Scales
接口将分片数修改成目标值(实际,Scales
只是一个包装,其实质是更新Deployment
的Replica
只) - 当
DeploymentController
接收到更新后,就会引发其扩缩容操作
- 获取目标分片数时,若与原值不相等则通过
- 防止扩容过快,限制最大不能超过当前实例数的两倍;
- 根据历史值来调整该值(
- Object: 描述
- 定义
到此,HPA
的单次操作执行流程就介绍完了,下面以一张图来简要描述该过程: