kubernetes(k8s):基于metrics server的HPA(pod水平自动弹性伸缩)

文章目录

  • 1. Horizontal Pod Autoscaler(HPA) pod水平自动伸缩
  • 2. HPA实例
    • 2.1 以cpu的使用率判断pod的扩容和缩容
    • 2.2创建 Horizontal Pod Autoscaler
  • 3. HPA的伸缩过程
  • 4. 引入其他度量指标(cpu+内存)

1. Horizontal Pod Autoscaler(HPA) pod水平自动伸缩

官网:https://kubernetes.io/zh/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/

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 对外提供度量数据。

2. 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.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: php-apache
spec:
  selector:
    matchLabels:
      run: php-apache
  replicas: 1
  template:
    metadata:
      labels:
        run: php-apache
    spec:
      containers:
      - name: php-apache
        image: hpa-example
        ports:
        - containerPort: 80
        resources:              //资源限制
          limits:
            cpu: 500m
          requests:
            cpu: 200m      // 节点的cpu至少要有0.2cpu

---

apiVersion: v1
kind: Service           //服务
metadata:
  name: php-apache
  labels:
    run: php-apache
spec:
  ports:
  - port: 80
  selector:
    run: php-apache

其中需要的镜像hpa-example,已经拉至harbor仓库

(2)运行部署

[kubeadm@server1 hpa]$ vim php-apache.yaml
[kubeadm@server1 hpa]$ kubectl apply -f php-apache.yaml 
deployment.apps/php-apache created
service/php-apache created
[kubeadm@server1 hpa]$

查看状态,可以看出该部署文件创建了一个由deployment控制器维护的pod,以及一个service

[kubeadm@server1 hpa]$ kubectl get all  // 创建了php-apache的pod、service、deployment、replicaset
NAME                                          READY   STATUS              RESTARTS   AGE
pod/nfs-client-provisioner-55d87b5996-8clxq   1/1     Running             3          7d
pod/php-apache-dfb6d784b-cqvbw                0/1     ContainerCreating   0          45s

NAME                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP   23d
service/php-apache   ClusterIP   10.98.233.77   <none>        80/TCP    45s

NAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nfs-client-provisioner   1/1     1            1           7d
deployment.apps/php-apache               0/1     1            0           46s

NAME                                                DESIRED   CURRENT   READY   AGE
replicaset.apps/nfs-client-provisioner-55d87b5996   1         1         1       7d
replicaset.apps/php-apache-dfb6d784b                1         1         0       46s

[kubeadm@server1 hpa]$ kubectl describe svc php-apache 
Name:              php-apache
Namespace:         default
Labels:            run=php-apache
Annotations:       Selector:  run=php-apache
Type:              ClusterIP
IP:                10.98.233.77
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.2.128:80  // 只有一个pod的ip
Session Affinity:  None
Events:            <none>

kubernetes(k8s):基于metrics server的HPA(pod水平自动弹性伸缩)_第1张图片

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 hpa
NAME         REFERENCE               TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   <unknown>/50%   1         10        0          8s

[kubeadm@server1 hpa]$ kubectl top pod
NAME                                      CPU(cores)   MEMORY(bytes)   
nfs-client-provisioner-55d87b5996-8clxq   2m           7Mi             
php-apache-dfb6d784b-cqvbw                1m           9Mi        

[root@server1 hpa]# kubectl get hpa    //当前时一个副本(REPLICAS)
NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   0%/50%    1         10        1          19s

请注意在上面的命令输出中,当前的CPU利用率是0%,这是由于我们尚未发送任何请求到服务器 (CURRENT 列显示了相应 deployment 所控制的所有 Pod 的平均 CPU 利用率)。

增加负载

现在,我们将看到 autoscaler 如何对增加负载作出反应。 我们将启动一个容器,并通过一个循环向 php-apache 服务器发送无限的查询请求:

[kubeadm@server1 hpa]$ kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   22d
php-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=Never
If you don't see a command prompt, try pressing enter.
/ # while true; do wget -q -O- http://10.109.183.127; done

kubernetes(k8s):基于metrics server的HPA(pod水平自动弹性伸缩)_第2张图片在几分钟时间内,通过以下命令,我们可以看到CPU负载升高了

