Kubernetes自动伸缩方案

发布于:2024-05-07 ⋅ 阅读:(16) ⋅ 点赞:(0)

楔子

  业务在部署上线后,其承载的流量跟随时间的变化、业务的演进,也一直在变化,随之而来的便是其对资源量需求的波动。在业务高峰期,比如社交软件、视频软件、共享单车的晚高峰期,其对资源的需求量大。而在业务使用的低峰期,比如半夜、凌晨,其对资源的需求量小。另外还存在活动、热点事件、节假日使短时间流量徒增情况,就整体而言,流量事实上是一个动态波动的曲线。对于sre来说,自动扩缩容对业务的质量、成本和效率都有个全方面提升,几乎所有的公司都在它上面花费了大量的精力

服务的横向伸缩 - HPA

  服务的负载升高时,期望快速且丝滑地扩容服务节点数,并且在服务负载回落时,期望安全的缩容服务节点数。对于sre来说,关键在于找到合理的指标来决策操作的发起,最常用且通用的是节点的负载,它能保证业务在大多数场景下能够触发HPA,但是负载触发HPA有两个问题:资源的利用率和伸缩效率。

  负载是一个业务可用性的“间接”指标,它不像请求量、请求成功率一样,能直接反馈业务的状态。因此在实际使用中,通常只是“猜测性”定义一个比较“安全”的负载扩缩容阈值,比如之前在腾讯期间,即使在成本优化期间,很多业务的HPA的阈值也只是在40%-45%之间,实质上资源使用率有很大的优化空间。

  这个问题其实有解决办法,比如很多公司尝试使用接口请求量、请求成功率等自定义指标,来作为HPA的触发指标,比如已在CNCF“毕业”的KEDA,KEDA将自己注册为External Metrics的提供者,以此具备了多种HPA的触发器指标,比如PromQL、SQL、Crond等,但定义自定义指标需要一定的成本;另一个可行的方案是,通过压测来增强对服务承载QPS的感知,以此制定一个合理的负载扩缩容阈值,这也需要一定的时间成本,核心的、比较稳定的业务用的比较多。 image.png   以上的问题,如果HAP的伸缩效率达到秒级,其实都算不上问题。就像目前油价破8、电车配置卷疯了的情况下,油车仍然有市场一样,伸缩效率的限制致使HPA的使用趋向保守。控制器在巡查发现指标达到阈值后,对服务的副本数进行更新,而Kubelet在监听到副本数变更并开启部署后,扩容节点到放量仍需走完启动InitContainer、拉取镜像、创建并启动业务容器、PostStart初始化任务、Readness就绪检测、预热等几个流程,一般情况下整个流程耗时1-2分钟左右,这与业务期望的“无感”扩容有不小的差距。其他步骤相对比较快或可省略,就绪检测事关业务安全,不可能轻易舍弃,因此目前业界对HPA的整体用法还是大部分用负载触发,少部分核心的、性价比高的采用压测或自定义指标触发 image.png

服务的纵向伸缩 - VPA

  与HPA相比,VPA的使用并不广泛,它与HPA原理类似,都是通过触发指标来更新RS的副本数,与HPA功能大部分重合,但HPA具有更好的扩展性,总不能指望每台宿主机都留有大量资源等待VPA,这与提升资源利用率的理念相悖。另一方面,VPA还具有以下缺点:

  1. 与HPA不能同时使用
  2. VPA时需要重建Pod
  3. 推荐值没有上限和下限
  4. 只能修改request,而不能修改limit(可以选择在Pod创建时、更新时、或任意时刻重建Pod)
  5. PA只能通过Metrics Sever触发,不能自定义指标
  6. 因此VPA只在需大量人工维护request的场景比较适用

定时扩缩容 - CrondHPA

  严格上来讲,CrondHPA其实算HPA的一种,与HPA不同的,它是通过定时任务,而不是监控指标来触发扩缩容,它不能像HPA一样,动态调整副本数,而只能设定一个静态的值,因此在计划内流量徒增的场景特别适合,比如定时投放、秒杀、跨日/年等场景。

  但更好的选择是与HPA结合来使用,HPA负责平常时段的动态扩缩容,而CrondHPA负责特殊时刻的扩缩容,两者同时使用时需注意冲突的问题,比如两者目标副本数冲突、CrondHPA的目标副本数超出HPA的上下限,对此业界有两种较好的解决方法:

  1. 将CrondHPA的scaleTargetRef指向HPA资源,因此CrondHPA可以感知到HPA的request和limit,CrondHPA扩缩容通过修改HPA的request和limit来实现,最终副本数取两者较大的
  2. 同一个Service指向两个RS,分别绑定HPA和CrondHPA
scaleTargetRef: 
    apiVersion: autoscaling/v1 
    kind: HorizontalPodAutoscaler 
    name: nginx-deployment-basic-hpa

节点池的伸缩 - Cluster AutoScaler

  设想在业务高峰期,节点池资源不够,业务Pod无法调度怎么办。对于节点池的规模,sre希望它能永远使用率100%,且不能影响Pod的调度。Cluster AutoScaler能解决这个这个问题,AutoScaler的触发指标一般有两个:资源使用率和可分配Pod数量。前者是较通用的做法,但始终会有部分资源的浪费,云厂商一般提供这种方案。而后者高度定制化,能将资源的使用率趋近极限,个人推荐这种方案。

  可分配Pod数量可用Promethues指标kube_node_status_allocatable_cpu_cores获取,我们期望节点池的可分配Pod配置一直保持在某个水位(min和max),并且由于扩容效率限制,扩容时期望根据实际用量扩容多个节点,而缩容时依次逐个缩容节点,并且缩容时需关注节点上多业务Pod的情况,才能保证业务的万无一失

总结

  自动扩缩容对业务的重要性,怎么强调都不为过分,做好它不仅对业务的安全,对sre能力的解放也是个巨大的提升,以上提到的都是浅尝辄止,具备自动扩缩容的能力只是开始,还有更多需sre关注的点,比如伸缩效率、触发指标的准确性等,不断地打磨才能更好的服务于业务