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

一.HPA简介

  • HAP,全称 Horizontal Pod Autoscaler, 可以基于 CPU 利用率自动扩缩 ReplicationController、Deployment 和 ReplicaSet 中的 Pod 数量。 除了 CPU 利用率,也可以基于其他应程序提供的自定义度量指标来执行自动扩缩。 Pod 自动扩缩不适用于无法扩缩的对象,比如 DaemonSet。
  • Pod 水平自动扩缩特性由 Kubernetes API 资源和控制器实现。资源决定了控制器的行为。 控制器会周期性的调整副本控制器或 Deployment 中的副本数量,以使得 Pod 的平均 CPU 利用率与用户所设定的目标值匹配。

Pod HAP工作机制示意图
在这里插入图片描述
实际生产中,广泛使用这四类指标:

  • Resource metrics - CPU核内存利用率指标
  • Pod metrics - 例如网络利用率和流量
  • Object metrics - 特定对象的指标,比如Ingress, 可以按每秒使用请求数来扩展容器
  • Custom metrics - 自定义监控,比如通过定义服务响应时间,当响应时间达到一定指标时自动扩容

二.HPA实时调度pod(CPU)

Hpa会根据Pod的CPU使用率动态调节Pod的数量

使用Deployment生成php-apache,开放端口80,镜像hpa-example已上传至harbor供集群拉取

[root@server1 dash]# cat deploy.yml 
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

---

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

部署hpa,查看详细信息

[root@server1 dash]# kubectl  apply  -f deploy.yml 
deployment.apps/php-apache created
service/php-apache created
[root@server1 dash]# kubectl  get svc
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP   10d
php-apache   ClusterIP   10.96.118.8   <none>        80/TCP    29s
[root@server1 dash]# kubectl  get pod
NAME                          READY   STATUS    RESTARTS   AGE
php-apache-6cc67f7957-crtvk   1/1     Running   0          34s
[root@server1 dash]# kubectl  describe  svc php-apache 
Name:              php-apache
Namespace:         default
Labels:            run=php-apache
Annotations:       <none>
Selector:          run=php-apache
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.96.118.8
IPs:               10.96.118.8
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.22.33:80
Session Affinity:  None
Events:            <none>
[root@server1 dash]# kubectl  get deployments.apps 
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
php-apache   1/1     1            1           66s
[root@server1 dash]# kubectl  get hpa
NAME         REFERENCE               TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   <unknown>/50%   1         10        0          3s

现在,php-apache 服务器已经运行,我们将通过 kubectl autoscale 命令创建 Horizontal Pod Autoscaler。 以下命令将创建一个 Horizontal Pod Autoscaler 用于控制我们上一步骤中创建的 Deployment,使 Pod 的副本数量维持在 1 到 10 之间。 大致来说,HPA 将(通过 Deployment)增加或者减少 Pod 副本的数量以保持所有 Pod 的平均 CPU 利用率在 50% 左右(由于每个 Pod 请求 200 毫核的 CPU,这意味着平均 CPU 用量为 100 毫核)

[root@server1 dash]# kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
horizontalpodautoscaler.autoscaling/php-apache autoscaled
[root@server1 dash]# kubectl  get hpa
NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   0%/50%    1         10        1          2m53s

创建交互pod,不断写入,增大cpu负载

[root@server1 ~]# kubectl run -i --tty load-generator --rm --image=busybox --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://php-apache; done"


If you don't see a command prompt, try pressing enter.


OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!O

查看hpa php-apache,随着负载增大,pod php-apache 数量增多,用于缓解压力

[root@server1 dash]# kubectl  get hpa
NAME         REFERENCE               TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   192%/50%   1         10        8          4m53s
[root@server1 dash]# kubectl  top pod --use-protocol-buffers
NAME                          CPU(cores)   MEMORY(bytes)   
load-generator                17m          0Mi                        
php-apache-6cc67f7957-4wrgq   96m          8Mi             
php-apache-6cc67f7957-8ckhs   215m         11Mi            
php-apache-6cc67f7957-crtvk   213m         15Mi            
php-apache-6cc67f7957-lkftt   112m         8Mi             
php-apache-6cc67f7957-mnmrb   91m          7Mi             
php-apache-6cc67f7957-rjx8v   92m          8Mi             
php-apache-6cc67f7957-rtjbw   138m         8Mi             
php-apache-6cc67f7957-x5767   124m         8Mi   

