应用现状
企业应用的流量大小不是每时每刻都一样,有高峰和低谷,如果每时每刻都要保持可承载高峰流量的机器数目,那么成本会很高。通常解决这个问题的办法就是根据流量大小或资源占用率自动调节CCE集群中工作负载及节点的数量,也就是弹性伸缩。
在CCE中,由于使用Pod/容器部署应用,容器可使用的资源是在部署时即配置好,不会无限制使用CCE节点中的资源,所以在CCE中弹性伸缩需要先对Pod数量进行伸缩,Pod数量增加后节点资源使用率才会增加,进而根据节点资源使用率再去伸缩集群中节点的数量。
解决方案
CCE中的弹性伸缩主要使用HPA(Horizontal Pod Autoscaling)和CA(Cluster AutoScaling)两种弹性伸缩策略,HPA负责工作负载弹性伸缩,也就是应用层面的弹性伸缩;CA负责节点弹性伸缩,也就是资源层面的弹性伸缩。
通常情况下,两者需要配合使用,因为HPA需要集群有足够的vCPU和内存等资源才能扩容成功,当集群资源不够时需要CA扩容节点,使得集群有足够资源;而当HPA缩容后集群会有大量空余资源,这时就需要CA对集群节点进行缩容以释放资源,才不至于造成浪费。
如下图所示,HPA根据监控指标进行扩容,当集群资源不够时,新创建的Pod会处于Pending状态,CA会检查所有Pending状态的Pod,根据用户配置的扩缩容策略,选择出一个最合适的节点池,在这个节点池扩容。
CCE同时支持创建CA策略,根据CPU/内存分配率扩容、还可以按照时间定期扩容节点,CA策略可以与autoscaler默认的根据Pod的Pending状态进行扩容配合使用。
使用HPA+CA可以很容易做到弹性伸缩,且节点和Pod的伸缩过程可以非常方便的观察到,使用HPA+CA做弹性伸缩能够满足大部分业务场景需求。
本实践将通过一个示例介绍HPA+CA两种策略配合使用下弹性伸缩的过程,从而帮助您更好的理解和使用CCE中的弹性伸缩。
准备工作
准备一个算力密集型的应用,当用户请求时,需要先计算出结果后才返回给用户结果,如下示例,这是一个PHP页面,代码将保存在index.php文件中,用户请求时先循环开方1000000次,然后再返回“OK!”。
编写Dockerfile制作容器镜像。
FROM php:5-apache
COPY index.php /var/www/html/index.php
RUN chmod a+rx index.php
执行如下命令构建镜像,镜像名称为busy-php。
docker build -t busy-php:latest .
构建完成后上传到目标资源池的SWR镜像仓库,上传容器镜像的步骤请参见“容器镜像服务 > 客户端上传镜像”。
创建有1个工作节点的CCE集群,工作节点规格2U4G,节点需要带弹性公网IP,以便访问公网。
在CCE控制台“插件管理”中,如未安装请首先给集群安装好以下插件:
•autoscaler:CA插件。
•metrics-server:是Kubernetes集群范围资源使用数据的聚合器,能够收集包括了Pod、Node、容器、Service等主要Kubernetes核心资源的度量数据。
创建节点池和CA策略
在CCE控制台中,创建一个节点池,添加一个2U4G的节点,并打开节点池的弹性扩缩容开关,如下图所示。
修改autoscaler插件配置,将自动缩容开关打开,并配置缩容相关参数,例如节点资源使用率小于50%时进行缩容扫描,启动缩容。插件规格建议至少选择“高可用50”,即保证运行不少于2个autoscaler实例。
上面配置的节点池弹性伸缩,会根据Pod的Pending状态进行扩容,根据节点的资源使用率进行缩容。
CCE同时支持创建CA策略,这里的CA策略可以根据CPU/内存分配率扩容、还可以按照时间定期扩容。CA策略可以与autoscaler默认的根据Pod的Pending状态进行扩容共同作用。
如下图所示,在CCE控制台
弹性伸缩 >
节点伸缩中创建一个“节点伸缩策略”,配置当集群CPU分配率大于70%时,增加一个节点。CA策略需要关联节点池,可以关联多个节点池,当需要对节点扩缩容时,在节点池中根据最小浪费规则挑选合适规格的节点扩缩容。
创建工作负载
使用刚构建的busy-php容器镜像创建无状态工作负载,副本数为1。vCPU设置为0.5 core、内存设置为200MiB,limits与requests建议取值保持一致,避免扩缩容过程中出现震荡。
然后再为这个负载创建一个Nodeport类型的Service,以便能从外部访问。
创建HAP策略
创建HPA策略,如下图所示,该策略关联了名为busy-php的工作负载,期望CPU使用率为50%。
另外有两个配置参数,一个是CPU的阈值范围,最低30,最高70,表示CPU使用率在30%到70%之间时,不会扩缩容,防止小幅度波动造成影响。另一个是扩缩容冷却时间窗,表示策略成功触发后,在缩容/扩容冷却时间内,不会再次触发缩容/扩容,以防止短期波动造成影响。
准备压测环境
在本例中使用linux开源压测工具wrk模拟外部压力负载,您也可以使用其它压测工具进行模拟,确保对集群中的工作负载可形成持续的压力即可。
为确保压测效果,建议在节点池外的同一集群工作节点上安装并运行压测工具,本例以在linux工作节点上安装wrk为例:
如未安装git、gcc,首先安装:
yum install git -y
yum install gcc -y
下载wrk工具:
git clone https://github.com/wg/wrk.git
进入wrk目录,编译:
cd wrk && make
完成编译后,可将wrk可执行文件软连接至/usr/local/bin等目录下,方便后续使用。
首先通过如下命令测试工作负载是否正常,正常结果应为返回“OK!”。
curl http://192.168.0.149:31504
其中的{ip:port}为busy-php工作负载的访问地址和端口,可在负载详情页中获取:
验证wrk工具并查看结果是否正常:
wrk -t2 -c10 -d3s http://192.168.0.149:31504/
wrk的详细使用方法和参数说明,请参考官方介绍:https://github.com/wg/wrk。
观察弹性伸缩过程
首先查看CCE集群中刚才新建的节点池情况,初始状态节点池中有1个节点。
说明本实践中的压测、工作负载和节点等相关指标值仅为参考示例。
查看HPA策略,因为之前已进行过连通性测试,可以看到目标负载busy-php的指标(CPU使用率)为16%
通过如下命令开始打压,其中{ip:port}为负载的访问地址,可以在busy-php负载的详情页中查询。
wrk -t10 -c1000 -d1200s http://192.168.0.149:31504/
说明上述压测命令中的并发数、连接数、持续时间仅为示例,请根据节点规格等参数进行合理的设置。
观察工作负载的伸缩过程。
可以看到第二行开始负载的CPU使用率达到99%,超过了目标值,此时触发了工作负载的弹性伸缩,将负载扩容为2个副本/Pod,随后的几分钟内,CPU使用并未下降,这是因为虽然工作负载进行了扩容,但新创建的Pod并不一定创建成功,一般是因为资源不足Pod处于Pending状态,此时需同步进行节点扩容。
如下图所示,工作负载的副本数已通过动态扩容达到8,但因为没有充足的vCPU和内存资源,会被k8s集群标记为“实例调度失败”。
之后工作负载CPU使用率一直保持在99%以上,工作负载持续进行扩容,副本数从2个扩容到4个,再扩容到8个最后扩容至12个。观察负载和HPA策略的详情,从事件中可以看到负载的扩容的过程和策略生效的时间线,如下所示。
与此同时,查看节点池中的节点数量,发现在刚才工作负载扩容的同时,节点数量也扩容了。在CCE控制台中可以看到伸缩历史,节点数量会根据CA及autoscaler策略,通过判断Pod的Pending状态进行扩容。
另外还可以看到CA策略也执行了一次,当集群中CPU分配率大于70%,将节点池中节点数量从2扩容到了3。
本例中节点扩容机制具体是这样:
•Pod数量变为4后,由于没有资源,Pod处于Pending状态,触发了autoscaler默认的扩容策略,将节点数量进行增加。
•同时因为集群中CPU分配率大于70%,触发了CA策略,从而将节点数增加一个,从控制台上伸缩历史可以看出来。根据分配率扩容,可以保证集群一直处于资源充足的状态。
本例中启动压测时设置了压力持续时间,因此当压测工具停止打压后,观察负载Pod数量。CPU负载快速下降,工作负载开始缩容,工作负载副本数也快速由12缩容至2个,最后恢复到1个副本。
观察负载和HPA策略的详情,从事件中可以看到负载的缩容过程和策略生效的时间线,在控制台中同样可以看到HPA策略生效历史。
再继续观察,会看到节点池中的节点数量会被不断缩容。
最终,节点池节点数量将稳定在2。
这里节点没有继续被缩容,是因为节点池中这两个节点都存在namespace为kube-system的Pod(且不是DaemonSets创建的Pod)。关于节点在什么情况下不会被缩容请参考CCE帮助中心
弹性伸缩 > 集群/节点弹性伸缩 > 节点伸缩原理。
如需继续缩容,可编辑节点池,手动减少其节点数量。
总结
通过上述的实践可以看到,使用CCE的HPA+CA机制,可以很容易做到工作负载及节点的弹性伸缩,且节点和Pod的伸缩过程可以非常方便的观察到,使用HPA+CA做弹性伸缩能够满足大部分业务场景需求。