一、概述
Pod 水平自動擴縮(Horizontal Pod Autoscaler)簡稱 HPA,HPA 可以根據 CPU 利用率進行自動伸縮 Pod 副本數量,除了 CPU 利用率,也可以基於其他應程式提供的自定義度量指標來執行自動擴縮。
通過 HPA 可以達到某個時刻業務請求量很大的時候,不需要我們人工去幹涉,它會根據我們設定的指標來進行自動伸縮 Pod 數量來應付訪問量。
這是官方的圖
這是我畫的圖(勿噴)
二、安裝Metrics-Server
Heapster 官方在v1.11中已經被廢棄,Heapster 監控資料可用,但 HPA 不再從 Heapster 拿資料,所以就不能滿足我們本次實驗。
Kubernetes 版本為 v1.2 或更高採用 Metrics-Server 來獲取監控資料, HPA 根據此 Metrics API 來獲取度量資料,所以本次實驗需要安裝 Metrics-Server 外掛。
1.1 下載YAML檔案,修改配置
Metrics-Server
GitHub 連結:
https://github.com/kubernetes-sigs/metrics-server
由於我的環境 K8s 版本是 1.21,直接安裝最新的 Metrics-Server 即可。
我們需要下載components.yaml
下載到本地,新增- --kubelet-insecure-tls
到配置檔案中,否則會報錯
[root@k8s-master01 ]# wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
如果 Linux 作業系統一直無法下載,可以嘗試在 Windows 上的迅雷下載好上傳。
開啟components.yaml
新增如下配置:
- --kubelet-insecure-tls
# kubelet 的10250埠使用的是https協議,連線需要驗證tls證書,--kubelet-insecure-tls不驗證客戶端證書。
1.2 注意事項
如果不新增- --kubelet-insecure-tls
,可能會出現如下報錯
檢視 metrics-server-xxx-xxx
詳細事件時發現報錯如下:
[root@k8s-master01 ~]# kubectl describe pod metrics-server-xxx-xxx -n kube-system
我們在檢視該 Pod 詳細日誌,報錯如下:
[root@k8s-master01 ~]# kubectl logs -n kube-system metrics-server-6dfddc5fb8-f8gnd
...
I0531 07:57:33.049547 1 server.go:188] "Failed probe" probe="metric-storage-ready" err="not metrics to serve"
I0531 07:57:43.049460 1 server.go:188] "Failed probe" probe="metric-storage-ready" err="not metrics to serve"
E0531 07:57:44.458989 1 scraper.go:139] "Failed to scrape node" err="Get \"https://192.168.115.11:10250/stats/summary?only_cpu_and_memory=true\": x509: cannot validate certificate for 192.168.115.11 because it doesn't contain any IP SANs" node="k8s-master01"
E0531 07:57:44.472464 1 scraper.go:139] "Failed to scrape node" err="Get \"https://192.168.115.13:10250/stats/summary?only_cpu_and_memory=true\": x509: cannot validate certificate for 192.168.115.13 because it doesn't contain any IP SANs" node="k8s-node02"
E0531 07:57:44.478313 1 scraper.go:139] "Failed to scrape node" err="Get \"https://192.168.115.12:10250/stats/summary?only_cpu_and_memory=true\": x509: cannot validate certificate for 192.168.115.12 because it doesn't contain any IP SANs" node="k8s-node01"
1.3 手動下載映象
由於k8s.gcr.io
在國外,導致無法下載metrics-server
映象問題。
當我們檢視 Pod 狀態是發現為ImagePullBackOff
[root@k8s-master01 ~]# kubectl get pod -n kube-system
檢視 metrics-server-xxx-xxx
詳細事件時發現報錯如下:
[root@k8s-master01 ~]# kubectl describe pod metrics-server-xxx-xxx -n kube-system
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 4m1s default-scheduler Successfully assigned kube-system/metrics-server-87966b776-jqknh to k8s-node01
Normal Pulling 106s (x4 over 4m) kubelet Pulling image "k8s.gcr.io/metrics-server/metrics-server:v0.5.0"
Warning Failed 91s (x4 over 3m45s) kubelet Failed to pull image "k8s.gcr.io/metrics-server/metrics-server:v0.5.0": rpc error: code = Unknown desc = Error response from daemon: Get https://k8s.gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
Warning Failed 91s (x4 over 3m45s) kubelet Error: ErrImagePull
Warning Failed 76s (x6 over 3m45s) kubelet Error: ImagePullBackOff
Normal BackOff 61s (x7 over 3m45s) kubelet Back-off pulling image "k8s.gcr.io/metrics-server/metrics-server:v0.5.0"
需要手動下載映象再進行改名(每個節點都需要下載)
[root@k8s-master01 ~]# docker pull bitnami/metrics-server:0.5.0
[root@k8s-master01 ~]# docker tag bitnami/metrics-server:0.5.0 k8s.gcr.io/metrics-server/metrics-server:v0.5.0
注意:當你看到這篇筆記的時候,可能映象已經更新了,根據報錯提示來下載即可。
1.4 開始建立 Metrics-Server
只需要在 K8s-master 節點建立即可!
[root@k8s-master01 ~]# kubectl apply -f components.yaml
serviceaccount/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
service/metrics-server created
deployment.apps/metrics-server created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
檢視 Pod 狀態發現已經 Running
[root@k8s-master01 ~]# kubectl get pod -n kube-system
檢查 Metrics Server
[root@k8s-master01 ~]# kubectl top nodesW0531 17:22:17.466637 97641 top_node.go:119] Using json format to get metrics. Next release will switch to protocol-buffers, switch early by passing --use-protocol-buffers flagNAME CPU(cores) CPU% MEMORY(bytes) MEMORY% k8s-master01 119m 5% 1198Mi 64% k8s-node01 29m 1% 476Mi 25% k8s-node02 32m 1% 433Mi 23%
不知道為什麼會出現這樣的提示,Metrics Server 是正常的,也可以獲取到資源使用情況,暫時不理它,後續再解決。
W0531 17:22:17.466637 97641 top_node.go:119] Using json format to get metrics. Next release will switch to protocol-buffers, switch early by passing --use-protocol-buffers flag
在 K8s Dashboard 介面檢視資源使用情況
二、建立 HPA 測試案例
建立一個Deployment
管理的Nginx
Pod,然後利用HPA
來進行自動擴縮容。
定義Deployment
的YAML
檔案如下:(hap-deploy-demo.yaml)
apiVersion: apps/v1kind: Deploymentmetadata: name: hpa-nginx-deployspec: selector: matchLabels: run: hpa-nginx-deploy replicas: 1 template: metadata: labels: run: hpa-nginx-deploy spec: containers: - name: nginx image: hub.test.com/library/mynginx:v1 # 映象地址 ports: - containerPort: 80 resources: limits: # 最大限制 cpu: 500m # CPU最大是500微核 requests: # 最低保證 cpu: 200m # CPU最小是200微核
在test
名稱空間建立Deployment
:
[root@k8s-master01 hpa-test]# kubectl create -f hpa-deploy-demo.yaml -n testdeployment.apps/hpa-nginx-deploy created
-n test 指定名稱空間
檢視 Pod 、Deployment 狀態
建立一個HPA
,可以使用kubectl autoscale
命令來建立:
[root@k8s-master01 ~]# kubectl autoscale deployment hpa-nginx-deploy --cpu-percent=20 --min=1 --max=10 -n testhorizontalpodautoscaler.autoscaling/hpa-nginx-deploy autoscaled
--cpu-percent=20 HPA 會通過 Pod 伸縮保持平均 CPU 利用率在20%以內;
--min=1 --max=10 允許 Pod 伸縮範圍,最小的 Pod 副本數為1,最大為10;
也可以使用 YAML 進行 HPA 編寫更為詳細的設定。
檢視 HPA 當前狀態
[root@k8s-master01 hpa-test]# kubectl get hpa -n testNAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGEhpa-nginx-deploy Deployment/hpa-nginx-deploy 0%/20% 1 10 1 37m
當前的 CPU 利用率是 0%,由於未傳送任何請求到該 Pod。
檢視 hpa-nginx-deploy
Pod 的 IP地址
[root@k8s-master01 hpa-test]# kubectl get pod -n test -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATEShpa-nginx-deploy-9f8676f85-57kg8 1/1 Running 0 42m 10.244.1.23 k8s-node01 <none> <none>
2.1 增加負載測試
增大負載進行測試,我們來建立一個busybox
,並且迴圈訪問上面建立的服務。
[root@k8s-master01 ~]# kubectl run -i --tty load-generator --rm --image=busybox --restart=Never -- /bin/sh -c "while true; do wget -q -O- http://10.244.1.23; done" -n test
等待一小會,檢視 HPA 負載情況,當前 CPU 使用率 49% 已經超出設定值
[root@k8s-master01 ~]# kubectl get hpa -n test -w
此時來檢視deployment
Pod 副本數量,由原來的1個自動擴容到5個
[root@k8s-master01 ~]# kubectl get deployment hpa-nginx-deploy -n test -w
再次檢視 HPA 負載情況,可以看到一直保持在 20% 以內
2.2 停止負載測試
在剛剛建立 busybox 容器的終端中,輸入<Ctrl> + C
來終止負載的測試即可。
等待一會,檢視 HPA 負載情況和 Deployment
Pod副本數是否到達收縮功能
這是 Dashboard 介面情況,已經過去一兩分鐘了,還沒見收縮,再等等
此時我們可以看到 Pod 副本數已經被收縮了,因為 CPU 使用率為 0,所以只保留最小副本數1個 Pod 對外提供服務
收縮的過程可能要等待幾分鐘;
通過上圖可以看到,Pod 副本數不是一下子回收,而是逐步的回收機制。
這是 Dashboard 介面情況
到此 Pod 水平自動擴縮測試就到此結束了,HPA 不僅僅這些,還有多項度量指標和自定義度量指標自動擴縮等策略等著你去實踐。