关闭测试pod,开始冷却,负载下降,单个pod cpu占用降低,但pod数量没有下降

[root@server1 dash]# kubectl  top pod --use-protocol-buffers
NAME                          CPU(cores)   MEMORY(bytes)         
php-apache-6cc67f7957-4wrgq   30m          8Mi             
php-apache-6cc67f7957-8ckhs   36m          11Mi            
php-apache-6cc67f7957-crtvk   24m          15Mi            
php-apache-6cc67f7957-lkftt   38m          8Mi             
php-apache-6cc67f7957-mnmrb   31m          7Mi             
php-apache-6cc67f7957-rjx8v   31m          8Mi             
php-apache-6cc67f7957-rtjbw   38m          8Mi             
php-apache-6cc67f7957-x5767   31m          8Mi             
[root@server1 dash]# kubectl  get hpa
NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   79%/50%   1         10        8          5m49s

负载降至零

[root@server1 dash]# kubectl  get hpa
NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   0%/50%    1         10        8          9m
[root@server1 dash]# kubectl  top pod --use-protocol-buffers
NAME                          CPU(cores)   MEMORY(bytes)          
php-apache-6cc67f7957-4wrgq   1m           8Mi             
php-apache-6cc67f7957-8ckhs   1m           11Mi            
php-apache-6cc67f7957-crtvk   1m           15Mi            
php-apache-6cc67f7957-lkftt   1m           8Mi             
php-apache-6cc67f7957-mnmrb   1m           7Mi             
php-apache-6cc67f7957-rjx8v   1m           8Mi             
php-apache-6cc67f7957-rtjbw   1m           8Mi             
php-apache-6cc67f7957-x5767   1m           8Mi       

最终,pod数量减少



[root@server1 dash]# kubectl  top pod --use-protocol-buffers
NAME                          CPU(cores)   MEMORY(bytes)             
php-apache-6cc67f7957-8ckhs   1m           11Mi            
php-apache-6cc67f7957-crtvk   1m           15Mi            
php-apache-6cc67f7957-rtjbw   1m           8Mi    

HPA伸缩过程:

  • 收集HPA控制下所有Pod最近的cpu使用情况(CPU utilization)
  • 对比在扩容条件里记录的cpu限额(CPUUtilization)
  • 调整实例数(必须要满足不超过最大/最小实例数)
  • 每隔30s做一次自动扩容的判断

CPU utilization的计算方法是用cpu usage(最近一分钟的平均值,通过metrics可以直接获取到)除以cpu request(这里cpu request就是我们在创建容器时制定的cpu使用核心数)得到一个平均值,这个平均值可以理解为:平均每个Pod CPU核心的使用占比。

HPA进行伸缩算法:

  • 计算公式:TargetNumOfPods = ceil(sum(CurrentPodsCPUUtilization) / Target)
  • ceil()表示取大于或等于某数的最近一个整数
  • 每次扩容后冷却3分钟才能再次进行扩容,而缩容则要等5分钟后。
  • 当前Pod Cpu使用率与目标使用率接近时,不会触发扩容或缩容:
  • 触发条件:avg(CurrentPodsConsumption) / Target >1.1 或 <0.9

三.HPA实时调度pod(CPU+MEM)

cpu占用率cpu:60 内存占用 mem:50

[root@server1 dash]# cat hpa.yml 
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: php-apache
spec:
  maxReplicas: 10
  minReplicas: 1
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: php-apache
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        averageUtilization: 60
        type: Utilization
  - type: Resource
    resource:
      name: memory
      target:
        averageValue: 50Mi
        type: AverageValue

执行部署脚本,查看hap信息 16023552/50Mi, 0%/60%

[root@server1 dash]# vim hpa.yml
[root@server1 dash]# kubectl  apply  -f hpa.yml 
Warning: resource horizontalpodautoscalers/php-apache is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by kubectl apply. kubectl apply should only be used on resources created declaratively by either kubectl create --save-config or kubectl apply. The missing annotation will be patched automatically.
horizontalpodautoscaler.autoscaling/php-apache configured
[root@server1 dash]# kubectl  get hpa
NAME         REFERENCE               TARGETS                 MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   16023552/50Mi, 0%/60%   1         10        1          13m
[root@server1 dash]# kubectl  top pod --use-protocol-buffers
NAME                          CPU(cores)   MEMORY(bytes)            
php-apache-6cc67f7957-crtvk   1m           15Mi            
        
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