[kubeadm@server1 ~]$ kubectl get hpa
NAME         REFERENCE               TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   250%/50%   1         10        1          6m22s
[kubeadm@server1 ~]$ 

这时,由于请求增多,CPU利用率已经升至250%。 可以看到,deployment 的副本数量已经增长到了5

[kubeadm@server1 ~]$ kubectl get hpa
NAME         REFERENCE               TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   250%/50%   1         10        5          6m57s
[kubeadm@server1 ~]$

查看pod的资源使用情况

[kubeadm@server1 ~]$ kubectl get pod
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-55d87b5996-8clxq   1/1     Running   3          7d
php-apache-dfb6d784b-52xmw                1/1     Running   0          2m20s
php-apache-dfb6d784b-cqvbw                1/1     Running   0          23m
php-apache-dfb6d784b-lsgtl                1/1     Running   0          2m20s
php-apache-dfb6d784b-r6gdc                1/1     Running   0          2m20s
php-apache-dfb6d784b-xzsf2                1/1     Running   0          2m5s
test       

kubernetes(k8s):基于metrics server的HPA(pod水平自动弹性伸缩)_第3张图片停止负载

我们将通过停止负载来结束我们的示例。

在我们创建 busyboxplus容器的终端中,输入 + C来终止负载的产生。

然后我们可以再次查看负载状态(等待几分钟时间):

[kubeadm@server1 ~]$ kubectl get hpa
NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   0%/50%    1         10        1          9m42s
[kubeadm@server1 ~]$

这时,CPU利用率已经降到0,所以 HPA 将自动缩减副本数量至1

注意: 自动伸缩完成副本数量的改变可能需要几分钟的时间。
kubernetes(k8s):基于metrics server的HPA(pod水平自动弹性伸缩)_第4张图片

3. HPA的伸缩过程

HPA伸缩过程:

  1. 收集HPA控制下所有Pod最近的cpu使用情况(CPU utilization)
  2. 对比在扩容条件里记录的cpu限额(CPUUtilization)----50%
  3. 调整实例数(必须要满足不超过最大/最小实例数)
  4. 每隔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 hpa
NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   0%/50%    1         10        1          32m

[kubeadm@server1 ~]$ kubectl top pod
NAME                                      CPU(cores)   MEMORY(bytes)   
nfs-client-provisioner-55d87b5996-8clxq   2m           7Mi             
php-apache-dfb6d784b-lsgtl                1m           12Mi            
test                                      0m           2Mi      

4. 引入其他度量指标(cpu+内存)

使用多个指标作为伸缩的条件

利用autoscaling/v2beta2API版本,您可以在自动伸缩 php-apache 这个 Deployment 时引入其他度量指标

[kubeadm@server1 ~]$ kubectl api-versions 
autoscaling/v1  // 使用一个指标
autoscaling/v2beta1   // 使用多个指标作为伸缩的条件
autoscaling/v2beta2
[root@server1 hpa]# vim hpav2.yaml 
[root@server1 hpa]# cat hpav2.yaml 
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler      //hpa
metadata:
  name: php-apache
spec:
  maxReplicas: 10
  minReplicas: 1
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: php-apache
  metrics:
  - type: Resource           //资源
    resource:
      name: cpu              //cpu
      target:
        averageUtilization: 60     // 限制cpu的使用率60%
        type: Utilization
  - type: Resource          //资源
    resource:
      name: memory          //内存
      target:
        averageValue: 50Mi        //内存使用量时50Mi
        type: AverageValue

[root@server1 hpa]# kubectl apply -f hpav2.yaml 
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
horizontalpodautoscaler.autoscaling/php-apache configured

[root@server1 hpa]# kubectl get hpa
NAME         REFERENCE               TARGETS                 MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   13824512/50Mi, 0%/60%   1         10        8          26m

kubernetes(k8s):基于metrics server的HPA(pod水平自动弹性伸缩)_第5张图片可以看出已经有了cpu和内存的双重指标,内存单位是字节

你可能感兴趣的:(kubernetes,kubernetes,HPA,metrics,server)