前言
容器技术的发展让软件交付和运维变得更加标准化、轻量化、自动化。这使得动态调整负载的容量变成一件非常简单的事情。在kubernetes中,通常只需要修改对应的replicas数目即可完成。当负载的容量调整变得如此简单后,我们再回过头来看下应用的资源画像。对于大部分互联网的在线应用而言,负载的峰谷分布是存在一定规律的。例如下图是一个典型web应用的负载曲线。从每天早上8点开始,负载开始飙高,在中午12点到14点之间,负载会回落;14点到18点会迎来第二个高峰;在18点之后负载会逐渐回落到最低点。
资源的波峰和波谷之间相差3~4倍左右的容量,低负载的时间会维持8个小时左右。如果使用纯静态的容量规划方式进行应用管理与部署,我们可以计算得出资源浪费比为25% (计算方式:1 - (1x8+4x16)/4x24 = 0.25 )。而当波峰和波谷之间的差别到达10倍的时候,资源浪费比就会飙升至57%(计算方式:1 - (1x8+10x16)/10x24 = 0.57 )。
那么当我们面对这么多的资源浪费时,是否可以通过弹性的方式来解决呢?标准的HPA是基于指标阈值进行伸缩的,常见的指标主要是CPU、内存,当然也可以通过自定义指标例如QPS、连接数等进行伸缩。但是这里存在一个问题,因为基于资源的伸缩存在一定的时延,这个时延主要包含:采集时延(分钟级) + 判断时延(分钟级) + 伸缩时延(分钟级)。而对于上图中,我们可以发现负载的峰值毛刺还是非常尖锐的,这有可能会由于HPA分钟级别的伸缩时延造成负载数目无法及时变化,短时间内应用的整体负载飙高,响应时间变慢。特别是对于一些游戏业务而言,由于负载过高带来的业务抖动会造成玩家非常差的体验。
为了解决这个场景,阿里云容器服务提供了kube-cronhpa-controller
,专门应对资源画像存在周期性的场景。开发者可以根据资源画像的周期性规律,定义time schedule,提前扩容好资源,而在波谷到来后定时回收资源。底层再结合cluster-autoscaler
的节点伸缩能力,提供资源成本的节约。
使用方式
cronhpa
是基于CRD的方式开发的controller,使用cronhpa
的方式非常简单,整体的使用习惯也尽可能的和HPA保持一致。代码仓库地址
1. 安装CRD
2. 安装RBAC授权
3. 部署kubernetes-cronhpa-controller
4. 验证kubernetes-cronhpa-controller
安装状态
运行一个cronhpa的demo
安装了kubernetes-cronhpa-controller
后,我们可以通过一个简单的demo进行功能的验证。在部署前,我们先看下一个标准的cronhpa的定义。
其中scaleTargetRef
字段负责描述伸缩的对象,jobs
中定义了扩展的crontab
定时任务。在这个例子中,设定的是每分钟的第0秒扩容到3个Pod,每分钟的第30s缩容到1个Pod。如果执行正常,我们可以在30s内看到负载数目的两次变化。
1. 部署demo应用与cronhpa的配置
2. 检查demo应用副本数目
3. 查看cronhpa的状态 ,确认cronhpa的job已提交
4. 等待一段时间,查看cronhpa的运行状态。
此时可以在event中发现负载的定时伸缩已经生效。
最后
kubernetes-cronhpa-controller
可以很好的解决拥有周期性资源画像的负载弹性,结合底层的cluster-autoscaler
可以降低大量的资源成本。目前kubernetes-cronhpa-controller
已经正式开源,更详细的用法与文档请查阅代码仓库的文档,欢迎开发者提交issue与pr。
本文作者:莫源
本文为云栖社区原创内容,未经允许不得转载。