【kubernetes系列】Kubernetes之自动扩容Horizontal Pod Autoscaling(HPA)

k8s中的自动扩容Horizontal Pod Autoscaling(HPA)

分布式系统要能够根据当前负载的变化情况自动触发水平扩展或缩容的行为,因为这一过程可能是频繁发生的、不可预料的,所以手动控制的方式是不现实的。HPA全称是Horizontal Pod Autoscaler,翻译成中文是POD水平自动伸缩,以下都会用HPA代替Horizontal Pod Autoscaler,HPA可以基于CPU利用率、内存利用率对replication controller、deployment和replicaset中的pod数量进行自动扩缩容(除了CPU利用率也可以基于其他应程序提供的度量指标custom metrics进行自动扩缩容)

在Kubernetes1.1版本中首次发布了这一重量级新特性—–Horizontal Pod Autoscaler。

HPA的实现是一个控制循环,由controller manager的–horizontal-pod-autoscaler-sync-period参数指定周期(默认值为15秒)。每个周期内,controller manager根据每个HorizontalPodAutoscaler定义中指定的指标查询资源利用率。controller manager可以从resource metrics API(pod 资源指标)和custom metrics API(自定义指标)获取指标。依赖metric-server服务,需要自行单独部署,过程中可以随时查看该pod的日志来排查问题,部署方式参考https://github.com/kubernetes-sigs/metrics-server

目前,可以有以下两种方式作为Pod负载的度量指标:

1、CPU/内存 utilization percentage

2、应用程序自定义的度量指标,比如服务在每秒内的相应的请求数(TPS或QPS)

CPU/内存 utilization percentage是一个算术平均值,即目标pod所有副本自身的CPU/内存利用率的平均值。拿cpu来说,一个Pod自身的CPU利用率是该Pod当前CPU使用量除以它的Pod request的值。比如当我们定义一个Pod的pod request为0.6,而当前pod的cpu使用量为0.3,则使用率为50%。如此可以得出一个平均值,如果某一个时刻CPU utilization percentage超过80%,则意味着当前Pod副本不足以支撑接下来更多的请求,需要进行动态扩容。而当请求高峰时段过去后,Pod的CPU利用率又会降下来,此时对应的Pod副本数应该自动减少到一个合理的水平。

CPU/内存 utilization percentage计算过程使用到的Pod的CPU使用量通常是1分钟的平均值。

条件

HPA通过定期(定期轮询的时间通过–horizontal-pod-autoscaler-sync-period选项来设置,默认的时间为30秒)通过Status.PodSelector来查询pods的状态,获得pod的CPU使用率。然后,通过现有pods的CPU使用率的平均值(计算方式是最近的pod使用量(最近一分钟的平均值,从heapster中获得)除以设定的每个Pod的CPU使用率限额)跟目标使用率进行比较,并且在扩容时,还要遵循预先设定的副本数限制:MinReplicas <= Replicas <= MaxReplicas。

计算扩容后Pod的个数:sum(最近一分钟内某个Pod的CPU使用率的平均值)/CPU使用上限的整数+1

过程

1、创建HPA资源,设定目标CPU或者内存使用率限额,以及最大、最小实例数

2、收集一组中(PodSelector)每个Pod最近一分钟内的CPU或者内存使用率,并计算平均值

3、读取HPA中设定的CPU或者内存使用限额

4、计算:平均值之和/限额,求出目标调整的实例个数

5、目标调整的实例数不能超过1中设定的最大、最小实例数,如果没有超过,则扩容;超过,则扩容至最大的实例个数

例外

考虑到自动扩展的决策可能需要一段时间才会生效,例如当pod所需要的CPU/内存负荷过大,从而运行一个新的pod进行分流,在创建过程中,系统的CPU/内存使用量可能会有一个攀升的过程。所以,在每一次作出决策后的一段时间内,将不再进行扩展决策。对于ScaleUp而言,这个时间段为3分钟,Scaledown为5分钟。

HPA允许一定范围内的CPU/内存使用量的不稳定,只有avg(CurrentPodsConsumption) / Target**小于90%或者大于110%**时才会触发扩容或缩容,避免频繁扩容、缩容造成颠簸。如下,内存使用率已经超过85%还是没有自动扩展。

