动手实操,让你的 Kubernetes 集群弹起来!
目录
什么是集群自动弹性伸缩?
集群自动弹性伸缩(cluster-autoscaler) 是一个可以自动扩缩 Kubernetes 集群规模的工具,独立于 Kubernetes 主代码仓库以外,与 VPA、Addon-Resizer 等组件共同维护在 kubernetes/autoscaler 仓库,并且各云厂商贡献了对标准扩展接口(CloudProvider)的实现。
为什么需要集群自动弹性伸缩?
cluster-autosclaer 属于弹性伸缩的重要一部分,只要谈到弹性伸缩,一般都会首先想到两个关键词:成本、效率。
cluster-autoscaler 根据用户配置的策略,自动的调整集群的规模,优势主要体现在:
资源动态调整:在业务高峰期时可以结合对工作负载的弹性扩容来调整扩大集群规模,承载更大的计算量。业务低峰期,动态的对工作负载分布进行调整,对节点进行排水、回收,以此降低计算资源成本。
屏蔽底层资源:可以让开发者专注于业务开发,屏蔽对底层资源的感知,降低运维人员的运维难度以及运维成本。
集群自动弹性伸缩的原理是什么?
cluster-autoscaler 声明了 CloudProvider
接口,通过抽象的 NodeGroup
概念来对接各云厂商的弹性伸缩服务(比如阿里云的 ess
,华为云的 as
等)。
提示:
CloudProvider Interface: https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/cloud_provider.go#L89
按照用户指定的策略定期的去检查集群中 Pending
状态的 Pod 以及 Node 的资源水位,来执行 Scale 操作,其中主要是 Scale Up 以及 Scale Down 操作,分别对应节点的弹出以及销毁。
Scale Up
ScaleUp 的逻辑流程如下:
cluster-autoscaler 会对由于资源不足导致
Pending
状态的 Pod 进行监听。获取配置的多个弹性伸缩组,当存在上述
Pending
的 Pod 时,会根据需要的资源、Pod 调度需要的条件(Label,Taint,GPU 等)在伸缩组中进行匹配筛选。如果可以满足调度的条件,会根据计算结果驱动对应伸缩组创建节点。
我们来画一下流程会更直观一点
上面我们有提到,Scale Up 的逻辑是从多个弹性伸缩组中去判断筛选,去弹出新的节点。
这里就会涉及到弹性伸缩组的选择策略,去选择合适的 NodeGroup
,官方声明了如下 6 种策略,通过 expander
参数可以指定,不同云厂商对于策略的支持有限的,并不是支持所有策略:
random:随机选择
most-pods:选择可以容纳最多当前 Pods 的伸缩组,会与 Pending Pod 亲和性等相关
least-waste:选择一个资源浪费最少的节点池进行扩容
price:选择性价比最高的伸缩组
priority:优先级策略,可以在
kube-system
下的cluster-autoscaler-priority-expander
configmap 配置,按照配置伸缩组的优先级进行选择,可以参考 prioritygrpc:通过 GRPC 调用外部的选择服务来选择伸缩组,相当于自定义扩展
Scale Down
对于节点回收这种比较敏感且可能造成数据丢失的功能,并不是强制开启的,cluster-autoscaler 的参数中可以通过 scale-down-enabled
来控制。
Scale Down 的流程如下:
当 cluster-autoscaler 监听到 Node 的利用率低于设置的阈值时(
scale-down-utilization-threshold
参数)会触发判断尝试判断是否可以将此 Node 上的 Pod 彻底驱逐到其他的节点,有些特殊的 Pod 不在判断范围内(比如
skip-nodes-with-system-pods
参数可以控制是否跳过 kube-system 等 Pod)判断完成后,将先驱逐节点上的 Pod 到其他节点,再移除节点
同样的,我们来画一下流程图会更清晰一些
实践环节
百说不如一练,接下来我们动手实践一下,实践环节将基于 ACK 的自动伸缩能力来进行,并结合 HPA 来使用 ClusterAutoscaler。
前期准备
准备阶段,我们需要准备如下内容:
ACK 集群,创建请参考 通过控制台快速使用ACK
Keda(基于 Kubernetes 事件驱动的伸缩器), 安装请参考 Deploy With Helm
提示:
本次演示应用发布以及 HPA 在 Erda 平台上操作,相关操作可以直接替换为其他 PaaS 平台的弹性伸缩或原生 kubectl 操作。
集群自动弹性伸缩配置
首先我们来到 容器服务控制台,在集群更多
中选择 自动伸缩
。
进入后我们需要配置如下参数:
缩容阈值:节点上 Request 的资源与总资源量的比值,低于阈值触发集群缩容
缩容触发时延:节点缩容时需要连续满足触发时延所设定的时间才可进行缩容
静默时间: 扩容出的节点,在静默时间过后,方可进入缩容判断
弹性灵敏度: 判断伸缩的间隔时间
节点池扩容顺序策略: 这里我们选择
least-waste
提示:
更详细的参数解释,请参考配置自动伸缩
节点池配置
创建完成后,可以看到伸缩状态为 待激活
,接下来我们创建节点池
点击 创建节点池
,如下几个配置需要我们着重注意
填写基本信息,这里容器运行时我们选择
containerd
,建议容器运行时保持与当前集群一致,可以通过如下命令查看
配置自动伸缩实例的规格,会从第一个规格开始按顺序尝试购买
配置节点池的数量上下限以及节点标签,这里因为我们服务是发在 Erda 平台上的,并且是期望生产环境、无状态服务的弹性伸缩,所以需要如下标签。
提示:
需要根据当前集群应用交付的实际场景去配置合适的标签
实例自定义数据,弹出的节点在一些场景下我们需要进行数据的初始化,需要用到该选项,采用标准的 cloud-init 方式执行 shell。
这里我们执行如下脚本,修改 containerd
的镜像仓库配置以及将宿主机 DNS 指向 CoreDNS
节点池配置完成后,等待初始化完成。从集群中我们可以看到 cluster-autoscaler 组件已经创建出来,并且集群弹性伸缩状态变为 已激活
结果验证
首先我们在 Erda 平台上发布一个服务
接下来我们配置弹性伸缩策略,当 CPU 平均使用率在 80% 以上,触发扩容
我们可以直接查看该 Deployment
Erda 创建的 Keda ScaledObject,大家可以按照 keda 官方的配置去作用在自己的 Deployment 上,详细参考 ScaledObject spec
配置完成后,我们进入服务的 控制台
, 输入如下命令,提高服务 CPU 的平均使用率
等待片刻后,可以看到触发了 Keda 的事件,实例扩容为 2 个
从 ACK 节点池中,我们可以看到出现了伸缩活动,弹出了一台 ECS
从 Erda 中我们可以看到,新的实例已经运行在了集群弹出的新节点上
验证完成集群节点扩容,接下来我们降低 CPU 的平均使用率,触发 HPA 缩容,我们进入服务 控制台
执行如下命令,停止 CPU 占用,降低平均使用率
稍等片刻后,从集群事件中可以看到,所有指标已经低于目标值,触发实例恢复,恢复到扩容之前的 1 个实例
此时我们登陆 ACK 控制台,在节点池伸缩活动中可以看到,触发了节点的缩容,ECS 被删除回收
到这里我们的验证就完成了,以上就是经典的 HPA 结合 ClusterAutoscaler 的应用场景。
相关链接:
评论