1. 程式人生 > 其它 >Kubernetes自動橫向擴充套件(HPA)詳解

Kubernetes自動橫向擴充套件(HPA)詳解

1.HPA介紹

HPA 的全稱為(Horizontal Pod Autoscaling)它可以根據當前 pod 資源的使用率(如 CPU、磁碟、記憶體等),進行副本數的動態的擴容與縮容,以便減輕各個 pod 的壓力。當 pod 負載達到一定的閾值後,會根據擴縮容的策略生成更多新的 pod 來分擔壓力,當 pod 的使用比較空閒時,在穩定空閒一段時間後,還會自動減少 pod 的副本數量。

官方文件
https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/
https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/
https://github.com/kubernetes-sigs/metrics-server

2.HPA原理

Kubernetes HPA和阿里雲的彈性伸縮Auto Scalling 很類似

使用彈性伸縮(Auto Scaling),您可以根據業務需求和策略設定伸縮規則,在業務需求增長時自動為您增加ECS例項以保證計算能力,在業務需求下降時自動減少ECS例項以節約成本。彈性伸縮不僅適合業務量不斷波動的應用程式,
同時也適合業務量穩定的應用程式。

伸縮物件:

HPA可以對replication controller, deployment, replica set和stateful set進行自動伸縮,但是不能對daemon set進行自動伸縮。因為daemon set只能每個節點執行一個副本,不可伸縮。

3.HPA示例

3.1安裝Metrics Server

HPA需要從Metrics Server中獲取Pod的CPU和記憶體Metrics,用來判斷是否達到自動伸縮閾值。

如果還沒有安裝Metrics Server,可以參考:https://www.cnblogs.com/wuxinchun/p/15273213.html

3.2建立Deployment

1)yaml檔案

為了測試 HPA,這裡將使用php-apache,php-apache主要是一個 之後將通過請求訪問該 Pod ,用來模擬請求的負載增加和減少,檢視 Pod 的數量變化

[root@k8s-master metrics-server]# pwd
/root/k8s_practice/metrics-server [root@k8s-master metrics-server]# 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: "registry.cn-shenzhen.aliyuncs.com/cookcodeblog/hpa-example:latest" 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

2)建立php-apache並驗證

[root@k8s-master metrics-server]# kubectl apply -f php-apache.yaml
[root@k8s-master metrics-server]# kubectl get deploy,svc php-apache 
NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/php-apache   1/1     1            1           2m26s

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
service/php-apache   ClusterIP   10.100.133.191   <none>        80/TCP    2m26s
[root@k8s-master metrics-server]# kubectl get pod -l run=php-apache -o wide
NAME                          READY   STATUS    RESTARTS   AGE    IP            NODE        NOMINATED NODE   READINESS GATES
php-apache-5b58575b9d-bc56q   1/1     Running   0          3m6s   10.244.1.38   k8s-node1   <none>           <none>

3.3建立HPA

1)建立預設建立的HPA名稱和需要自動伸縮的物件名一致

# 可以通過--name來指定HPA名稱
[root@k8s-master metrics-server]# kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
horizontalpodautoscaler.autoscaling/php-apache autoscaled

注:為deployment php-apache 建立HPA,其中最小副本數為1,最大副本數為10,保持該deployment的所有Pod的平均CPU使用率不超過50%

在本例中,deployment的pod的resources.request.cpu為200m (200 milli-cores vCPU),所以HPA將保持所有Pod的平均CPU使用率不超過100m。

2)通過kubectl top pods檢視pod的CPU使用情況。

[root@k8s-master metrics-server]# kubectl get hpa php-apache
NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   0%/50%    1         10        1          17s

注:如果TARGETS列值格式為<acutal>/<expected>, 如果actual值總是為unkown,則表示無法從Metrics Server中獲取指標值。請參見上面的“安裝Metrics Server”章節

HPA預設每15秒從Metrics Server取一下指標來判斷是否要自動伸縮:
The Horizontal Pod Autoscaler is implemented as a control loop, with a period controlled by the controller manager’s 
--horizontal-pod-autoscaler-sync-period flag (with a default value of 15 seconds).
Metrics Server採集指標的預設間隔為60秒:
Default 60 seconds, can be changed using metrics-resolution flag. We are not recommending setting values below 15s, 
as this is the resolution of metrics calculated within Kubelet.

3.3模擬增加負載

1)模擬增加負載