[root@prod-com-k8master1 prod_yaml]# kubectl get hpa -A
NAMESPACE   NAME              REFERENCE                TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
com-prod    aad-server-mem    Deployment/aad-server    123%/85%   2         4         4          223d
com-prod    ac-server-mem     Deployment/ac-server     92%/85%    2         3         2          223d
com-prod    adb-service-mem   Deployment/adb-service   90%/85%    1         2         1          223d
com-prod    adc-service-mem   Deployment/adc-service   62%/85%    2         3         2          223d
com-prod    ade-service-mem   Deployment/ade-service   54%/85%    6         9         6          226d

为什么选择相对使用率

为了简便,选用了相对使用率(90%的CPU资源)而不是0.6个CPU core来描述扩容、缩容条件。如果选择使用绝对度量,用户需要保证目标(限额)要比请求使用的低,否则,过载的Pod未必能够消耗那么多,从而自动扩容永远不会被触发:假设设置CPU为1个核,那么这个pod只能使用1个核,可能Pod在过载的情况下也不能完全利用这个核,所以扩容不会发生。在修改申请资源时,还有同时调整扩容的条件,比如将1个core变为1.2core,那么扩容条件应该同步改为1.2core,真是太麻烦了,与自动扩容的目标相悖。

实例一

1、基于CPU自动扩容

[root@k8s-m1 hpa]# cat cpu-hpa.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-cpu-hpa
  namespace: test1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-cpu-hpa
  template:
    metadata:
      labels:
        app: nginx-cpu-hpa
    spec:
      containers:
      - name: nginx-hpa
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        resources:
          limits:
            cpu: 200m
          requests:
            cpu: 100m
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-cpu-hpa-svc
  namespace: test1
spec:
  ports:
  - port: 80
    protocol: TCP
  selector:
    app: nginx-cpu-hpa
  type: ClusterIP

kubectl apply -f cpu-hpa.yaml

2、创建HPA

nginx-cpu-hpa服务正在运行,使用kubectl autoscale创建自动缩放器,实现对nginx-cpu-hpa这个deployment创建的pod自动扩缩容,下面的命令将会创建一个HPA,HPA将会根据CPU,内存等资源指标增加或减少副本数,创建一个可以实现如下目的的hpa:

