在 Kubernetes 中,VerticalPodAutoscaler (垂直 Pod 自動擴縮器) 會自動更新工作負載管理資源(例如 Deployment 或 StatefulSet),旨在根據實際使用量自動調整基礎架構資源的請求 (Requests) 與限制 (Limits)。
垂直擴縮意味著當資源需求增加時,對應的方式是為該工作負載已經在執行的 Pod 分配更多資源(例如:記憶體或 CPU)。這也稱為適度調整 (Rightsizing),有時也稱為自動駕駛 (Autopilot)。這與水平擴縮不同,水平擴縮在 Kubernetes 中是指部署更多 Pod 來分配負載。
如果資源使用量減少,且 Pod 資源請求超過了最佳水準,VerticalPodAutoscaler 會指示工作負載資源(Deployment、StatefulSet 或其他類似資源)調低資源請求,以防止資源浪費。
VerticalPodAutoscaler 是作為一個 Kubernetes API 資源和一個控制器來實作的。該資源決定了控制器的行為。垂直 Pod 自動擴縮控制器在 Kubernetes 資料平面中執行,它會基於對歷史資源利用率、叢集中可用資源量以及即時事件(例如記憶體不足 (OOM) 狀況)的分析,定期調整其目標(例如 Deployment)的資源請求和限制。
VerticalPodAutoscaler 在 Kubernetes 中被定義為自訂資源定義 (CRD)。與作為核心 Kubernetes API 一部分的 HorizontalPodAutoscaler 不同,VPA 必須在您的叢集中單獨安裝。
目前的穩定 API 版本為 autoscaling.k8s.io/v1。有關 VPA 安裝和 API 的更多詳細資訊,可以在 VPA GitHub 儲存庫中找到。
圖 1. VerticalPodAutoscaler 控制 Deployment 中 Pod 的資源請求與限制
Kubernetes 透過多個協作的組件來實現垂直 Pod 自動擴縮,這些組件會間歇性地執行(這不是一個連續的過程)。VPA 由三個主要組件組成:
在每個週期中,Recommender 會查詢由每個 VerticalPodAutoscaler 定義所目標的 Pod 的資源利用率。Recommender 會找到由 targetRef 定義的目標資源,然後根據目標資源的 .spec.selector 標籤選擇 Pod,並從資源度量 API 取得指標,以分析實際的 CPU 和記憶體消耗。
Recommender 會分析每個被 VerticalPodAutoscaler 目標 Pod 的當前及歷史資源使用數據(CPU 和記憶體)。它會檢查:
基於此分析,Recommender 會計算三種類型的建議:
這些建議會儲存在 VerticalPodAutoscaler 資源的 .status.recommendation 欄位中。
更新器 (Updater) 組件會監控 VerticalPodAutoscaler 資源,並將當前的 Pod 資源請求與建議進行比較。當差異超過配置的閾值且更新策略允許時,更新器可以:
選擇的方法取決於配置的更新模式、叢集功能以及所需的資源變更類型。在可用時,原地更新可避免 Pod 中斷,但對於哪些資源可以修改可能有限制。更新器會遵循 PodDisruptionBudgets (Pod 中斷預算) 以最小化對服務的影響。
准入控制器 (Admission controller) 作為一個變更 Webhook 運作,它會攔截 Pod 建立請求。它會檢查 Pod 是否由 VerticalPodAutoscaler 目標鎖定,如果是,則在 Pod 建立之前套用建議的資源請求和限制。更具體地說,准入控制器會使用 VerticalPodAutoscaler 資源中 .status.recommendation 區段的「目標建議 (Target recommendation)」作為新的資源請求。准入控制器確保新的 Pod 在啟動時具有適當大小的資源分配,無論它們是在初始部署時、更新器驅逐後,還是由於擴縮操作而建立的。
VerticalPodAutoscaler 需要在叢集中安裝指標來源,例如 Kubernetes 的 Metrics Server 附加元件。VPA 組件會從 metrics.k8s.io API 取得指標。Metrics Server 需要單獨啟動,因為大多數叢集預設不會部署它。有關資源指標的更多資訊,請參閱 Metrics Server。
VerticalPodAutoscaler 支援不同的更新模式,這些模式控制如何以及何時將資源建議應用到您的 Pod。您可以使用 VPA 規格中 updatePolicy 下的 updateMode 欄位來配置更新模式:
---
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: my-app-vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: my-app
updatePolicy:
updateMode: "Recreate" # Off, Initial, Recreate, InPlaceOrRecreate
在 Off (關閉) 更新模式下,VPA 推薦器仍會分析資源使用情況並產生建議,但這些建議不會自動應用於 Pod。建議僅儲存在 VPA 物件的 .status 欄位中。
您可以使用諸如 kubectl 之類的工具來查看 .status 及其中的建議。
在 Initial (初始化) 模式下,VPA 僅在 Pod 首次建立時設定資源請求。即使建議隨時間推移而變化,它也不會更新已經在執行的 Pod 的資源。這些建議僅在 Pod 建立期間應用。
在 Recreate (重建) 模式下,VPA 會透過在當前資源請求與建議有顯著差異時驅逐 Pod,來主動管理 Pod 資源。當 Pod 被驅逐時,工作負載控制器(管理 Deployment、StatefulSet 等)會建立一個替換 Pod,並且 VPA 准入控制器會將更新後的資源請求應用於新 Pod。
在 InPlaceOrRecreate 模式下,VPA 會嘗試在不重新啟動 Pod 的情況下更新 Pod 資源請求和限制(如果可行)。然而,如果無法針對特定的資源變更執行原地更新,VPA 會退回到驅逐 Pod(類似於 Recreate 模式),並允許工作負載控制器建立一個帶有更新後資源的替換 Pod。
在此模式下,更新器會使用原地調整容器資源 (Resize Container Resources In-Place) 功能原地應用建議。
Auto 更新模式自 VPA 1.4.0 版本起已被棄用。請使用 Recreate 進行基於驅逐的更新,或使用 InPlaceOrRecreate 進行帶有驅逐回退的原地更新。Auto 模式目前是 Recreate 模式的別名,其行為完全相同。它的引入是為了允許未來自動更新策略的擴展。
資源策略允許您微調 VerticalPodAutoscaler 如何產生建議及應用更新。您可以為資源建議設定界限、指定要管理的資源,並為 Pod 內的各個容器配置不同的策略。
您可以在 VPA 規格的 resourcePolicy 欄位中定義資源策略:
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: my-app-vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: my-app
updatePolicy:
updateMode: "Recreate"
resourcePolicy:
containerPolicies:
- containerName: "application"
minAllowed:
cpu: 100m
memory: 128Mi
maxAllowed:
cpu: 2
memory: 2Gi
controlledResources:
- cpu
- memory
controlledValues: RequestsAndLimits
這些欄位設定了 VPA 建議的界限。VPA 永遠不會建議低於 minAllowed 或高於 maxAllowed 的資源,即使實際使用數據顯示應有不同的值。
controlledResources 欄位指定 VPA 應為 Pod 中的容器管理哪些資源類型。如果未指定,VPA 預設會同時管理 CPU 和記憶體。您可以限制 VPA 僅管理特定資源。有效的資源名稱包括 cpu 和 memory。
controlledValues 欄位決定 VPA 是控制資源請求、限制,還是兩者皆控制:
請參閱請求與限制以了解更多關於這兩個概念的資訊。
准入控制器和更新器 VPA 組件會對建議進行後處理,以符合 LimitRanges 中定義的約束。Kubernetes 叢集中會檢查類型為 Pod 和 Container 的 LimitRange 資源。
例如,如果超過了 Container LimitRange 資源中的 max 欄位,兩個 VPA 組件都會將限制降低到 max 欄位中定義的值,並按比例減少請求,以維持 Pod 規格中的請求與限制比率。
如果您在叢集中配置了自動擴縮,您可能還需要考慮使用節點自動擴縮,以確保您執行的是正確數量的節點。您還可以閱讀關於水平 Pod 自動擴縮的更多資訊。