kubernetes 的出现极大的简化了应用更新和扩容的流程,在部署工作负载波动较大的应用时,我们时常会遇到几个问题:
kubernetes 提供了一些功能来解决这些问题,主要包括 pod 水平扩容(HorizontalPodAutoscaler)、pod 垂直扩容(VerticalPodAutoscaler) 以及集群扩容(ClusterAutoscaler)
HorizontalPodAutoscaler 实现了 pod 的水平伸缩,即副本数的伸缩,可以用于根据某种指标扩容的场景(比如cpu/mem使用率,连接数等等)。 HorizontalPodAutoscaler 的工作原理可以简述为下图:
HorizontalPodAutoscaler 作为一个 controller 运行于 kube-controller-manager 中,周期性的去获取相关 pod 的 metrics 信息(比如cpu/mem使用率,连接数等等),在获取到具体的 metrics 信息之后,HorizontalPodAutoscaler 会根据相关的设置,计算副本数的预期值,如果当前 pod 的数量和副本数不一致,则 HorizontalPodAutoscaler 会对副本数进行调整。
kubernetes 本身并不负责提供具体的 metrics,而是通过 metrics.k8s.io
、custom.metrics.k8s.io
两个 apigroup 暴露集群的 metrics。实际上的 metrics 采集端可以通过配置这三个 apigroup 所对应的后端 service 来提供具体的 metrics 数据。比较典型的方案是使用 prometheus 和 prometheus adapter 对接到 kubernetes 的 metrics api。
HorizontalPodAutoscaler 计算期望副本数的算法如下表达:
desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]
其中 currentMetricValue 代表当前 metrics 的值,比如平均每个 pod 的 cpu 使用量为 0.5 core,desiredMetricValue 代表期望 metrics 的值,比如期望每个 pod 的 cpu 使用量为 0.2 core。当实际使用量大于期望使用量时,HorizontalPodAutoscaler 会增加 pod 的副本数,以期望降低单个 pod 的负载,从而使得单个 pod 的 cpu 使用量降低到 0.2 core,当实际使用量小于期望使用量时,则 HorizontalPodAutoscaler 会减少 pod 的副本数。
HorizontalPodAutoscaler 的扩容频率可以通过指定 kube-controller-manager
的 --horizontal-pod-autoscaler-sync-period
参数实现。
可以看到 HorizontalPodAutoscaler 中采用的副本数计算方法较为简单,其认为当 pod 数量增长一倍时,单个 pod 的负载也会降低一半,实际的业务程序很难满足这个需求,因此在实际使用中需要配合自身对业务程序的预估设置动态扩容规则。
VerticalPodAutoscaler 实现了 pod 的纵向伸缩,即request的伸缩。VerticalPodAutoscaler 通过对某个 pod 过去的实际资源使用进行统计,根据相应的策略调整 pod request。VerticalPodAutoscaler 的工作原理可以简述为下图:
VerticalPodAutoscaler 并不默认内置于 kube-controller-manager 中,而是需要在集群中部署额外的组件。VerticalPodAutoscaler 整体包含三个组件:Admission Controller
、Recommender
和 Updater
。
Recommender
是 VerticalPodAutoscaler 的核心组件,负责计算期望的 request 值。与 HorizontalPodAutoscaler
相似的是,Recommender
也是通过 kubernetes 暴露的 metrics api 获取 pod 的实际资源使用,并根据一系列的策略去计算适用于当前 pod 的 request 值。Recommender
会统计过去一段时间内 pod 的实际资源使用,认为 pod 未来的实际资源使用分布与过去这段时间的分布一致,并以此计算推荐值。例如,对于 CPU 使用量,Recommender
会推荐一个 request 值,使得过去这段时间 pod cpu 的实际使用量超过 0.95 * request 的时间小于 1%,对于 Mem 使用量,Recommender
会推荐一个 request 值,使得在某一段时间之内,pod mem 的实际使用量超过 request 的概率不高于 1%。
Updater
组件负责把 Recommender
作出的 request 推荐值应用到现存的 pod 上。当 pod 当前的 request 与 Recommender
推荐的值相差较大时,Updater
就会通过某种方式触发 pod 更新(当前是通过 evict pod 实现)。
Admission Controller
是实际更新 pod request 的组件。Admission Controller
通过 kubernetes 的 dynamic admission control 机制拦截了所有 pod 创建请求,当 Updater
触发 pod 重建之后,Admission Controller
会根据 Recommender
推荐的值将 pod 的 request 改写为相应的值。
由于当前在 kubernetes 中,修改 pod request 必定会触发 pod 的重新创建,所以在应用 VerticalPodAutoscaler 时,一般配合 deployment 或其他控制器的滚动更新重新创建 pod,否则对业务程序的可用性会有一定影响。
相对于 HorizontalPodAutoscaler/VerticalPodAutoscaler 只是在 pod 层面实现了 request 及副本数的调整,ClusterAutoscaler 实现了集群容量的自动调整。
ClusterAutoscaler 会周期性的检测是否有 Pending 的 pod,当发现有 pod 由于资源问题导致 Pending 时,ClusterAutoscaler 会尝试按照设置的相关伸缩组的节点模板信息,尝试调度 Pending 的 pod,当 ClusterAutoscaler 发现依据某个节点的模板创建此节点之后,pod 即可被调度时,即会触发相应伸缩组的扩容操作。同时,ClusterAutoscaler 提供了 --expander 参数,通过此参数即可指定不同的选择算法,从而影响当存在多个伸缩组模板时,实际去扩容哪一个伸缩组。
ClusterAutoscaler 对 kubernetes 的部署环境有一定要求,需要集群所在环境具有动态 provision node 的能力,因此 ClusterAutoscaler 大多应用于云上托管的 kubernetes 集群,只要实现 ClusterAutoscaler 定义的相关 CloudProvider 接口,即可将 ClusterAutoscaler 应用于对应环境。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。