1)让副本数维持在1-10个之间(这里副本数指的是通过deployment部署的pod的副本数)
2)将所有Pod的平均CPU使用率维持在20%(通过kubectl run运行的每个pod如果是100毫核,这意味着平均CPU利用率为20毫核
给上面nginx-cpu-hpa这个deployment创建HPA

[root@k8s-m1 hpa]#kubectl autoscale deployment nginx-cpu-hpa -n test1 --cpu-percent=20 --min=1 --max=10

解释:
kubectl autoscale deployment nginx-cpu-hpa (nginx-cpu-hpa表示deployment的名字) --cpu-percent=20(表示cpu使用率不超过50%) --min=1(最少一个pod) --max=10(最多10个pod)
kubectl delete hpa tomcat-hpa -n app (命令行创建的hpa修改需要先删除)

3、验证HPA

[root@k8s-m1 hpa]# kubectl get hpa -n test1
NAME            REFERENCE                  TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
nginx-cpu-hpa   Deployment/nginx-cpu-hpa   0%/20%    1         10        1          14m

4、进行压测查看pod的数量变化
查看svc地址为:

[root@k8s-m1 hpa]# kubectl get svc -n test1
NAME                TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
nginx-cpu-hpa-svc   ClusterIP   10.109.69.60   <none>        80/TCP    49m

进行压力测试:
为满足大并发,通过安装webbench软件进行测试,安装过程如下:

yum install make cmake ctags -y
mkdir /usr/local/man
wget  http://home.tiscali.cz/~cz210552/distfiles/webbench-1.5.tar.gz
tar zxvf webbench-1.5.tar.gz
cd webbench-1.5
make && make install
while true; do webbench -c 200 -t 60 http://10.109.69.60:80/index.html; done  #一分钟内200个并发

5、查看hpa的负载变化

[root@k8s-m1 hpa]# kubectl get  hpa -n test1 nginx-cpu-hpa 
NAME            REFERENCE                  TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
nginx-cpu-hpa   Deployment/nginx-cpu-hpa   115%/20%   1         10        6          4h4m

6、查看pod数量变化

[root@k8s-m1 hpa]# kubectl get pods -n test1 -o wide
NAME                            READY   STATUS    RESTARTS   AGE     IP             NODE     NOMINATED NODE   READINESS GATES
nginx-cpu-hpa-7b7545fcc-4dxjt   1/1     Running   0          37s     10.244.11.0    k8s-m3   <none>           <none>
nginx-cpu-hpa-7b7545fcc-cjcgc   1/1     Running   0          37s     10.244.11.27   k8s-m3   <none>           <none>
nginx-cpu-hpa-7b7545fcc-fpf8b   1/1     Running   0          21s     10.244.11.13   k8s-m3   <none>           <none>
nginx-cpu-hpa-7b7545fcc-wkjk9   1/1     Running   0          4h37m   10.244.11.38   k8s-m3   <none>           <none>
nginx-cpu-hpa-7b7545fcc-z2wkc   1/1     Running   0          37s     10.244.11.62   k8s-m3   <none>           <none>
nginx-cpu-hpa-7b7545fcc-zsgnl   1/1     Running   0          21s     10.244.11.3    k8s-m3   <none>           <none>

7、测试停止后,pod数量减少为1

[root@k8s-m1 hpa]# kubectl get pods -n test1 -o wide
NAME                            READY   STATUS    RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
nginx-cpu-hpa-7b7545fcc-wkjk9   1/1     Running   0          51m   10.244.11.38   k8s-m3   <none>           <none>

实例二

1、基于内存自动扩容

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-mem-hpa
  namespace: test1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-mem-hpa
  template:
    metadata:
      labels:
        app: nginx-mem-hpa
    spec:
      containers:
      - name: nginx-hpa
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        resources:
          limits:
           memory: 100Mi
          requests:
           memory: 50Mi
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-mem-hpa-svc
  namespace: test1
spec:
  ports:
  - port: 80
    protocol: TCP
  selector:
    app: nginx-mem-hpa
  type: ClusterIP
---
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: nginx-hpa
  namespace: test1
spec:
  maxReplicas: 10
  minReplicas: 1
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx-mem-hpa
  metrics:
  - type: Resource
    resource:
      name: memory
      targetAverageUtilization: 50

2、验证HPA

[root@k8s-m1 hpa]# kubectl get hpa -n test1
NAME        REFERENCE                  TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
nginx-hpa   Deployment/nginx-mem-hpa   6%/50%    1         10        1          87s

3、进行压测查看pod的数量变化
查看svc地址为:

[root@k8s-m1 webbench-1.5]# kubectl get svc -n test1
NAME                TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
nginx-mem-hpa-svc   ClusterIP   10.108.189.64   <none>        80/TCP    12m

进行压力测试,通过webbench软件进行大并发测试,安装过程如下:

[root@k8s-m1 webbench-1.5]#  while true; do webbench -c 20000 -t 10 http://10.108.189.64:80/index.html; done #10s内20000w个并发

4、动态查看hpa的负载变化

[root@k8s-m1 hpa]# kubectl get hpa -n test1 -w
NAME        REFERENCE                  TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
nginx-hpa   Deployment/nginx-mem-hpa   20%/50%   1         10        1         1m
......
......
nginx-hpa   Deployment/nginx-mem-hpa   63%/50%   1         10        6         14m

5、查看pod数量变化,

[root@k8s-m1 hpa]# kubectl get pod -n test1
NAME                             READY   STATUS    RESTARTS   AGE
nginx-mem-hpa-855fb5bbb4-6xbtk   1/1     Running   0          7m48s
nginx-mem-hpa-855fb5bbb4-9lklv   1/1     Running   0          6m46s
nginx-mem-hpa-855fb5bbb4-ffdlc   1/1     Running   0          7m48s
nginx-mem-hpa-855fb5bbb4-k8bpt   1/1     Running   0          6m46s
nginx-mem-hpa-855fb5bbb4-m9sgb   1/1     Running   0          6m46s
nginx-mem-hpa-855fb5bbb4-nqmh7   1/1     Running   0          10m

6、测试停止后,pod数量减少为1,注意这个过程变化效果可能比较缓慢

[root@k8s-m1 hpa]# kubectl get pod -n test1
NAME                             READY   STATUS    RESTARTS   AGE
nginx-mem-hpa-855fb5bbb4-nqmh7   1/1     Running   0          17m
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

margu_168

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值