一、什么是HPA?
HPA(Horizontal Pod Autoscaler,水平Pod自动伸缩器)可根据观察到的CPU、内存使用率或自定义度量标准来自动扩展或缩容Pod的数量。HPA不适用于无法缩放的对象,比如DaemonSet
HPA控制器会定期调整RC或Deployment的副本数,以使观察到的平均CPU利用率与用户指定的目标相匹配
HPA需要metrics-server(项目地址:https://github.com/kubernetes-incubator/metrics-server)获取度量指标,由于在高可用集群安装中已经安装了metrics-server,所以本节的实践部分无须再次安装
二、HPA原理
2.1、为什么要使用HPA
在生产环境中,总会有一些意想不到的事情发生,比如公司网站流量突然升高,此时之前创建的Pod已不足以撑住所有的访问,而运维人员也不可能24小时守着业务服务,这时就可以通过配置HPA,实现负载过高的情况下自动扩容Pod副本数以分摊高并发的流量,当流量恢复正常后,HPA会自动缩减Pod的数量
2.2、HPA中一些细节的处理
噪声处理:
通过上面的公式可以发现,Target的数目很大程度上会影响最终的结果,而在Kubernetes中,无论是变更或者升级,都更倾向于使用Recreate而不是Restart的方式进行处理。这就导致了在Deployment的生命周期中,可能会出现某一个时间,Target会由于计算了Starting或者Stopping的的Pod而变得很大。这就会给HPA的计算带来非常大的噪声,在HPA Controller的计算中,如果发现当前的对象存在Starting或者Stopping的Pod会直接跳过当前的计算周期,等待状态都变为Running再进行计算。
冷却周期:
在弹性伸缩中,冷却周期是不能逃避的一个话题,很多时候我们期望快速弹出与快速回收,而另一方面,我们又不希望集群震荡,所以一个弹性伸缩活动冷却周期的具体数值是多少,一直被开发者所挑战。在HPA中,默认的扩容冷却周期是3分钟,缩容冷却周期是5分钟。
边界值计算:
我们回到刚才的计算公式,第一次我们算出需要弹出的容器数目是5,此时扩容后整体的负载是42%,但是我们似乎忽略了一个问题,一个全新的Pod启动会不会自己就占用了部分资源?此外,8%的缓冲区是否就能够缓解整体的负载情况,要知道当一次弹性扩容完成后,下一次扩容要最少等待3分钟才可以继续扩容。为了解决这些问题,HPA引入了边界值△,目前在计算边界条件时,会自动加入10%的缓冲,这也是为什么在刚才的例子中最终的计算结果为6的原因
2.3、原理
通过集群内的资源监控系统(metrics-server),来获取集群中资源的使用状态。
根据CPU、内存、以及用户自定义的资源指标数据的使用量或连接数为参考依据,来制定一个临界点,一旦超出这个点,HPA就会自动创建出pod副本
HPA通过定期(定期轮询的时间通过–horizontal-pod-autoscaler-sync-period选项来设置,默认的时间为30秒)通过Status.PodSelector来查询pods的状态,获得pod的CPU使用率。然后,通过现有pods的CPU使用率的平均值(计算方式是最近的pod使用量(最近一分钟的平均值,从metrics-serve中获得)
除以设定的每个Pod的CPU使用率限额)跟目标使用率进行比较,并且在扩容时,还要遵循预先设定的副本数限制:MinReplicas <= Replicas <= MaxReplicas。
计算扩容后Pod的个数:sum(最近一分钟内某个Pod的CPU使用率/量的平均值)/CPU使用上限的整数+1
流程
1、创建HPA资源,设定目标CPU使用率限额,以及最大、最小实例数
2、收集一组中(PodSelector)每个Pod最近一分钟内的CPU使用率,并计算平均值
3、读取HPA中设定的CPU使用限额
4、计算:平均值之和/限额,求出目标调整的实例个数
5、目标调整的实例数不能超过1中设定的最大、最小实例数,如果没有超过,则扩容;超过,则扩容至最大的实例个数
6、回到2,不断循环
三、实现一个Web服务器的自动伸缩特性
使HPA生效前提:
必须定义 requests参数,必须安装metrics-server
# 1、运行hpa资源,名称为php-apache,并设置请求CPU的资源为200m并暴露一个80端口
[root@k8s-master01 ~]# kubectl run php-apache --image=mirrorgooglecontainers/hpa-example --requests=cpu=200m --expose --port=80
service/php-apache created
pod/php-apache created
# 2、当hpa资源的deployment资源对象的CPU使用率达到20%时,就进行扩容,最多可以扩容到5个
[root@k8s-master01 ~]# kubectl autoscale deployment php-apache --cpu-percent=20 --min=1 --max=5
# 3、确定当前的pod正常运行
[root@master ~]# kubectl get pod | grep php-apa
php-apache-867f97c8cb-9mpd6 1/1 Running 0 44m
模拟消耗php-apache的资源,并验证pod是否会自动扩容与缩容
# 新开启多个终端(也可使用node节点),对php-apache的pod进行死循环请求,如下(如果你的系统资源比较充足,可以选择开启多个终端,对pod进行死循环请求
while true; do wget -q -O- 10.97.45.108; done
# 然后查看数量
[root@master ~]# kubectl get pod
# 当停止死循环请求后,也并不会立即减少pod数量,会等一段时间后减少pod数量,防止流量再次激增。
# 至此,HPA实现pod副本数量的自动扩容与缩容就实现了。