一文帶你掌握Kubernetes VPA(Pod縱向自動(dòng)擴(kuò)縮)
簡(jiǎn)介
之前的文章我們介紹了HPA(Horizontal Pod Autoscaler)的實(shí)現(xiàn),HPA一般被稱為橫向擴(kuò)展,與HPA不同的Vertical Pod Autoscaler ( VPA ) 會(huì)自動(dòng)調(diào)整 Pod 的 CPU 和內(nèi)存屬性,被稱為縱向擴(kuò)展。VPA可以給出服務(wù)運(yùn)行所適合的CPU和內(nèi)存配置,省去估計(jì)服務(wù)占用資源的時(shí)間,更合理的使用資源。當(dāng)然,VPA也可根據(jù)資源的使用情況“調(diào)整”pod的資源。這里的調(diào)整我們用了雙引號(hào),因?yàn)樗膶?shí)現(xiàn)機(jī)制是重建而不是動(dòng)態(tài)增加。下面是一個(gè)實(shí)際的例子:假設(shè)我的memory limits是100Mi,但是現(xiàn)在已經(jīng)用到了98Mi,如果再大的話就oom了,此時(shí)vpa會(huì)在垂直方向上提升你的memory limits的大小。這種vpa比較適合一些資源消耗比較大的應(yīng)用,例如es,你給大了資源浪費(fèi),給小了,又不夠。所以vpa就派上用場(chǎng)了。當(dāng)然,vpa不像hpa默認(rèn)集成在k8s里面的,需要你自己去配置的。
VPA 與 HPA
從根本上來說,VPA 和 HPA 之間的區(qū)別在于它們的擴(kuò)展方式。HPA 通過添加或刪除pod進(jìn)行擴(kuò)展,從而水平擴(kuò)展容量。然而,VPA 通過增加或減少現(xiàn)有 Pod 容器內(nèi)的 CPU 和內(nèi)存資源來進(jìn)行擴(kuò)展,從而垂直擴(kuò)展容量。下表更詳細(xì)地解釋了 Kubernetes VPA 和 HPA 之間的差異。
需要調(diào)整容量 | 水平縮放 (HPA) | 垂直縮放 (VPA) |
更多資源 | 添加更多 Pod | 增加現(xiàn)有 pod 容器的 CPU 或內(nèi)存資源 |
資源較少 | 刪除 Pod | 減少現(xiàn)有 Pod 容器的 CPU 或內(nèi)存資源 |
工作原理
圖片
VPA 的組成部分
VPA 部署具有三個(gè)主要組件:VPA Recommender、VPA Updater和VPA Admission Controller。讓我們看一下每個(gè)組件的作用。VPA Recommender:
- 監(jiān)控資源利用率并計(jì)算目標(biāo)值。
- 查看指標(biāo)歷史記錄、OOM 事件和 VPA 部署規(guī)范并建議公平請(qǐng)求。根據(jù)定義的限制請(qǐng)求比例提高/降低限制。
VPA 更新程序:
- 驅(qū)逐那些需要新資源限制的 Pod。
- 如果定義了“updateMode: Auto”,則實(shí)現(xiàn)推薦器建議的任何內(nèi)容。
VPA 準(zhǔn)入控制器:
- 每當(dāng) VPA 更新程序逐出并重新啟動(dòng) Pod 時(shí),都會(huì)在新 Pod 啟動(dòng)之前更改 CPU 和內(nèi)存設(shè)置(使用 Webhook)。
- 當(dāng) Vertical Pod Autoscaler 設(shè)置為“Auto”的 updateMode 時(shí),如果需要更改 Pod 的資源請(qǐng)求,則驅(qū)逐 Pod。由于 Kubernetes 的設(shè)計(jì),修改正在運(yùn)行的 pod 的資源請(qǐng)求的唯一方法是重新創(chuàng)建 pod。
Kubernetes VPA 工作模式
圖片
- 用戶配置VPA。
- VPA Recommender 從指標(biāo)服務(wù)器讀取 VPA 配置和資源利用率指標(biāo)。
- VPA Recommender 提供 Pod 資源推薦。
- VPA Updater 讀取 Pod 資源建議。
- VPA Updater 啟動(dòng) Pod 終止。
- 部署意識(shí)到 Pod 已終止,并將重新創(chuàng)建 Pod 以匹配其副本配置。
- 當(dāng) Pod 處于重新創(chuàng)建過程中時(shí),VPA 準(zhǔn)入控制器會(huì)獲取 Pod 資源推薦。由于 Kubernetes 不支持動(dòng)態(tài)更改正在運(yùn)行的 pod 的資源限制,因此 VPA 無法使用新的限制更新現(xiàn)有 pod。它會(huì)終止使用過時(shí)限制的 pod。當(dāng) Pod 的控制器向 Kubernetes API 服務(wù)請(qǐng)求替換時(shí),VPA 準(zhǔn)入控制器會(huì)將更新的資源請(qǐng)求和限制值注入到新 Pod 的規(guī)范中。
- 最后,VPA 準(zhǔn)入控制器會(huì)覆蓋對(duì) Pod 的建議。在我們的示例中,VPA 準(zhǔn)入控制器向 Pod 添加了一個(gè)“250m”CPU。
最佳實(shí)踐
既然你知道了大致原理,讓我們開始動(dòng)手操作你吧
克隆代碼
# git clone https://github.com/kubernetes/autoscaler.git
由于某些原因拉不到鏡像,改yaml修改優(yōu)先使用本地鏡像
# cd autoscaler/vertical-pod-autoscaler/deploy
# sed -i 's/Always/IfNotPresent/g' recommender-deployment.yaml
# sed -i 's/Always/IfNotPresent/g' admission-controller-deployment.yaml
# sed -i 's/Always/IfNotPresent/g' updater-deployment.yaml
# 拉取鏡像
# docker pull giantswarm/vpa-admission-controller:0.14.0
# docker pull giantswarm/vpa-recommender:0.14.0
# docker pull giantswarm/vpa-updater:0.14.0
# 修改tag
# docker tag giantswarm/vpa-updater:0.14.0 registry.k8s.io/autoscaling/vpa-updater:0.14.0
# docker tag giantswarm/vpa-recommender:0.14.0 registry.k8s.io/autoscaling/vpa-recommender:0.14.0
# docker tag giantswarm/vpa-admission-controller:0.14.0 registry.k8s.io/autoscaling/vpa-admission-controller:0.14.0
# cd autoscaler/vertical-pod-autoscaler/hack
# 安裝腳本安裝之前保證你的K8S集群的metrics-server已安裝,并且openssl升級(jí)到1.1.1或更高版本
# ./vpa-up.sh
等待安裝完成
# kubectl get pods -n kube-system | grep vpa
kube-system vpa-admission-controller-75bffbf8d8-6hxqq 1/1 Running 0 5m9s
kube-system vpa-recommender-748c55b5bf-kqqjc 1/1 Running 0 4m34s
kube-system vpa-updater-679d5dcdd6-lslc7 1/1 Running 0 4m15s
使用VPA,您需要為要自動(dòng)計(jì)算資源需求的每個(gè)控制器插入一個(gè)Vertical Pod Autoscaler資源。這將是最常見的Deployment。VPA有四種運(yùn)行模式
- "Auto":VPA 在創(chuàng)建 pod 時(shí)分配資源請(qǐng)求,并使用首選更新機(jī)制在現(xiàn)有 pod 上更新它們。目前這相當(dāng)于"Recreate"(見下文)。一旦 pod 請(qǐng)求的免重啟(“就地”)更新可用,它可能會(huì)被該"Auto"模式用作首選的更新機(jī)制。注意:VPA 的此功能是實(shí)驗(yàn)性的,可能會(huì)導(dǎo)致您的應(yīng)用程序停機(jī),當(dāng)目前運(yùn)行的pod的資源達(dá)不到VPA的推薦值,就會(huì)執(zhí)行pod驅(qū)逐,重新部署新的足夠資源的服務(wù)
- "Recreate":VPA 在創(chuàng)建 Pod 時(shí)分配資源請(qǐng)求,并在現(xiàn)有 Pod 上更新它們,當(dāng)請(qǐng)求的資源與新建議有很大差異時(shí)(尊重 Pod 中斷預(yù)算,如果定義)。這種模式應(yīng)該很少使用,只有當(dāng)您需要確保在資源請(qǐng)求發(fā)生變化時(shí)重新啟動(dòng) Pod 時(shí)。否則,更喜歡這種"Auto"模式,一旦它們可用,就可以利用重新啟動(dòng)免費(fèi)更新。注意:VPA 的此功能是實(shí)驗(yàn)性的,可能會(huì)導(dǎo)致您的應(yīng)用程序停機(jī)
- "Initial":VPA 僅在創(chuàng)建 pod 時(shí)分配資源請(qǐng)求,以后不會(huì)更改它們
- "Off":VPA 不會(huì)自動(dòng)更改 Pod 的資源需求。這些建議是經(jīng)過計(jì)算的,并且可以在 VPA 對(duì)象中進(jìn)行檢查。這種模式僅獲取資源推薦值,但是不更新Pod
創(chuàng)建一個(gè)updateMode: Auto 的VPA
# 將updateMode中的requests 改為 CPU:50m,Memory: 50Mi,同時(shí)將updateMode修改為Auto
# 創(chuàng)建一個(gè)pod和svc
# kubectl get pods -n vpa
NAME READY STATUS RESTARTS AGE
nginx-8454bb78d8-67pth 1/1 Running 0 9s
nginx-8454bb78d8-6efsh 1/1 Running 0 9s
# kubectl get svc -n vpa
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx NodePort 10.0.200.5 <none> 80:45425/TCP 15s
# 進(jìn)行壓測(cè),壓測(cè)到一半時(shí),突然連接斷了,說明POD被重新創(chuàng)建了
# ab -c 1000 -n 100000 http://192.168.0.191:45425/
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 192.168.0.191 (be patient)
apr_socket_recv: Connection reset by peer (104)
Total of 187078 requests completed
# 查看vpa
# kubectl describe vpa nginx-vpa -n vpa | tail -n 20
Conditions:
Last Transition Time: 2023-09-07T15:41:32Z
Status: True
Type: RecommendationProvided
Recommendation:
Container Recommendations:
Container Name: nginx
Lower Bound: #容器的最小估計(jì)值
Cpu: 100m
Memory: 262144k
Target: #目標(biāo)估計(jì)是我們用于設(shè)置資源請(qǐng)求的估計(jì)
Cpu: 350m
Memory: 262144k
Uncapped Target: #無上限目標(biāo)估計(jì)是在沒有minAllowed和maxAllowed限制的情況下產(chǎn)生的目標(biāo)估計(jì)
Cpu: 350m
Memory: 262144k
Upper Bound: #上限是容器的最大建議資源估計(jì)
Cpu: 2
Memory: 405160855
Events: <none>
# 查看pod被重新創(chuàng)建了 稍高的配置
# kubectl get pods -n vpa
NAME READY STATUS RESTARTS AGE
nginx-daecsfv8d8-see8h 1/1 Running 0 4m
nginx-daecsfv8d8-fsise 1/1 Running 0 3m
已知的限制
- 每當(dāng) VPA 更新 Pod 資源時(shí),都會(huì)重新創(chuàng)建 Pod,這會(huì)導(dǎo)致重新創(chuàng)建所有正在運(yùn)行的容器。Pod 可以在不同的節(jié)點(diǎn)上重新創(chuàng)建。
- VPA 無法保證它驅(qū)逐或刪除以應(yīng)用建議(在Auto和Recreate模式下配置時(shí))的 pod 將成功重新創(chuàng)建。通過將 VPA 與Cluster Autoscaler結(jié)合使用可以部分解決這個(gè)問題。
- VPA 不會(huì)更新不在控制器下運(yùn)行的 Pod 的資源。
- 目前,Vertical Pod Autoscaler不應(yīng)與CPU 或內(nèi)存上的Horizontal Pod Autoscaler (HPA)一起使用。但是,您可以在自定義和外部指標(biāo)上將 VPA 與 HPA結(jié)合使用。
- VPA 準(zhǔn)入控制器是一個(gè)準(zhǔn)入 Webhook。如果您將其他準(zhǔn)入 Webhook 添加到集群中,則分析它們?nèi)绾谓换ヒ约八鼈兪欠窨赡芟嗷_突非常重要。準(zhǔn)入控制器的順序由 API 服務(wù)器上的標(biāo)志定義。
- VPA 會(huì)對(duì)大多數(shù)內(nèi)存不足事件做出反應(yīng),但并非在所有情況下都會(huì)做出反應(yīng)。
- VPA 性能尚未在大型集群中進(jìn)行測(cè)試。
- VPA 建議可能會(huì)超出可用資源(例如節(jié)點(diǎn)大小、可用大小、可用配額)并導(dǎo)致Pod 處于掛起狀態(tài)。通過將 VPA 與Cluster Autoscaler結(jié)合使用可以部分解決這個(gè)問題。
- 與同一 Pod 匹配的多個(gè) VPA 資源具有未定義的行為。
總結(jié)
在本文中,我們使用VPA實(shí)現(xiàn)了基于POD對(duì)配置進(jìn)行橫向擴(kuò)展,合理的使用可以提高對(duì)K8S的利用率,實(shí)現(xiàn)降本增效。但是目前的VPA也存在一些問題,我個(gè)人覺得VPA最大的問題是會(huì)對(duì)服務(wù)進(jìn)行重建,重建過程中可能會(huì)有流量損失,但是好消息是從1.27 版本動(dòng)態(tài)調(diào)整容器CPU和內(nèi)存資源限制,無需重啟應(yīng)用程序,在可見的將來,會(huì)實(shí)現(xiàn)動(dòng)態(tài)擴(kuò)容更加順滑,讓我們一起期待~