VPA 的三個元件#
VPA 主要由三個元件組成,分別負責「觀察」、「重啟」與「注入」三件事:
- Recommender
- 觀察 Pod 的資源使用情形並計算預估值。
- 參考歷史指標,給出建議的
requests/limits。
- Updater
- 把需要更新的 Pod 驅逐(因為 Request/Limit 變更必須重啟容器)。
- 當
updatePolicy.updateMode: Auto時,只要 Recommender 給出新建議就會觸發 Updater 行動。
- Admission Controller
- 在 Updater 把 Pod 驅逐、Deployment 準備重新建立時,透過 Webhook 介入。
- 在新的 Pod 啟動前,把更新後的
requests/limits注入進去。
三個元件互相搭配,才能把「重新計算建議 → 重啟 Pod → 套用新的資源設定」這條路走通。
安裝 VPA#
由於 Kubernetes 內建 API 只支援 HPA,使用 VPA 或 Cluster Autoscaler 等需要以 Custom Resource 的形式另外安裝。
下載官方 autoscaler repo 並進入 VPA 目錄:
git clone git@github.com:kubernetes/autoscaler.git
cd ./autoscaler/vertical-pod-autoscaler執行安裝腳本:
./hack/vpa-up.sh安裝過程中會建立 CRD、RBAC、ServiceAccount,以及 vpa-recommender、vpa-updater、vpa-admission-controller 三個 Deployment。
在 macOS 上,安裝過程可能因為系統內建的 LibreSSL 不支援
-addext參數而失敗,看到類似unknown option -addext的錯誤訊息。這時要先把剛剛裝的部分卸下來,再升級 OpenSSL/LibreSSL。
先卸載:
./hack/vpa-down.sh安裝較新的 LibreSSL,並把新版本放到 PATH 前面:
brew install libressl
echo 'export PATH="/opt/homebrew/opt/libressl/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc再次執行安裝:
./hack/vpa-up.sh確認三個 VPA 元件都跑起來:
kubectl get pods -n kube-system | grep vpavpa-admission-controller-667dd5b58-jsftm 1/1 Running 0 84s
vpa-recommender-5f48d76d7-g7x6m 1/1 Running 0 85s
vpa-updater-6fc5699544-wrvhb 1/1 Running 0 85s確認 CRD 已註冊:
kubectl api-resources | grep vpaverticalpodautoscalercheckpoints vpacheckpoint autoscaling.k8s.io/v1 true VerticalPodAutoscalerCheckpoint
verticalpodautoscalers vpa autoscaling.k8s.io/v1 true VerticalPodAutoscaler實戰練習#
測試用 Deployment#
這個範例的容器會週期性大量耗用 CPU,方便我們觀察 VPA 的推薦值:
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hamster
namespace: default
spec:
selector:
matchLabels:
app: hamster
replicas: 1
template:
metadata:
labels:
app: hamster
spec:
containers:
- name: hamster
image: k8s.gcr.io/ubuntu-slim:0.1
resources:
requests:
cpu: 100m
memory: 50Mi
limits:
cpu: 2000m
memory: 2Gi
command: ["/bin/sh"]
args:
- "-c"
- "while true; do timeout 0.2s yes >/dev/null; sleep 0.5s; done"對應的 VPA 設定#
# vpa.yaml
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: hamster-vpa
namespace: default
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: hamster
updatePolicy:
updateMode: "Off"
resourcePolicy:
containerPolicies:
- containerName: "*"
minAllowed:
cpu: 100m
memory: 50Mi
maxAllowed:
cpu: 1
memory: 500Mi
controlledResources: ["cpu", "memory"]幾個重要欄位:
spec.updatePolicy.updateModeOff:VPA 只給推薦值,不會自動修改任何設定。Initial:只在 Pod 建立時套用推薦值,後續不會再自動調整。Auto:完全交給 Recommender,自動套用推薦值。Recreate:類似Auto,但每次都以 recreate 方式重啟 Pod(使用情境較少)。
spec.resourcePolicy.containerPoliciescontainerName:套用範圍,*代表 Pod 內所有容器。minAllowed/maxAllowed:可調整的下限與上限。controlledResources:要監控的資源指標,目前可選 cpu 與 memory。
部署:
kubectl apply -f ./deployment.yaml -f ./vpa.yaml查看推薦結果#
kubectl get vpaNAME MODE CPU MEM PROVIDED AGE
hamster-vpa Auto 379m 262144k True 2m58s進一步看推薦細節:
kubectl describe vpa hamster-vpa擷取重點輸出:
Status:
Conditions:
Last Transition Time: 2022-08-28T10:03:36Z
Status: True
Type: RecommendationProvided
Recommendation:
Container Recommendations:
Container Name: hamster
Lower Bound:
Cpu: 204m
Memory: 262144k
Target:
Cpu: 379m
Memory: 262144k
Uncapped Target:
Cpu: 379m
Memory: 262144k
Upper Bound:
Cpu: 1
Memory: 500MiStatus.Recommendation 中幾個值的意義:
Lower Bound:當 Pod 的 Request 小於此值時,VPA 會把 Pod 刪除並重建。Upper Bound:當 Pod 的 Request 大於此值時,VPA 會把 Pod 刪除並重建。Target:在minAllowed與maxAllowed範圍內的最終推薦值,用來讓容器以最佳狀態執行。Uncapped Target:完全不受minAllowed/maxAllowed約束時的推薦值。
移除 VPA 模組#
./hack/vpa-down.sh小結#
各種 Autoscaler 能幫我們省下不少不必要的資源浪費,HPA 與 VPA 也可以結合使用。但要特別注意:使用「非外部指標」的 HPA 會跟 VPA 的 Auto 模式互相打架,造成不可預期的結果。實務上比較穩妥的做法是 HPA 搭配 VPA 的 Off 模式——讓 VPA 只負責提供推薦值,作為人工調整 Request/Limit 時的參考。
原文出處#
- GitHub:https://github.com/MikeHsu0618/2022-ithelp/tree/main/Day27
- iThome:https://ithelp.ithome.com.tw/articles/10299462