Kubernetes Autoscaler
电商项目流量波峰波谷现象是非常常见的, 在闲时服务器资源利用率可能只有10%左右, 但是活动期间利用率会瞬间飙升导致集群压力变大甚至宕机, 传统的应对方案就是增加集群的硬件资源, 但这也会增加不少费用开销
本篇文章中用几段简单的k8s配置来展示公司的k8s集群是如何应对这种情况的, 在这之前我们需要了解几个k8s的概念
Pod
是k8s中的工作单元, 可以理解为一个Pod就是一个应用实例, 对于同一个项目往往会在集群里部署多个Pod以提高负载性能
Deployment
是控制Pod的一种控制器, 主要作用是保持Pod的数量在预期数量中, 比如以下的配置
重点关注replicas
字段, 配置声明了期望有3个nginx实例在集群中运行, Deployment会尽力满足这个需求
HorizontalPodAutoscaler
简称HPA, 是k8s的一种横向扩容机制, 通常作用在Deployment上
scaleTargetRef
字段指示了HPA要作用在哪个对象上, HPA会监控这个对象的某些指标, 在指标达到某个阈值后k8s会自动扩容或缩容这个对象, metrics
字段指示了需要监控的指标, 上例的配置监控的指标CPU使用率, 阈值是50%, 这里的CPU使用率指的是Deployment配置中的
上例的配置限制了容器最多使用1个核的CPU以及1024Mi(1Gi)的内存, 所以HPA的触发条件是这个Deployment的Pods的CPU平均使用率高于了容器限制的50%
用通俗点的话描述这个HPA, nginx
这个Deployment最少要有3个Pod在运行, 当这三个Pod的CPU平均使用率超过50%, HPA就会对这个Deployment进行扩容, 即是增加Pod数量, 最多增加到6个Pod
当然, 在这几个Pod的CPU平均使用率下降之后, HPA会自动缩容把Pod的数量控制在minReplicas
字段限制的数量
有了HPA问题似乎就解决了, 当流量上升的时候, 原有的Pod的CPU使用率会上升, 上升到50%的时候HPA会自动创建Pod来负载均衡, 整体负载能力就提高了
但当流量无限上升的时候, HPA难免还是会遇到集群资源不够的问题, 按照上面的Deployment配置, 假设每个Pod都能吃满limit
中的配置, 也就是一个Pod会占用1个CPU核心以及1G的内存, 如果集群共有16核和16G内存, 那最大也只能负载16个Pod, 按照最佳实践一般都需要预留20%~30%的硬件资源给k8s的系统组件, 所以这时候难免还是需要购买新的节点供HPA扩容使用, 一个节点从购买到就绪成为k8s的节点需要5分钟时间, 这时间是无法接受的, 因为这五分钟内现有的服务器已经无法承担突发流量了, 系统已经开始崩溃
对于这个问题, k8s社区诞生了一个virtual-kubelet, 具体细节这里不展开, 阿里云在vk的基础上开发了ack-vk-node组件, 把vk运行在阿里云的ECI实例上, 以快速提供k8s工作节点, 使得可以在秒级时间内快速为k8s集群添加节点, 并在不需要的时候快速销毁, 下面将这种节点成为vk-node
在上述的架构上, 阿里云提供了ElasticWorkload
组件
上例是一段ElasticWorkload
配置, sourceTarget
字段指示了工作的对象, 还是上面的Deployment, max
字段指示了最多在k8s工作节点上运行多少个Pod, 注意, 这里的工作节点不包括vk-node
replicas
字段和Deployment的replicas
字段作用一样, 用来指示当前的Deployment的Pod数量
elasticUnit
配置了在vk-node的状态, max
字段指示最多允许在vk-node上运行32个Pod
用通俗的话描述上例配置, 当replicas
数量<=10时, 这10个Pod都会在k8s的工作节点上运行, >10的Pod会在vk-node上运行, 这样就无需购买太多的保有节点了
现在可以通过手动调整ElasticWorkload
的replicas
字段来控制Deployment的Pod数量来触发上述的行为, 但是这样会很不方便, 需要实时的盯着服务器流量来调整replicas
可能你已经发现了, 可以用HPA来控制ElasticWorkload
, 调整一下HPA的配置
将HPA的scaleTargetRef
字段指向ElasticWorkload
对象, 这样HPA控制器在需要扩容的时候就会修改ElasticWorkload
对象的replicas
字段
总结一下整体的配置, nginx
这个Deployment正常情况下会运行HPA的minReplicas
字段配置的数量的Pods, 也就是3个, 当这3个Pods的CPU使用率>=50%的时候, HPA会开始逐步调整ElasticWorkload
的replicas
数量, 注意, 这个调整不是一步到位的, HPA会逐步的调高Pod的数量, 然后再观察平均CPU使用率再决定需不需要继续扩容, ElasticWorkload
会根据自己的replicas
字段调整Deployment的replicas
字段, 使Deployment控制器创建出HPA需要的Pod数量, 当HPA需要把Pod数量调整到>10的时候, ElasticWorkload
会把超过10的Pod调度到vk-node中运行
上面的解决方案已经能很大程度的提升了系统的弹性负载性能, 但还是有以下几点不足
虽然vk-node可以在秒级内就绪, 但还是需要时间, 实测一个Pod从调度到vk-node到可以提供服务, 大概要15s的时间
HPA通过metrics-server获取Pod的资源使用情况, 会有一定的延迟, 也就是Pod的资源使用率已经上升了, 但是HPA要在下一个监控周期才会发现
对于上面两个问题的解决方案是
给HPA喂自定义指标, 比如可以将业务的实时QPS当做指标, 这样HPA能更快速的感知到流量上升趋势
将HPA的阈值调低, 在流量还没有到顶峰的时候就准备好vk-node, 这样就能更从容的面对
k8s为业务提供了无限的可能, 希望有更多的同学可以参与到公司的k8s运维工作中
最后更新于