k8s中如何實(shí)現(xiàn)pod自動擴(kuò)縮容詳解
k8s應(yīng)用自動擴(kuò)縮容概述
為什么要自動擴(kuò)縮容
在實(shí)際的業(yè)務(wù)場景中,我們經(jīng)常會遇到某個服務(wù)需要擴(kuò)容的場景(例如:測試對服務(wù)壓測、電商平臺秒殺、大促活動、或由于資源緊張、工作負(fù)載降低等都需要對服務(wù)實(shí)例數(shù)進(jìn)行擴(kuò)縮容操作)。
擴(kuò)縮容分類
按對象層面
- node擴(kuò)縮容
在使用 kubernetes 集群經(jīng)常問到的一個問題是,我應(yīng)該保持多大的節(jié)點(diǎn)規(guī)模來滿足應(yīng)用需求呢?cluster-autoscaler 的出現(xiàn)解決了這個問題, 可以通過 cluster-autoscaler 實(shí)現(xiàn)節(jié)點(diǎn)級別的動態(tài)添加與刪除,動態(tài)調(diào)整容器資源池,應(yīng)對峰值流量。 - pod層面
我們一般會使用 Deployment 中的 replicas 參數(shù),設(shè)置多個副本集來保證服務(wù)的高可用,但是這是一個固定的值,比如我們設(shè)置 10 個副本,就會啟 10 個 pod 同時 running 來提供服務(wù)。
如果這個服務(wù)平時流量很少的時候,也是 10 個 pod 同時在 running,而流量突然暴增時,又可能出現(xiàn) 10 個 pod 不夠用的情況。針對這種情況怎么辦?就需要自動擴(kuò)縮容。
按方式分類
- 手動模式::通過 kubectl scale 命令,這樣需要每次去手工操作一次,而且不確定什么時候業(yè)務(wù)請求量就很大了,所以如果不能做到自動化的去擴(kuò)縮容的話,這也是一個很麻煩的事情。
- 自動模式:
1、kubernetes HPA(Horizontal Pod Autoscaling):根據(jù)監(jiān)控指標(biāo)(cpu 使用率、磁盤、自定義的等)自動擴(kuò)容或縮容服務(wù)中的pod數(shù)量,當(dāng)業(yè)務(wù)需求增加時,系統(tǒng)將無縫地自動增加適量 pod 容器,提高系統(tǒng)穩(wěn)定性。
2、kubernetes KPA(Knative Pod Autoscaler):基于請求數(shù)對 Pod 自動擴(kuò)縮容,KPA 的主要限制在于它不支持基于 CPU 的自動擴(kuò)縮容。
3、kubernetes VPA(Vertical Pod Autoscaler):基于 Pod 的資源使用情況自動設(shè)置 pod 的 CPU 和內(nèi)存的 requests,從而讓集群將 Pod 調(diào)度到有足夠資源的最佳節(jié)點(diǎn)上。
如何實(shí)現(xiàn)自動擴(kuò)縮容
HPA運(yùn)作方式
- 整體邏輯:K8s 的 HPA controller 已經(jīng)實(shí)現(xiàn)了一套簡單的自動擴(kuò)縮容邏輯,默認(rèn)情況下,每 15s 檢測一次指標(biāo),只要檢測到了配置 HPA 的目標(biāo)值,則會計(jì)算出預(yù)期的工作負(fù)載的副本數(shù),再進(jìn)行擴(kuò)縮容操作。同時,為了避免過于頻繁的擴(kuò)縮容,默認(rèn)在 5min 內(nèi)沒有重新擴(kuò)縮容的情況下,才會觸發(fā)擴(kuò)縮容。
- 缺陷:HPA 本身的算法相對比較保守,可能并不適用于很多場景。例如,一個快速的流量突發(fā)場景,如果正處在 5min 內(nèi)的 HPA 穩(wěn)定期,這個時候根據(jù) HPA 的策略,會導(dǎo)致無法擴(kuò)容。
- pod數(shù)量計(jì)算方式:通過現(xiàn)有 pods 的 CPU 使用率的平均值(計(jì)算方式是最近的 pod 使用量(最近一分鐘的平均值,從 metrics-server 中獲得)除以設(shè)定的每個 Pod 的 CPU 使用率限額)跟目標(biāo)使用率進(jìn)行比較,并且在擴(kuò)容時,還要遵循預(yù)先設(shè)定的副本數(shù)限制:MinReplicas <= Replicas <= MaxReplicas。
計(jì)算擴(kuò)容后 Pod 的個數(shù):sum(最近一分鐘內(nèi)某個 Pod 的 CPU 使用率的平均值)/CPU 使用上限的整數(shù)+1
指標(biāo)信息來源
K8S 從 1.8 版本開始,各節(jié)點(diǎn)CPU、內(nèi)存等資源的 metrics 信息可以通過 Metrics API 來獲取,用戶可以直接獲取這些 metrics 信息(例如通過執(zhí)行 kubect top 命令),HPA 使用這些 metics 信息來實(shí)現(xiàn)動態(tài)伸縮。
部署HPA實(shí)現(xiàn)pod自動擴(kuò)縮容
基于1.23.1版kubernetes
HPA官網(wǎng):https://kubernetes.io/zh/docs/tasks/run-application/horizontal-pod-autoscale/
數(shù)據(jù)采集組件metrics-server
概述
metrics-server 是一個集群范圍內(nèi)的資源數(shù)據(jù)集和工具,同樣的,metrics-server 也只是顯示數(shù)據(jù),并不提供數(shù)據(jù)存儲服務(wù),主要關(guān)注的是資源度量 API 的實(shí)現(xiàn),比如 CPU、文件描述符、內(nèi)存、請求延時等指標(biāo),metric-server 收集數(shù)據(jù)給 k8s 集群內(nèi)使用,如 kubectl,hpa,scheduler 等。
github地址:https://github.com/kubernetes-sigs/metrics-server/
不同k8s版本根據(jù)官網(wǎng)安裝對應(yīng)版本的metrics-server
部署
1、鏡像下載
所用鏡像可提前自行下載:registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server:v0.6.1
2、導(dǎo)入鏡像
docker load -i metrics-server-0.6.1.tar.gz
3、修改apiserver配置
注意:會中斷業(yè)務(wù),生產(chǎn)環(huán)境謹(jǐn)慎操作!
這個是 k8s 在 1.17 的新特性,如果是 1.16 版本的可以不用添加,1.17 以后要添加。這個參數(shù)的作用是 Aggregation 允許在不修改 Kubernetes 核心代碼的同時擴(kuò)展 Kubernetes API。
vim /etc/kubernetes/manifests/kube-apiserver.yaml
增加如下內(nèi)容:
- --enable-aggregator-routing=true
添加后的效果如下圖所示:
修改完成后重啟kubelet
systemctl restart kubelet
4、部署metrics-server 服務(wù)
kubectl apply -f components.yaml
用到的yaml文件到github下載,地址:https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.6.1/components.yaml
5、驗(yàn)證metrics-server是否部署成功
kubectl get pods -n kube-system | grep metrics
可以看到pod處于Running狀態(tài):
kubectl top nodes # 查看各節(jié)點(diǎn)資源使用情況
kubectl top pods -n kube-system # 查看kube-system名稱空間下pod資源使用情況
測試環(huán)境準(zhǔn)備
創(chuàng)建php-apache服務(wù)
1、鏡像準(zhǔn)備
使用 dockerfile 構(gòu)建一個新的鏡像,在 k8s 的 xuegod63 節(jié)點(diǎn)構(gòu)建
mkdir php cd php vim dockerfile
dockerfile內(nèi)容如下:
FROM php:5-apache ADD index.php /var/www/html/index.php RUN chmod a+rx index.php
創(chuàng)建index.php文件,內(nèi)容如下:
<?php $x = 0.0001; for ($i = 0; $i <= 1000000;$i++) { $x += sqrt($x); } echo "OK!"; ?>
docker build -t k8s.gcr.io/hpa-example:v1 . # 構(gòu)建鏡像 docker save -o hpa-example.tar.gz k8s.gcr.io/hpa-example:v1 # 打包鏡像 scp hpa-example.tar.gz xuegod64:/root/ # 將鏡像傳到工作節(jié)點(diǎn)
在工作節(jié)點(diǎn)導(dǎo)入鏡像:
docker load -i hpa-example.tar.gz
2、通過 deployment 部署一個 php-apache 服務(wù)
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: k8s.gcr.io/hpa-example:v1 imagePullPolicy: IfNotPresent 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
kubectl apply -f php-apache.yaml # 更新資源清單文件 kubectl get pods # 驗(yàn)證 php 是否部署成功
創(chuàng)建nginx服務(wù)
1、通過deployment部署一個nginx服務(wù)
cat nginx.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-hpa spec: selector: matchLabels: app: nginx replicas: 1 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.9.1 imagePullPolicy: IfNotPresent ports: - containerPort: 80 name: http protocol: TCP resources: requests: cpu: 0.01 memory: 25Mi limits: cpu: 0.05 memory: 60Mi --- apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: selector: app: nginx type: NodePort ports: - name: http protocol: TCP port: 80 targetPort: 80 nodePort: 30080
注意:nginx 的 pod 里需要有如下字段,否則 hpa 會采集不到內(nèi)存指標(biāo)
resources: requests: cpu: 0.01 memory: 25Mi limits: cpu: 0.05 memory: 60Mi
創(chuàng)建資源并查看:
kubectl apply -f nginx.yaml # 更新資源清單 kubectl get pods # 查看pod kubectl get svc # 查看service
HPA基于cpu自動擴(kuò)縮容
php-apache 服務(wù)正在運(yùn)行,使用 kubectl autoscale 創(chuàng)建自動縮放器,實(shí)現(xiàn)對 php-apache 這個deployment 創(chuàng)建的 pod 自動擴(kuò)縮容,下面的命令將會創(chuàng)建一個 HPA,HPA 將會根據(jù) CPU資源指標(biāo)增加或減少副本數(shù),創(chuàng)建一個可以實(shí)現(xiàn)如下目的的 hpa:
(1)讓副本數(shù)維持在 1-10 個之間(這里副本數(shù)指的是通過 deployment 部署的 pod 的副本數(shù))
(2)將所有 Pod 的平均 CPU 使用率維持在 50%(通過 kubectl run 運(yùn)行的每個 pod 如果是 200毫核,這意味著平均 CPU 利用率為 100 毫核)
創(chuàng)建HPA基于cpu自動擴(kuò)縮容
創(chuàng)建:
kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
查看:
kubectl get hpa
可以看到cpu目標(biāo)及當(dāng)前狀態(tài),最大、最小、當(dāng)前副本數(shù)。
壓測php-apache服務(wù),看擴(kuò)容
重新打開一個master節(jié)點(diǎn)的終端,進(jìn)行如下操作:
kubectl run v1 -it --image=busybox --image-pull-policy=IfNotPresent /bin/sh while true; do wget -q -O- http://php-apache.default.svc.cluster.local; done
在原master終端查看hpa情況:
kubectl get hpa kubectl get pods
可以看到平均cpu使用率達(dá)到了98%,副本數(shù)已經(jīng)變?yōu)?個。
注意:可能需要幾分鐘來穩(wěn)定副本數(shù)。由于不以任何方式控制負(fù)載量,因此最終副本數(shù)可能會與此示例不同。
停止對 php-apache 服務(wù)壓測,看縮容
停止向 php-apache 這個服務(wù)發(fā)送查詢請求,在 busybox 鏡像創(chuàng)建容器的終端中,通過 Ctrl+ C 把剛才 while 請求停止,然后,我們將驗(yàn)證結(jié)果狀態(tài)(大約一分鐘后):
kubectl get hpa
可以看到平均cpu使用率降為0%,副本數(shù)降為1。
HPA基于內(nèi)存自動擴(kuò)縮容
nginx 服務(wù)正在運(yùn)行,使用 kubectl autoscale 創(chuàng)建自動縮放器,實(shí)現(xiàn)對 nginx 這個deployment 創(chuàng)建的 pod 自動擴(kuò)縮容,下面的命令將會創(chuàng)建一個 HPA,HPA 將會根據(jù)內(nèi)存資源指標(biāo)增加或減少副本數(shù),創(chuàng)建一個可以實(shí)現(xiàn)如下目的的 hpa:
(1)讓副本數(shù)維持在 1-10 個之間(這里副本數(shù)指的是通過 deployment 部署的 pod 的副本數(shù))
(2)將所有 Pod 的平均內(nèi)存使用率維持在 60%
創(chuàng)建HPA基于內(nèi)存自動擴(kuò)縮容
hpa-v1.yaml 內(nèi)容如下:
apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: nginx-hpa spec: maxReplicas: 10 minReplicas: 1 scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: nginx-hpa metrics: - type: Resource resource: name: memory target: type: Utilization averageUtilization: 60
kubectl apply -f hpa-v1.yaml # 更新資源清單 kubectl get hpa nginx-hpa # 查看創(chuàng)建的hpa
可以看到當(dāng)前內(nèi)存使用率、目標(biāo)內(nèi)存使用率,最大、最小、當(dāng)前副本數(shù)。
壓測nginx服務(wù),看擴(kuò)容
使用master節(jié)點(diǎn)的終端2登錄到上面通過 pod 創(chuàng)建的 nginx,并生成一個文件,增加內(nèi)存
kubectl exec -it nginx-hpa-7f5d6fbfd9-4d95f -- /bin/bash dd if=/dev/zero of=/tmp/a
使用終端1查看hpa情況:
kubectl get hpa nginx-hpa
可以看到平均內(nèi)存使用率達(dá)到了238%,,副本數(shù)達(dá)到了4個。
取消壓測,看縮容
到終端2使用 Ctrl + C 中斷dd進(jìn)程,刪除/tmp/a這個文件
rm -rf /tmp/a
在終端1查看hpa的情況:
kubectl get hpa nginx-hpa
可以看到平均內(nèi)存使用率已經(jīng)降到5%,副本數(shù)也降為1。(需要等幾分鐘才能看到)
kubernetes cluster-autoscaler概述
什么是 cluster-autoscaler呢?
Cluster Autoscaler (CA)是一個獨(dú)立程序,是用來彈性伸縮 kubernetes 集群的。它可以自動根據(jù)部署應(yīng)用所請求的資源量來動態(tài)的伸縮集群。當(dāng)集群容量不足時,它會自動去 Cloud Provider (支持GCE、GKE 和 AWS)創(chuàng)建新的 Node,而在 Node 長時間資源利用率很低時自動將其刪除以節(jié)省開支。
項(xiàng)目地址:https://github.com/kubernetes/autoscaler
Cluster Autoscaler 什么時候伸縮集群?
在以下情況下,集群自動擴(kuò)容或者縮放:
擴(kuò)容:由于資源不足,某些 Pod 無法在任何當(dāng)前節(jié)點(diǎn)上進(jìn)行調(diào)度。
縮容: Node 節(jié)點(diǎn)資源利用率較低時,且此 node 節(jié)點(diǎn)上存在的 pod 都能被重新調(diào)度到其他 node節(jié)點(diǎn)上運(yùn)行。
什么時候集群節(jié)點(diǎn)不會被 CA 刪除?
1、節(jié)點(diǎn)上有 pod 被 PodDisruptionBudget 控制器限制。
2、節(jié)點(diǎn)上有命名空間是 kube-system 的 pods。
3、節(jié)點(diǎn)上的 pod 不是被控制器創(chuàng)建,例如不是被 deployment, replica set, job, stateful set 創(chuàng)建。
4、節(jié)點(diǎn)上有 pod 使用了本地存儲。
5、節(jié)點(diǎn)上 pod 驅(qū)逐后無處可去,即沒有其他 node 能調(diào)度這個 pod。
6、節(jié)點(diǎn)有注解:“cluster-autoscaler.kubernetes.io/scale-down-disabled”: “true”(在 CA 1.0.3 或更高版本中受支持)。
kubectl annotate node <nodename> cluster-autoscaler.kubernetes.io/scale-down-disabled=true
HPA 如何與 Cluster Autoscaler 一起使用?
Horizontal Pod Autoscaler 會根據(jù)當(dāng)前 CPU 負(fù)載更改部署或副本集的副本數(shù)。如果負(fù)載增加,則 HPA 將創(chuàng)建新的副本,集群中可能有足夠的空間,也可能沒有足夠的空間。如果沒有足夠的資源,CA將嘗試啟動一些節(jié)點(diǎn),以便 HPA 創(chuàng)建的 Pod 可以運(yùn)行。如果負(fù)載減少,則 HPA 將停止某些副本。結(jié)果,某些節(jié)點(diǎn)可能變得利用率過低或完全為空,然后 CA 將終止這些不需要的節(jié)點(diǎn)。
Cluster Autoscaler 支持那些云廠商?
- GCE https://kubernetes.io/docs/concepts/cluster-administration/cluster-management/
- GKE https://cloud.google.com/container-engine/docs/cluster-autoscaler
- AWS(亞馬遜) https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md
- Azure(微軟) https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/azure/README.md
- Alibaba Cloud https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/alicloud/README.md
- OpenStack Magnum https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/magnum/README.md
- DigitalOcean https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/digitalocean/README.md
- CloudStack https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/cloudstack/README.md
- Exoscale https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/exoscale/README.md
- Packet https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/packet/README.md
- OVHcloud https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/ovhcloud/README.md
- Linode https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/linode/README.md
- Hetzner https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/hetzner/README.md
- Cluster API https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/clusterapi/README.md
總結(jié)
到此這篇關(guān)于k8s中如何實(shí)現(xiàn)pod自動擴(kuò)縮容的文章就介紹到這了,更多相關(guān)k8s實(shí)現(xiàn)pod自動擴(kuò)縮容內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Rainbond功能架構(gòu)及應(yīng)用管理官方文檔介紹
這篇文章主要為大家介紹了Rainbond功能機(jī)構(gòu)及使用官方文檔,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04CentOS?8.2?k8s?基礎(chǔ)環(huán)境配置
這篇文章主要介紹了CentOS?8.2?k8s?基礎(chǔ)環(huán)境配置,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-10-10Rainbond云原生快捷部署生產(chǎn)可用的Gitlab步驟詳解
這篇文章主要為大家介紹了Rainbond云原生快捷部署生產(chǎn)可用的Gitlab步驟詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04CentOS 7.9 升級內(nèi)核 kernel-ml-5.6.14版本的方法
這篇文章主要介紹了CentOS 7.9 升級內(nèi)核 kernel-ml-5.6.14版本,默認(rèn)內(nèi)核版本為3.10.0,現(xiàn)升級到 5.6.14 版本,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-10-10解決k8s namespace 一直處于 Terminating 狀態(tài)的問題
這篇文章主要介紹了k8s namespace 一直處于 Terminating 狀態(tài)的解決方法,以下的 tool 為 Terminating 狀態(tài)的 namespace,下面相關(guān)的一些操作記得將 tool 修改成自己的 namespace 名稱,需要的朋友可以參考下2022-10-10