開啟一個新的Terminal,建立一個臨時的podload-generator,並在該pod中向php-apache服務發起不間斷迴圈請求,模擬增加php-apache的負載(CPU使用率)。

[root@k8s-master metrics-server]# 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!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!OK!OK!OK!O

注:如果無法通過http://php-apache訪問服務,需要檢查kube-dns和網路是否配置正確,可以參考:https://cookcode.blog.csdn.net/article/details/109424100

2)模擬壓力測試幾分鐘後,觀察HPA:

[root@k8s-master metrics-server]# kubectl get hpa php-apache
NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   75%/50%   1         10        5          10m

可以看到TARGETS(CPU使用率)的acutal值已升高到75% (超過了期望值50%),副本數REPLICAS也從1自動擴容到了5。

注:如果Kubernetes叢集worker節點的CPU資源已經不足,HPA自動擴容會失敗,新擴容的pod會一直處在Pending狀態。通過kubectl describe命令檢視pod詳細資訊時,會看到“Insufficient cpu"的錯誤資訊。

3)觀察deployment和pod:

[root@k8s-master metrics-server]# kubectl get deployment php-apache
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
php-apache   8/8     8            8           16m
[root@k8s-master metrics-server]# kubectl get pods -l run=php-apache -o wide
NAME                          READY   STATUS    RESTARTS   AGE     IP            NODE        NOMINATED NODE   READINESS GATES
php-apache-5b58575b9d-5kxzq   1/1     Running   0          2m45s   10.244.2.40   k8s-node2   <none>           <none>
php-apache-5b58575b9d-6r4hn   1/1     Running   0          4m46s   10.244.2.39   k8s-node2   <none>           <none>
php-apache-5b58575b9d-bc56q   1/1     Running   0          17m     10.244.1.38   k8s-node1   <none>           <none>
php-apache-5b58575b9d-bf2lk   1/1     Running   0          4m31s   10.244.1.40   k8s-node1   <none>           <none>
php-apache-5b58575b9d-gs4gl   1/1     Running   0          2m45s   10.244.1.41   k8s-node1   <none>           <none>
php-apache-5b58575b9d-jrd72   1/1     Running   0          4m46s   10.244.2.38   k8s-node2   <none>           <none>
php-apache-5b58575b9d-nhb8q   1/1     Running   0          4m46s   10.244.1.39   k8s-node1   <none>           <none>
php-apache-5b58575b9d-rm8dm   1/1     Running   0          2m45s   10.244.2.41   k8s-node2   <none>           <none>

4)發現HPA觀測到的CPU實際使用率已降低到46%(小於目標值50%):

[root@k8s-master metrics-server]# kubectl get hpa php-apache
NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   46%/50%   1         10        8          13m

注:也就是HPA通過自動擴容到8個副本,來分攤了負載,使得所有Pod的平均CPU使用率保持在目標值內

可以通過kubectl describe hpa php-apache檢視HPA自動伸縮的事件

3.4模擬減少負載

在執行load-generator的Terminal,按下Ctrl+C來終止程序。

等待幾分鐘後,觀察HPA:

[root@k8s-master metrics-server]# kubectl get hpa php-apache
NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   0%/50%    1         10        1          22m

注:Kuberntes為了保證縮容時業務不中斷,和防止頻繁伸縮導致系統抖動,scaledown一次後需要等待一段時間才能再次scaledown,也叫伸縮冷卻(cooldown)。預設伸縮冷卻時間為5分鐘。

通過kubectl describe hpa php-apache檢視HPA自動伸縮的事件,可以看到“horizontal-pod-autoscaler New size: 1; reason: All metrics below target”的事件。

如果觀察HPA沒有scale down,需要再等待一段時間。

Kuberntes為了保證縮容時業務不中斷,和防止頻繁伸縮導致系統抖動,scaledown一次後需要等待一段時間才能再次scaledown,也叫伸縮冷卻(cooldown)。

預設伸縮冷卻時間為5分鐘。

--horizontal-pod-autoscaler-downscale-stabilization: The value for this option is a duration that specifies how long the autoscaler has to wait before another downscale operation can be performed after the current one has completed. The default value is 5 minutes (5m0s).

參見:https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#support-for-cooldown-delay

類似的,可以參考阿里雲自動伸縮的伸縮冷卻時間
作者:傑巨集唯一 出處:http://www.cnblogs.com/wuxinchun/ 本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利.