[Kubernetes] V2beta2版本HPA分析
文章目录
HPA全称是Horizontal Pod Autoscaler
,是k8s集群对负载的弹性扩缩容机制,这里将介绍一下基于1.18版本的HPA过程。
|
|
在kube-controller-manager初始化了HPAController,这里主要分为两个类型的Client,RESTClient
主要是基于custom metrics的client,LegacyClient则是基于Heapster metrics。
RESTClient初始化包括了resourceclient, custommetrics client, external metrics client三种类型。
|
|
事件处理
每次有HPA事件触发(Add,Update,Delete)都会将对应的hpa添加到对应的队列,然后触发a.reconcileKey
执行扩缩容。如果事件不是删除则会在处理完时间之后在resync时间延迟将key重新加入队列。
reconcileAutoscaler
完成hpa key操作。
- 将v1版本的autoscale转换成v2版本;
- 通过
schema.ParseGroupVersion(hpa.Spec.ScaleTargetRef.APIVersion)
解析需要扩缩容目标的GroupVersion; - 根据Group和Kind获取对应的resource mapping,然后由scale根据mapping获取集群中存在的资源,如果没有找到则会返回错误;
- 设置Condition为
AbleToScale
,将该hpa的key添加到hpacontroller的recommendation
; - 如果设置了minReplicas,则配置用户的minReplicas,否则将最小副本数设置为1;
- 如果当前副本数为0,则不进行扩缩容;当前副本大于最大副本数,则将期望副本数设置为最大副本数;当前副本小于最小副本数,则将期望副本数设置为最小副本数;否则将根据Metrics计算期望副本数;
computeReplicasForMetrics
计算期望副本数,根据每个Metrics的配置进行计算,并且会将最大的副本数设置为期望副本数;computeReplicasForMetric
计算每个Metrics的期望副本数,这里会根据不同的Metrics Type分别进行计算副本数,Type会分为Object
,Pods
,Resource
,External
,后面会进行分析;
- 根据是否需要recale进行副本数的扩缩容;
Metrics Type
metrics的类型在v2版本中可分为四种,分别是:Object
, Pods
, Resource
, External
。HPA在计算metric对应的副本时会按照对应的类型分别进行计算。
- Object
在类型为Object
的时候会根据Value的类型再进行分类,可分为Value
,AverageValue
两种类型进行计算,
|
|
- Pods
Pods类型只支持AverageValue
类型
|
|
- Resource
Resource类型则支持AverageValue
和AverageUtilization
两种。根据用户的定义获取对应的metric,
|
|
- External
external类型也支持两种类型AverageValue
和Value
。
|
|
以上四种类型的Metrics type,和Target type之间的对应关系可以总结为下表格。
MetricsType | AverageUtilization | AverageValue | Value | 场景 |
---|---|---|---|---|
Object | No | Yes | Yes | 监控指标不是由Pod本身提供,而是由k8s集群中的其他资源提供Metrics查询,比如ingress等 |
Pods | No | Yes | No | CPU,memory之外的有Pod提供的自定义metrics,如用户自定义metrics |
Resource | Yes | Yes | No | K8s的pod的所有系统资源(包括CPU,Memory等),一般只会用于CPU,Memory和语言类相关(GC) |
External | NO | Yes | Yes | 来源和K8s无关的外部监控指标 |
根据以上四种类型的Metrics Type这里针对Resource类型进行分析。在v2版本中用户可以填写多个不同的Metrics,HPA会针对每个Metrics都进行计算,然后选取副本数最大的那个进行扩缩容。
|
|
在获取resource的类型时会分为AverageValue
和AverageUtilization
两种。先看AverageValue类型,在GetRawResourceReplicas
通过GetResourceMetric获取每个pod的所有container的对应资源的资源使用总和。然后通过calcPlainMetricReplicas
计算需要副本数,包括以下工作。
- 根据selector获取所有符合条件的Pod;
- 根据pod进行分类,如果pod处于删除或者Failed状态,则忽略;如果是Pending则加入
ignored
;如果pod在上面查找的Metrics结果中没有,则加入missing
;如果资源类型是CPU,还会根据pod的状态和配置的启动延迟检查和延迟初始readiness来判断pod是否加入ingored
; - 将ignoredPods从Metrics结果中移除;
- 通过GetMetricUtilizationRatio获取当前资源利用率以及当前资源利用率和目标资源利用率的比值。通过将所有的pod资源使用量相加/metrics pod数量,然后用这个值除以目标利用率得到比率Ratio;
- rebalanceIgnored=处于pending状态的pod或者因为延迟检查的pod数量大于0 && 需要扩容;
- 如果没有ignore和missingPod,
- 如果Ratio-1的绝对值小于等于设定的tolerace,则返回当前副本数;
- 如果大于tolerace,则返回Ratio*当前ReadyPod数量,还需要返回当前利用率;
- 如果missing大于0;
- Ratio < 1,此时需要缩容,将missingpod的Metrics看做是100%的资源使用,即value等于targetUtilization;
- Ratio >= 1,此时需要扩容,则将missingPod的Metrics看做0%的资源使用,即value等于0;
- 如果需要扩容,并且ignoredpod>0,则将ignorepod的Metrics设置为0,
- 根据上面设置的Metrics重新计算Ratio,然后计算最终副本数; 每个MetricsType都会计算一次,最终取最大值。
behavior
上面计算之后的结果需要根据用户是否定义behavior来决定最后的操作。如果没有设定behavior,则由normalizeDesiredReplicas
来判定最终的副本数,如果设置了behavior,则根据behavior具体计算副本数。
|
|
- 如果设定了behavior并downStabilizationWindow没有设定则会会将HPA的downscaleStabilisationWindow设置成缩容窗口;
- 通过
stabilizeRecommendationWithBehaviors
计算副本数;- 根据扩容还是缩容配置delaySeconds和betterRecommendation;
- 从recommendataions获取这个hpa的最近更改情况,如果在扩缩容周期内有调整则会返回当前的副本数,如果周期内没有修改则返回真实的需要的副本数;
- 将本次修改添加到recommedataions;
Scale
根据Metrics计算出来的副本数和当前副本数不一样则进行扩缩容操作,并更新condition和status。
|
|
总结
到此HPA的功能流程已经分析完了,其中还有一些细节可以深究,可以后续再进行分析。 v1.18以后的的HPA相比之前已经有了很大的灵活性,可以的单独控制一段时间内的扩缩容策略以此来保证服务的稳定性,但是目前还并非是GA版本,还有功能不完善,比如当前的reconcile只是单线程处理queue中的事件,如果涉及到的对象比较多的时候还是会有一些问题。目前也有一些开源项目在现有HPA的基础上进行了的扩展,比如开源项目KEDA,后面将会针对开源的keda进行分析。
文章作者 zForrest
上次更新 2021-03-10 16:37