点击上方👆蓝字关注!
一. 说明
Horizontal Pod Autoscaler(HPA) pod水平自动伸缩,Kubernetes有一个 HPA(Horizontal Pod Autoscaler) 的资源,可以实现基于CPU使用率的Pod自动伸缩的功能。
(1)HPA基于Master Node上的kube-controller-manager服务启动参数horizontal-pod-autoscaler-sync-period定义的时长(默认为30秒),周期性的检测Pod的CPU使用率。
如果需要设置horizontal-pod-autoscaler-sync-period可以在Master Node上的/etc/default/kube-controller-manager中修改。
(2)HPA 与之前的 RC、Deployment 一样,也属于一种 Kubernetes 资源对象。通过追踪分析 RC 控制的所有目标 Pod 的负载变化情况,来确定是否需要针对性地调整目标Pod的副本数,这是HPA的实现原理。
(3)metrics-server 也需要部署到集群中, 它可以通过 resource metrics API 对外提供度量数据。
二. HPA实例
2.1 以cpu的使用率判断pod的扩容和缩容
(1)运行 php-apache 服务器并暴露服务
首先,我们先启动一个 deployment 来运行这个镜像并暴露一个服务
[root@server1 harbor]# docker pull 0layfolk0/hpa-example[root@server1 harbor]# docker tag 0layfolk0/hpa-example:latest reg.westos.org/library/hpa-example:latest[root@server1 harbor]# docker push reg.westos.org/library/hpa-example[root@server1 hpa]# vim php-apache.yaml[root@server1 hpa]# cat php-apache.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: php-apachespec:selector:matchLabels:run: php-apachereplicas: 1template:metadata:labels:run: php-apachespec:containers:- name: php-apacheimage: hpa-exampleports:- containerPort: 80resources: //资源限制limits:cpu: 500mrequests:cpu: 200m // 节点的cpu至少要有0.2cpu---apiVersion: v1kind: Service //服务metadata:name: php-apachelabels:run: php-apachespec:ports:- port: 80selector:run: php-apache
其中需要的镜像hpa-example,已经拉至harbor仓库
(2)运行部署
[kubeadm@server1 hpa]$ vim php-apache.yaml[kubeadm@server1 hpa]$ kubectl apply -f php-apache.yamldeployment.apps/php-apache createdservice/php-apache created
查看状态,可以看出该部署文件创建了一个由deployment控制器维护的pod,以及一个service
[kubeadm@server1 hpa]$ kubectl get all // 创建了php-apache的pod、service、deployment、replicasetNAME READY STATUS RESTARTS AGEpod/nfs-client-provisioner-55d87b5996-8clxq 1/1 Running 3 7dpod/php-apache-dfb6d784b-cqvbw 0/1 ContainerCreating 0 45sNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEservice/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 23dservice/php-apache ClusterIP 10.98.233.77 <none> 80/TCP 45sNAME READY UP-TO-DATE AVAILABLE AGEdeployment.apps/nfs-client-provisioner 1/1 1 1 7ddeployment.apps/php-apache 0/1 1 0 46sNAME DESIRED CURRENT READY AGEreplicaset.apps/nfs-client-provisioner-55d87b5996 1 1 1 7dreplicaset.apps/php-apache-dfb6d784b 1 1 0 46s[kubeadm@server1 hpa]$ kubectl describe svc php-apacheName: php-apacheNamespace: defaultLabels: run=php-apacheAnnotations: Selector: run=php-apacheType: ClusterIPIP: 10.98.233.77Port: <unset> 80/TCPTargetPort: 80/TCPEndpoints: 10.244.2.128:80 // 只有一个pod的ipSession Affinity: NoneEvents: <none>
2.2 创建 Horizontal Pod Autoscaler
现在,php-apache服务器已经运行,我们将通过 kubectl autoscale 命令创建 Horizontal Pod Autoscaler。以下命令将创建一个 Horizontal Pod Autoscaler 用于控制我们上一步骤中创建的 deployment,使 Pod 的副本数量在维持在1到10之间。大致来说,HPA 将通过增加或者减少 Pod 副本的数量(通过 Deployment )以保持所有 Pod 的平均CPU利用率在50%以内 (由于每个 Pod 通过 yaml文件 申请了200 milli-cores CPU,所以50%的 CPU 利用率意味着平均 CPU 利用率为100 milli-cores)。
[kubeadm@server1 hpa]$ kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10 # 当cpu的使用率达到50%,开始扩容horizontalpodautoscaler.autoscaling/php-apache autoscaled
我们可以通过以下命令查看 autoscaler 的状态:
[kubeadm@server1 hpa]$ kubectl get hpaNAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGEphp-apache Deployment/php-apache <unknown>/50% 1 10 0 8s[kubeadm@server1 hpa]$ kubectl top podNAME CPU(cores) MEMORY(bytes)nfs-client-provisioner-55d87b5996-8clxq 2m 7Miphp-apache-dfb6d784b-cqvbw 1m 9Mi[root@server1 hpa]# kubectl get hpa //当前时一个副本(REPLICAS)NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGEphp-apache Deployment/php-apache 0%/50% 1 10 1 19s
请注意在上面的命令输出中,当前的CPU利用率是0%,这是由于我们尚未发送任何请求到服务器 (CURRENT 列显示了相应 deployment 所控制的所有 Pod 的平均 CPU 利用率)。
增加负载
现在,我们将看到 autoscaler 如何对增加负载作出反应。我们将启动一个容器,并通过一个循环向 php-apache 服务器发送无限的查询请求:
[kubeadm@server1 hpa]$ kubectl get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22dphp-apache ClusterIP 10.109.183.127 <none> 80/TCP 6m22s//不断的访问php-apache的service让其占用cpu资源,当cpu资源使用超过50%时,创建副本(pod)[kubeadm@server1 hpa]$ kubectl run test --image=reg.westos.org/k8s/busyboxplus -it --rm --restart=NeverIf you don't see a command prompt, try pressing enter./ # while true; do wget -q -O- http://10.109.183.127; done
在几分钟时间内,通过以下命令,我们可以看到CPU负载升高了
[kubeadm@server1 ~]$ kubectl get hpaNAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGEphp-apache Deployment/php-apache 250%/50% 1 10 1 6m22s
这时,由于请求增多,CPU利用率已经升至250%。可以看到,deployment 的副本数量已经增长到了5
[kubeadm@server1 ~]$ kubectl get hpaNAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGEphp-apache Deployment/php-apache 250%/50% 1 10 5 6m57s
查看pod的资源使用情况
[kubeadm@server1 ~]$ kubectl get podNAME READY STATUS RESTARTS AGEnfs-client-provisioner-55d87b5996-8clxq 1/1 Running 3 7dphp-apache-dfb6d784b-52xmw 1/1 Running 0 2m20sphp-apache-dfb6d784b-cqvbw 1/1 Running 0 23mphp-apache-dfb6d784b-lsgtl 1/1 Running 0 2m20sphp-apache-dfb6d784b-r6gdc 1/1 Running 0 2m20sphp-apache-dfb6d784b-xzsf2 1/1 Running 0 2m5s
停止负载
我们将通过停止负载来结束我们的示例。
在我们创建 busyboxplus容器的终端中,输入<Ctrl> + C来终止负载的产生。
然后我们可以再次查看负载状态(等待几分钟时间):
[kubeadm@server1 ~]$ kubectl get hpaNAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGEphp-apache Deployment/php-apache 0%/50% 1 10 1 9m42s
这时,CPU利用率已经降到0,所以 HPA 将自动缩减副本数量至1
注意:自动伸缩完成副本数量的改变可能需要几分钟的时间。
三. HPA的伸缩过程
HPA伸缩过程:
收集HPA控制下所有Pod最近的cpu使用情况(CPU utilization)
对比在扩容条件里记录的cpu限额(CPUUtilization)----50%
调整实例数(必须要满足不超过最大/最小实例数)
每隔30s做一次自动扩容的判断
CPU utilization的计算方法:是用cpu usage(最近一分钟的平均值,通过metrics可以直接获取到)除以cpu request(这里cpu request就是我们在创建容器时制定的cpu使用核心数—200m)得到一个平均值,这个平均值可以理解为:平均每个Pod CPU核心的使用占比。
HPA进行伸缩算法:
计算公式:
TargetNumOfPods = ceil(sum(CurrentPodsCPUUtilization) / Target)—501/200/0.5=5.01
ceil()表示取大于或等于某数的最近一个整数
(1)为了保持集群的稳定,每次扩容后冷却3分钟才能再次进行扩容,而缩容则要等5分钟后。
(2)当前Pod Cpu使用率与目标使用率接近时,不会触发扩容或缩容:
(3)触发条件:avg(CurrentPodsConsumption) / Target >1.1 或 <0.9
使用kubeclt top pod 查看当前的cpu使用情况,将php-apache拉出的pod的cpu(cores)使用数相加,除以当前的pod数,除以cpu request,除以cpu使用率50%,如果 > 1.1 进行扩容,若果 < 0.9 进行缩容。例如:119+124+125+119/4/200/0.5=1.2,所以进行扩容。
//结束php-apache的service访问后,等待5分钟会自动缩容[kubeadm@server1 ~]$ kubectl get hpaNAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGEphp-apache Deployment/php-apache 0%/50% 1 10 1 32m[kubeadm@server1 ~]$ kubectl top podNAME CPU(cores) MEMORY(bytes)nfs-client-provisioner-55d87b5996-8clxq 2m 7Miphp-apache-dfb6d784b-lsgtl 1m 12Mitest 0m 2Mi
使用多个指标作为伸缩的条件
利用autoscaling/v2beta2API版本,您可以在自动伸缩 php-apache 这个 Deployment 时引入其他度量指标
[kubeadm@server1 ~]$ kubectl api-versionsautoscaling/v1 // 使用一个指标autoscaling/v2beta1 // 使用多个指标作为伸缩的条件autoscaling/v2beta2[root@server1 hpa]# vim hpav2.yaml[root@server1 hpa]# cat hpav2.yamlapiVersion: autoscaling/v2beta2kind: HorizontalPodAutoscaler //hpametadata:name: php-apachespec:maxReplicas: 10minReplicas: 1scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: php-apachemetrics:- type: Resource //资源resource:name: cpu //cputarget:averageUtilization: 60 // 限制cpu的使用率60%type: Utilization- type: Resource //资源resource:name: memory //内存target:averageValue: 50Mi //内存使用量时50Mitype: AverageValue[root@server1 hpa]# kubectl apply -f hpav2.yamlWarning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl applyhorizontalpodautoscaler.autoscaling/php-apache configured[root@server1 hpa]# kubectl get hpaNAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGEphp-apache Deployment/php-apache 13824512/50Mi, 0%/60% 1 10 8 26m
可以看出已经有了cpu和内存的双重指标,内存单位是字节。
👇👇👇点击关注,更多内容持续更新...





