Azure Kubernetes Service (AKS) 中的垂直 Pod 自動調整
本文提供 Azure Kubernetes Service (AKS) 中的垂直 Pod 自動調整程式 (VPA) 概觀,其基礎為開放原始碼 Kubernetes 版本。 設定時,其會按照每個工作負載的過去使用量,自動設定容器的資源要求和限制。 VPA 會釋出其他 Pod 的 CPU 和記憶體,並協助有效地利用 AKS 叢集。
垂直 Pod 自動調整提供一段時間的資源使用量建議。 若要管理資源使用量突然增加,請使用水平 Pod 自動調整程式,以視需要調整 Pod 複本數目。
福利
Pod 垂直自動調整程式提供下列優點:
會分析處理器和記憶體資源,調整至適合應用程式的「正確大小」。 VPA 不只負責擴大,也負責根據資源使用量隨著時間縮小。
如果 Pod 的調整模式設定為 [自動] 或 [重新建立],則 Pod 在需要變更其資源要求時即會被收回。
藉由指定資源原則以設定個別容器的 CPU 和記憶體條件約束
確定節點有正確的資源可排程 Pod
處理器或記憶體資源所執行之所有調整的可設定記錄
改善叢集資源使用率,並釋放其他 Pod 的 CPU 和記憶體。
限制
垂直 Pod 自動調整支援每個叢集最多有 1,000 個與
VerticalPodAutoscaler
物件相關聯的 Pod。VPA 所建議的資源可能會多於叢集中的可用資源。 因此,這可防止將 Pod 指派給節點並執行,因為節點的資源不足。 克服此限制的方式是將 LimitRange 設定為每個命名空間的最大可用資源,以確保 Pod 不會要求超過所指定值的資源。 此外,您可以在
VerticalPodAutoscaler
物件中設定每個 Pod 的允許資源建議上限。 請注意,VPA 無法完全克服節點資源不足問題。 限制範圍固定,但節點資源使用量會動態變更。不建議您搭配使用垂直 Pod 自動調整程式與水平 Pod 自動調整程式,這會根據相同的 CPU 和記憶體使用量計量進行調整。
VPA 建議工具最多只會儲存八天的歷程資料。
因為工作負載實際記憶體使用量的可見度有限,所以 VPA 不支援 JVM 型工作負載。
不建議或支援執行您自己的 VPA 實作與這個受控 VPA 實作。 支援額外或自訂建議工具。
不支援 AKS Windows 容器。
開始之前
AKS 叢集執行 Kubernetes 1.24 版及更新的版本。
已安裝並設定 Azure CLI 2.52.0 版或更新版本。 執行
az --version
以尋找版本。 如果您需要安裝或升級,請參閱安裝 Azure CLI。kubectl
應該連線到您想要安裝 VPA 的叢集。
VPA 概觀
API 物件
Pod 垂直自動調整程式是 Kubernetes 自動調整 API 群組中的 API 資源。 所支援的版本是 0.11 和更新版本,而且可以在 Kubernetes 自動調整程式存放庫中找到。
VPA 物件包含三個元件:
建議工具 - 其監視目前和過去的資源耗用量,並根據它來提供容器 CPU 和記憶體要求/限制的建議值。 建議工具會監視計量歷程記錄、「記憶體不足 (OOM)」事件和 VPA 部署規格,並建議公平要求。 提供適當的資源要求和限制設定,即會引發和降低限制。
Updater - 其會檢查哪些受控 Pod 已設定正確的資源,如果未設定,則會予以終止,以讓其控制器使用已更新的要求來將其重新建立。
VPA 許可控制器 - 其會在新 Pod 上設定正確的資源要求 (因 Updater 的活動而由其控制器所建立或重新建立)。
VPA 許可控制器
VPA 許可控制器是一個二進位檔案,可將自己註冊為「變動許可 Webhook」。 建立每個 Pod 之後,會從 apiserver 中取得要求,並評估是否有相符的 VPA 設定,或尋找對應的 VPA 設定,並使用目前的建議以在 Pod 中設定資源要求。
獨立獨立會在 VPA 許可控制器外部執行,稱為 overlay-vpa-cert-webhook-check
。 overlay-vpa-cert-webhook-check
用來建立和續約憑證,並將 VPA 許可控制器註冊為 MutatingWebhookConfiguration
。
針對高可用性,AKS 支援兩個許可控制器複本。
VPA 物件作業模式
針對您想要自動計算資源需求的每個控制器,插入垂直 Pod 自動調整程式資源。 這是最常見的部署。 VPA 可以操作四種模式:
Auto
- VPA 會在 Pod 建立期間指派資源要求,並使用慣用的更新機制來更新現有 Pod。 目前,Auto
相當於Recreate
,也是預設模式。 重新啟動 Pod 要求的免費 (「就地」) 更新之後,可以將其用作Auto
模式的慣用更新機制。 使用Recreate
模式時,如果 VPA 需要變更其資源要求,則會收回 Pod。 這可能會導致同時重新啟動 Pod,進而造成應用程式不一致。 在此情況下,您可以使用 PodDisruptionBudget 來限制重新啟動,並維護一致性。Recreate
- VPA 會在 Pod 建立期間指派資源要求,以及在所要求的資源與新建議明顯不同時收回現有 Pod 來更新現有 Pod (如果已定義,則遵守 Pod 中斷預算)。 只有在您需要確保只要資源要求變更即重新啟動 Pod 時,才應該罕見地使用此模式。 否則,偏好使用Auto
模式,而這可能會在重新啟動免費更新可用之後利用重新啟動免費更新。Initial
- VPA 只會在 Pod 建立期間指派資源要求,之後永遠不會變更。Off
- VPA 不會自動變更 Pod 的資源需求。 系統會計算建議,而且可以在 VPA 物件中進行檢查。
應用程式開發期間的部署模式
如果您不熟悉 VPA,則建議您使用的常見部署模式是在應用程式開發期間執行下列步驟,以識別其唯一資源使用率特性、測試 VPA 以確認其正常運作,並與其他 Kubernetes 元件一起測試以最佳化叢集的資源使用率。
在生產叢集中,設定 UpdateMode = "Off",並以建議模式來執行 VPA,以測試和熟悉 VPA。 UpdateMode = "Off" 可以避免引入可能導致中斷的設定錯誤。
收集所指定時段內的實際資源使用率遙測,以先建立可觀察性。 這可協助您瞭解容器和 Pod 資源徵兆或問題的行為和跡象,而容器和 Pod 資源受到其上所執行的工作負載的影響。
熟悉監視資料以瞭解效能特性。 根據此深入解析,據此設定所需的要求/限制,然後在下次部署或升級中進行設定
根據您的需求,將
updateMode
值設定為Auto
、Recreate
或Initial
。
在叢集上部署、升級或停用 VPA
在本節中,您會在叢集上部署、升級或停用 Pod 垂直自動調整程式。
若要在新叢集上啟用 VPA,請使用
--enable-vpa
參數搭配 az aks create 命令。az aks create -n myAKSCluster -g myResourceGroup --enable-vpa
幾分鐘後,命令會完成並傳回關於叢集的 JSON 格式資訊。
選擇性,若要啟用現有叢集上的 VPA,請搭配使用
--enable-vpa
與 [https://learn.microsoft.com/en-us/cli/azure/aks?view=azure-cli-latest#az-aks-update] 命令。az aks update -n myAKSCluster -g myResourceGroup --enable-vpa
幾分鐘後,命令會完成並傳回關於叢集的 JSON 格式資訊。
選擇性,若要停用現有叢集上的 VPA,請搭配使用
--disable-vpa
與 [https://learn.microsoft.com/en-us/cli/azure/aks?view=azure-cli-latest#az-aks-update] 命令。az aks update -n myAKSCluster -g myResourceGroup --disable-vpa
幾分鐘後,命令會完成並傳回關於叢集的 JSON 格式資訊。
若要驗證已成功建立 Pod 垂直自動調整程式 Pod,請使用 kubectl get 命令。
kubectl get pods -n kube-system
命令輸出包含 VPA Pod 特定的下列結果。 Pod 應該顯示「正在執行」的狀態。
NAME READY STATUS RESTARTS AGE
vpa-admission-controller-7867874bc5-vjfxk 1/1 Running 0 41m
vpa-recommender-5fd94767fb-ggjr2 1/1 Running 0 41m
vpa-updater-56f9bfc96f-jgq2g 1/1 Running 0 41m
測試您的垂直 Pod 自動調整程式安裝
下列步驟會建立包含兩個 Pod 的部署,每個 Pod 會執行一個容器,各容器要求 100 個 millicore 且嘗試使用稍微高於 500 個 millicore。 也會建立指向部署的 VPA 設定。 此 VPA 會觀察 Pod 的行為,並在大約 5 分鐘之後,使用較高的 CPU 要求更新 Pod。
建立名為
hamster.yaml
的檔案,然後將 kubernetes/autoscaler GitHub 存放庫中的下列 Pod 垂直自動調整程式範例資訊清單複製進來。使用 kubectl apply 命令部署
hamster.yaml
Pod 垂直自動調整程式範例並指定 YAML 資訊清單的名稱:kubectl apply -f hamster.yaml
幾分鐘後,命令會完成並傳回關於叢集的 JSON 格式資訊。
執行下列 kubectl get 命令,以從 hamster 範例應用程式取得 Pod:
kubectl get pods -l app=hamster
範例輸出類似下列內容:
hamster-78f9dcdd4c-hf7gk 1/1 Running 0 24s hamster-78f9dcdd4c-j9mc7 1/1 Running 0 24s
對其中一個 Pod 使用 kubectl describe 命令,檢視其 CPU 和記憶體保留。 將 "exampleID" 更換為上一個步驟輸出所傳回的其中一個 Pod 識別碼。
kubectl describe pod hamster-exampleID
範例輸出是叢集相關資訊的程式碼片段:
hamster: Container ID: containerd:// Image: k8s.gcr.io/ubuntu-slim:0.1 Image ID: sha256: Port: <none> Host Port: <none> Command: /bin/sh Args: -c while true; do timeout 0.5s yes >/dev/null; sleep 0.5s; done State: Running Started: Wed, 28 Sep 2022 15:06:14 -0400 Ready: True Restart Count: 0 Requests: cpu: 100m memory: 50Mi Environment: <none>
本範例中的 Pod 保留了 100 millicpu 和 50 Mibibyte 的記憶體。 在此範例應用程式中,Pod 執行需求不超過 100 millicpu,因此沒有可用的 CPU 容量。 Pod 也保留比所需更少的記憶體。 Pod 垂直自動調整程式 vpa-recommender 部署會分析裝載 hamster 應用程式的 Pod,以查看 CPU 和記憶體需求是否恰當。 如果需要調整,vpa-updater 會使用更新後的值重新啟動 Pod。
等候 vpa-updater 啟動新的 hamster Pod,這應該需要幾分鐘的時間。 您可以使用 kubectl get 命令監視 Pod。
kubectl get --watch pods -l app=hamster
啟動新的 hamster Pod 時,請描述執行 kubectl describe 命令的 Pod,並檢視更新後的 CPU 和記憶體保留。
kubectl describe pod hamster-<exampleID>
範例輸出是 Pod 描述資訊的程式碼片段:
State: Running Started: Wed, 28 Sep 2022 15:09:51 -0400 Ready: True Restart Count: 0 Requests: cpu: 587m memory: 262144k Environment: <none>
在前面的輸出中,您可以看到 CPU 保留增加至 587 millicpu,超過原始值的五倍。 記憶體增加至 262,144 KB,約為 250 Mibibyte,或原始值的五倍。 此 Pod 未獲得足夠的資源,Pod 垂直自動調整程式會使用更適當的值更正估計值。
若要檢視更新後的 VPA 建議,請執行 kubectl describe 命令描述 hamster-vpa 資源資訊。
kubectl describe vpa/hamster-vpa
範例輸出是資源使用率相關資訊的程式碼片段:
State: Running Started: Wed, 28 Sep 2022 15:09:51 -0400 Ready: True Restart Count: 0 Requests: cpu: 587m memory: 262144k Environment: <none>
設定 Pod 自動調整程式要求
updateMode 設定為 [自動] 時,垂直 Pod 自動調整會使用 VerticalPodAutoscaler
物件來自動設定 Pod 上的資源要求。根據您的需求和測試,您可以設定不同的值。 在此範例中,updateMode 設定為 Recreate
。
執行下列命令可啟用您叢集的 VPA。 將叢集名稱
myAKSCluster
更換成您 AKS 叢集的名稱,將myResourceGroup
更換成裝載叢集的資源群組名稱。az aks update -n myAKSCluster -g myResourceGroup --enable-vpa
建立名為
azure-autodeploy.yaml
的檔案,然後將下列資訊清單複製進來。apiVersion: apps/v1 kind: Deployment metadata: name: vpa-auto-deployment spec: replicas: 2 selector: matchLabels: app: vpa-auto-deployment template: metadata: labels: app: vpa-auto-deployment spec: containers: - name: mycontainer image: mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine resources: requests: cpu: 100m memory: 50Mi command: ["/bin/sh"] args: ["-c", "while true; do timeout 0.5s yes >/dev/null; sleep 0.5s; done"]
此資訊清單描述具有兩個 Pod 的部署。 每個 Pod 都有一個容器,而此容器會要求 100 milliCPU 和 50 MiB 的記憶體。
使用 kubectl create 命令來建立 Pod,如下列範例所示:
kubectl create -f azure-autodeploy.yaml
幾分鐘後,命令會完成並傳回關於叢集的 JSON 格式資訊。
執行下列 kubectl get 命令取得 Pod:
kubectl get pods
輸出類似下列範例,會顯示 Pod 的名稱和狀態:
NAME READY STATUS RESTARTS AGE vpa-auto-deployment-54465fb978-kchc5 1/1 Running 0 52s vpa-auto-deployment-54465fb978-nhtmj 1/1 Running 0 52s
建立名為
azure-vpa-auto.yaml
的檔案,然後將描述VerticalPodAutoscaler
的下列資訊清單複製進來:apiVersion: autoscaling.k8s.io/v1 kind: VerticalPodAutoscaler metadata: name: vpa-auto spec: targetRef: apiVersion: "apps/v1" kind: Deployment name: vpa-auto-deployment updatePolicy: updateMode: "Recreate"
targetRef.name
值指定名為vpa-auto-deployment
的部署所控制的任何 Pod 都屬於VerticalPodAutoscaler
。Recreate
的updateMode
值表示垂直 Pod 自動調整程式控制器可以刪除 Pod,並調整 CPU 和記憶體要求,然後建立新的 Pod。使用 kubectl apply 命令將資訊清單套用至叢集:
kubectl create -f azure-vpa-auto.yaml
等候幾分鐘,然後執行下列 kubectl get 命令,再次檢視執行中 Pod:
kubectl get pods
輸出類似下列範例,會顯示 Pod 名稱已變更和 Pod 的狀態:
NAME READY STATUS RESTARTS AGE vpa-auto-deployment-54465fb978-qbhc4 1/1 Running 0 2m49s vpa-auto-deployment-54465fb978-vbj68 1/1 Running 0 109s
使用 Kubectl get 命令,取得其中一個執行中 Pod 的詳細資訊。 將
podName
取代為您在上一個步驟中擷取的其中一個 Pod 名稱。kubectl get pod podName --output yaml
輸出類似下列範例,會顯示 Pod 垂直自動調整程式控制器已將記憶體要求增加至 262144k,且 CPU 要求增加到 25 milliCPU。
apiVersion: v1 kind: Pod metadata: annotations: vpaObservedContainers: mycontainer vpaUpdates: 'Pod resources updated by vpa-auto: container 0: cpu request, memory request' creationTimestamp: "2022-09-29T16:44:37Z" generateName: vpa-auto-deployment-54465fb978- labels: app: vpa-auto-deployment spec: containers: - args: - -c - while true; do timeout 0.5s yes >/dev/null; sleep 0.5s; done command: - /bin/sh image: mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine imagePullPolicy: IfNotPresent name: mycontainer resources: requests: cpu: 25m memory: 262144k
若要取得 Pod 垂直自動調整程式的詳細資訊及其 CPU 和記憶體建議,請使用 kubectl get 命令:
kubectl get vpa vpa-auto --output yaml
輸出類似下列範例:
recommendation: containerRecommendations: - containerName: mycontainer lowerBound: cpu: 25m memory: 262144k target: cpu: 25m memory: 262144k uncappedTarget: cpu: 25m memory: 262144k upperBound: cpu: 230m memory: 262144k
結果中顯示的
target
屬性指定以最佳方式執行容器,不需要變更 CPU 或記憶體目標。 當目標 CPU 和記憶體建議較高時,結果可能有所不同。垂直 Pod 自動調整程式會使用
lowerBound
和upperBound
屬性來決定是否刪除 Pod,並將其取代為新的 Pod。 如果 Pod 的要求低於下限或超過上限,則垂直 Pod 自動調整程式會刪除 Pod,並將其取代為符合目標屬性的 Pod。
垂直 Pod 自動調整程式的額外建議工具
在 VPA 中,其中一個核心元件是建議工具。 其根據即時資源耗用量來提供資源使用量建議。 AKS 會在叢集啟用 VPA 時部署建議工具。 您可以部署自訂建議工具,或映像與預設映像相同的額外建議工具。 擁有自訂建議工具的優點是您可以自訂建議邏輯。 使用額外的建議工具時,如果有許多 VPA 物件,則您可以將 VPA 分割為多個建議工具。
下列範例是您套用至現有 AKS 叢集的額外建議工具。 您接著會將 VPA 物件設定為使用額外建議工具。
建立名為
extra_recommender.yaml
的檔案,然後將下列資訊清單複製進來:apiVersion: apps/v1 kind: Deployment metadata: name: extra-recommender namespace: kube-system spec: replicas: 1 selector: matchLabels: app: extra-recommender template: metadata: labels: app: extra-recommender spec: serviceAccountName: vpa-recommender securityContext: runAsNonRoot: true runAsUser: 65534 # nobody containers: - name: recommender image: registry.k8s.io/autoscaling/vpa-recommender:0.13.0 imagePullPolicy: Always args: - --recommender-name=extra-recommender resources: limits: cpu: 200m memory: 1000Mi requests: cpu: 50m memory: 500Mi ports: - name: prometheus containerPort: 8942
使用 kubectl apply 命令來部署
extra-recomender.yaml
垂直 Pod 自動調整程式範例,並指定 YAML 資訊清單的名稱。kubectl apply -f extra-recommender.yaml
幾分鐘後,命令會完成並傳回關於叢集的 JSON 格式資訊。
建立名為
hamnster_extra_recommender.yaml
的檔案,然後將下列資訊清單複製進來:apiVersion: "autoscaling.k8s.io/v1" kind: VerticalPodAutoscaler metadata: name: hamster-vpa spec: recommenders: - name: 'extra-recommender' targetRef: apiVersion: "apps/v1" kind: Deployment name: hamster updatePolicy: updateMode: "Auto" resourcePolicy: containerPolicies: - containerName: '*' minAllowed: cpu: 100m memory: 50Mi maxAllowed: cpu: 1 memory: 500Mi controlledResources: ["cpu", "memory"] --- apiVersion: apps/v1 kind: Deployment metadata: name: hamster spec: selector: matchLabels: app: hamster replicas: 2 template: metadata: labels: app: hamster spec: securityContext: runAsNonRoot: true runAsUser: 65534 # nobody containers: - name: hamster image: k8s.gcr.io/ubuntu-slim:0.1 resources: requests: cpu: 100m memory: 50Mi command: ["/bin/sh"] args: - "-c" - "while true; do timeout 0.5s yes >/dev/null; sleep 0.5s; done"
如果未在
controlledResources
中指定memory
,則建議工具不會回應 OOM 事件。 在此情況下,您只會在controlledValues
中設定 CPU。controlledValues
可讓您選擇透過RequestsOnly
選項來更新容器的資源要求,還是使用RequestsAndLimits
選項來更新資源要求和限制。 預設值是RequestsAndLimits
。 如果您使用 [RequestsAndLimits
] 選項,則會根據實際使用量來計算「要求」,而且根據目前 Pod 的要求和限制比例來計算「限制」。例如,如果您從要求 2 個 CPU 和限制為 4 個 CPU 的 Pod 開始,則 VPA 一律會將限制設定為要求數目的兩倍。 相同的準則適用於記憶體。 當您使用
RequestsAndLimits
模式時,其可以作為初始應用程式資源要求和限制的藍圖。
您可以使用 CPU 和記憶體的自動模式和計算建議來簡化 VPA 物件。
使用 kubectl apply 命令來部署
hamster_extra-recomender.yaml
,並指定 YAML 資訊清單的名稱。kubectl apply -f hamster_customized_recommender.yaml
等候 vpa-updater 啟動新的 hamster Pod,這應該需要幾分鐘的時間。 您可以使用 kubectl get 命令監視 Pod。
kubectl get --watch pods -l app=hamster
啟動新的 hamster Pod 時,請描述執行 kubectl describe 命令的 Pod,並檢視更新後的 CPU 和記憶體保留。
kubectl describe pod hamster-<exampleID>
範例輸出是 Pod 描述資訊的程式碼片段:
State: Running Started: Wed, 28 Sep 2022 15:09:51 -0400 Ready: True Restart Count: 0 Requests: cpu: 587m memory: 262144k Environment: <none>
若要檢視更新後的 VPA 建議,請執行 kubectl describe 命令描述 hamster-vpa 資源資訊。
kubectl describe vpa/hamster-vpa
範例輸出是資源使用率相關資訊的程式碼片段:
State: Running Started: Wed, 28 Sep 2022 15:09:51 -0400 Ready: True Restart Count: 0 Requests: cpu: 587m memory: 262144k Environment: <none> Spec: recommenders: Name: customized-recommender
疑難排解
若要診斷 VPA 安裝問題,請執行下列步驟。
使用下列命令,檢查所有系統元件是否都正在執行:
kubectl --namespace=kube-system get pods|grep vpa
輸出應該會列出三個 Pod - recommender、updater 和 admission-controller,全部都有狀態,以顯示狀態 Running
。
確認系統元件是否記錄任何錯誤。 針對上一個命令所傳回的每個 Pod,執行下列命令:
kubectl --namespace=kube-system logs [pod name] | grep -e '^E[0-9]\{4\}'
執行下列命令,以確認已建立自訂資源定義:
kubectl get customresourcedefinition | grep verticalpodautoscalers
下一步
本文說明如何自動縮放叢集節點的資源使用率,例如 CPU 和記憶體,以符合應用程式需求。
您也可以使用水平 Pod 自動調整程式,自動調整執行應用程式的 Pod 數目。 如需使用水平 Pod 自動調整程式的步驟,請參閱調整 AKS 中的應用程式。
請參閱<垂直 Pod 自動調整程式 [API 參考]>,以深入了解相關 VPA 物件的定義。