k8s源码学习——autoscaler

autoscaler是k8s的controller中非常重要的一个controller,它提供了微服务的弹性能力,并且和serverless密切相关。弹性伸缩本身是很好理解的一个概念,当微服务负载高(cpu/内存使用率过高)的时候就水平扩容,增加pod的数量降低负载,当负载降低时就减少pod的数量,减少资源的消耗,通过这种方式使得微服务始终稳定在一个理想的状态。理论上,这么一个逻辑单纯的功能实现起来应该并不复杂,然而,由于实际情况的一些限制,autoscaler要处理的场景远比想象中要复杂得多,它要处理以下几个问题:

1)cpu/mem的监控数据是抽样采集的,波动是非常迅速的,而实际容器增减的速度显然跟不上监控数据波动的速度,你的伸缩相对实际负载来说是有滞后性的。

2)扩容的时候,扩容的pod数量超过了集群容量怎么办?而缩容的时候,要不要在没有请求的时候把集群大小缩为0,缩为0就意味着你的服务实际上已经下线了,而这个时候再有请求过来就会请求失败。

3)监控数据并不是稳定可靠的,如果采集到的数据经常有缺失怎么办。如果你的集群机器数量很大的话,某次采集缺失几个pod的数据发生的概率不会低,这种情况还要不要继续伸缩。

4)如果负载存在大范围波动的情况下该怎么办,比如说监控数据一直在某个值附近反复横跳,导致你的集群大小也会反复横跳,但是从更长的时间角度看,所有的波动其实都发生在某个值的附近,这个时候是不是应该优化。

5)一些数值处理该怎么做?比如你规定了80%cpu负载的情况下应该扩容,但是监控数据是78.5%的cpu使用率,这个时候你应不应该扩容?

要找到这些问题的答案,首先来看一下autoscaler的数据结构,看看有哪些属性。在pkg的apis目录下面,我们可以找到types.go这个文件,里面是autoscaler的主要的structs。比如HorizontalPodAutoscalerSpec这个结构体里面,我们发现了MinReplicas和MaxReplicas这两个字段:


code snippet

这两个字段一个规定了autoscale的上限,一个规定了autoscale的下限,说明了伸缩永远是发生在一个有限范围之内,很好地回答了伸缩规模的问题。但是很神奇的是,MaxReplicas使用的是值,而MinReplicas使用的却是指针,这是怎么一回事?从类型上理解,MaxReplicas是一个配置好就不会改变的值,而MinReplicas在运行时会被修改。阅读了注释,我们了解到MinReplicas默认设为1,只有当HPAScaleToZero这个配置设为true的时候,这个值才能被设置为0。这里面又有一个新的问题,为什么要单独设置scale为0的情况,这种情况有什么特殊的吗?是不是因为我们上面所说的集群大小为0了,相当于服务不可用了,这种情况需要单独处理?带着刨根问底的精神,我找到了这个pr https://github.com/kubernetes/kubernetes/pull/74526,里面解释了为什么要支持HPA伸缩到0:


why scale to 0

说得很明白了,支持HPA伸缩到0的目的是支持用户去定义一个metric,让HPA可以根据这个metric去伸缩replica到0来节约资源,主要针对某些批量任务。所以说,这个策略本身和服务可用性没有关系,也不支持serverless式的冷启动,它只实现了scale to zero的功能,但是没有处理请求的能力,要真正实现服务scale to zero还是需要knative提供的KPA和istio组件。

回过头我们来看一下伸缩规则,HPA的伸缩规则有两组,一组针对scale up,一组针对scale down,如下所示:


scaling rules

这里面提到了stabilization window(稳定窗口)这么一个概念,这是怎么一回事?而且注释说扩容默认没有稳定窗口,但是缩容有稳定窗口。TCP协议里面我们碰到过窗口这么个概念,一般来说,窗口是客户端和服务端用来做流控的一种机制,这里面这个窗口是不是也是这种功能。话不多说,直奔相关代码。

Autoscaler的控制逻辑都在pkg/controller/podautoscaler/horizontal.go这个文件里面。阅读代码,我们会发现,autoscaler的控制逻辑还是很清晰的,基本上就是一条直线。主控逻辑是一个1s执行一次的for循环,循环一个队列里面的HPA任务,先获取当前状态,然后计算出如果平衡到理想状态,需要scale_up/scale_down多少pod,然后再执行动作。里面有一个normalizeDesiredReplicasWithBehaviors方法,会对伸缩结果做平衡,它做了以下几个事情:

1)限制伸缩的值在最大最小范围之内。(避免超过资源限制)

2)限制一次伸缩的pod数量和每分钟伸缩的pod数量。(钝化伸缩动作,避免反复横跳)

3)选择5分钟之内的最小推荐值作为伸缩值。

OK,这下我们了解了,autoscaler根据当前metrics计算出一个值并不会直接拿来伸缩,而是作为推荐值和稳定窗口内的所有推荐值比较,取最小值作为伸缩依据,如果这个值一直不变的话,autoscaler不会做任何动作。这样的话,一方面autoscaler对于负载的变动是敏感的(每秒推荐一次),另一方面autoscaler对于变化的反应是迟钝的,你必须要连续5分钟的持续变动才能造成伸缩动作(当然你可以调这个窗口大小),这样提高了整个集群pod数量的稳定性。那么,为什么要取最小值而不是最大值(伸和缩都取最小)呢?因为HPA整个的设计思路就是节约资源,所以能少用点资源就少用点资源,这样整个k8s集群能够容纳的服务才能变多。

最后,还有一个问题,我们还没解决:对于微服务来说,scale到0之后,有新的请求进来了,怎么办?单纯靠HPA并不能解决这个问题,这个时候我们就需要Knative了,Knative解决这个问题的方式是先用proxy拦截掉这部分请求,然后由KPA(Knative的autoscaler)通过activator去激活一个pod,激活之后再把流量放进来,这样保证0pod的时候服务仍然看起来可用,具体代码实现,我们后面学习Knative源码的时候可以再看。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354

推荐阅读更多精彩内容