垂直 Pod 自動擴展

在 Kubernetes 中,VerticalPodAutoscaler (垂直 Pod 自動擴縮器) 會自動更新工作負載管理資源(例如 DeploymentStatefulSet),旨在根據實際使用量自動調整基礎架構資源請求 (Requests) 與限制 (Limits)

垂直擴縮意味著當資源需求增加時,對應的方式是為該工作負載已經在執行的 Pod 分配更多資源(例如:記憶體或 CPU)。這也稱為適度調整 (Rightsizing),有時也稱為自動駕駛 (Autopilot)。這與水平擴縮不同,水平擴縮在 Kubernetes 中是指部署更多 Pod 來分配負載。

如果資源使用量減少,且 Pod 資源請求超過了最佳水準,VerticalPodAutoscaler 會指示工作負載資源(Deployment、StatefulSet 或其他類似資源)調低資源請求,以防止資源浪費。

VerticalPodAutoscaler 是作為一個 Kubernetes API 資源和一個控制器來實作的。該資源決定了控制器的行為。垂直 Pod 自動擴縮控制器在 Kubernetes 資料平面中執行,它會基於對歷史資源利用率、叢集中可用資源量以及即時事件(例如記憶體不足 (OOM) 狀況)的分析,定期調整其目標(例如 Deployment)的資源請求和限制。

API 物件

VerticalPodAutoscaler 在 Kubernetes 中被定義為自訂資源定義 (CRD)。與作為核心 Kubernetes API 一部分的 HorizontalPodAutoscaler 不同,VPA 必須在您的叢集中單獨安裝。

目前的穩定 API 版本為 autoscaling.k8s.io/v1。有關 VPA 安裝和 API 的更多詳細資訊,可以在 VPA GitHub 儲存庫中找到。

VerticalPodAutoscaler 是如何運作的?

Vertical Pod Autoscaling architecture

圖 1. VerticalPodAutoscaler 控制 Deployment 中 Pod 的資源請求與限制

Kubernetes 透過多個協作的組件來實現垂直 Pod 自動擴縮,這些組件會間歇性地執行(這不是一個連續的過程)。VPA 由三個主要組件組成:

  • 推薦器 (Recommender):分析資源使用情況並提供建議。
  • 更新器 (Updater):透過驅逐 Pod 或在原地修改 Pod 來更新資源請求。
  • 以及 VPA 准入控制器 (Admission Controller) Webhook,它會將資源建議應用於新建立或重建的 Pod。

在每個週期中,Recommender 會查詢由每個 VerticalPodAutoscaler 定義所目標的 Pod 的資源利用率。Recommender 會找到由 targetRef 定義的目標資源,然後根據目標資源的 .spec.selector 標籤選擇 Pod,並從資源度量 API 取得指標,以分析實際的 CPU 和記憶體消耗。

Recommender 會分析每個被 VerticalPodAutoscaler 目標 Pod 的當前及歷史資源使用數據(CPU 和記憶體)。它會檢查:

  • 隨時間變化的歷史消耗模式,以識別趨勢
  • 峰值使用量與變異數,以確保有足夠的餘裕
  • 記憶體不足 (OOM) 事件與其他與資源相關的事故

基於此分析,Recommender 會計算三種類型的建議:

  • 目標建議 (Target recommendation)(針對典型使用量的最佳資源)
  • 下限 (Lower bound)(最小可行資源)
  • 上限 (Upper bound)(最大合理資源)。

這些建議會儲存在 VerticalPodAutoscaler 資源的 .status.recommendation 欄位中。

更新器 (Updater) 組件會監控 VerticalPodAutoscaler 資源,並將當前的 Pod 資源請求與建議進行比較。當差異超過配置的閾值且更新策略允許時,更新器可以:

  • 驅逐 Pod,觸發其以新的資源請求進行重建(傳統方法)
  • 在叢集支援原地 Pod 資源更新時,不驅逐 Pod 而直接在原地更新 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)

Off (關閉) 更新模式下,VPA 推薦器仍會分析資源使用情況並產生建議,但這些建議不會自動應用於 Pod。建議僅儲存在 VPA 物件的 .status 欄位中。

您可以使用諸如 kubectl 之類的工具來查看 .status 及其中的建議。

初始化 (Initial)

Initial (初始化) 模式下,VPA 僅在 Pod 首次建立時設定資源請求。即使建議隨時間推移而變化,它也不會更新已經在執行的 Pod 的資源。這些建議僅在 Pod 建立期間應用。

重建 (Recreate)

Recreate (重建) 模式下,VPA 會透過在當前資源請求與建議有顯著差異時驅逐 Pod,來主動管理 Pod 資源。當 Pod 被驅逐時,工作負載控制器(管理 Deployment、StatefulSet 等)會建立一個替換 Pod,並且 VPA 准入控制器會將更新後的資源請求應用於新 Pod。

就地或重建 (InPlaceOrRecreate)

InPlaceOrRecreate 模式下,VPA 會嘗試在不重新啟動 Pod 的情況下更新 Pod 資源請求和限制(如果可行)。然而,如果無法針對特定的資源變更執行原地更新,VPA 會退回到驅逐 Pod(類似於 Recreate 模式),並允許工作負載控制器建立一個帶有更新後資源的替換 Pod。

在此模式下,更新器會使用原地調整容器資源 (Resize Container Resources In-Place) 功能原地應用建議。

自動 (Auto) (已棄用)

注意

Auto 更新模式自 VPA 1.4.0 版本起已被棄用。請使用 Recreate 進行基於驅逐的更新,或使用 InPlaceOrRecreate 進行帶有驅逐回退的原地更新。

Auto 模式目前是 Recreate 模式的別名,其行為完全相同。它的引入是為了允許未來自動更新策略的擴展。

資源策略 (Resource policies)

資源策略允許您微調 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

minAllowed 與 maxAllowed

這些欄位設定了 VPA 建議的界限。VPA 永遠不會建議低於 minAllowed 或高於 maxAllowed 的資源,即使實際使用數據顯示應有不同的值。

controlledResources

controlledResources 欄位指定 VPA 應為 Pod 中的容器管理哪些資源類型。如果未指定,VPA 預設會同時管理 CPU 和記憶體。您可以限制 VPA 僅管理特定資源。有效的資源名稱包括 cpumemory

受控值 (controlledValues)

controlledValues 欄位決定 VPA 是控制資源請求、限制,還是兩者皆控制:

RequestsAndLimits
VPA 同時設定請求和限制。限制會根據 Pod 規格中定義的請求與限制比率,與請求按比例進行擴縮。這是預設模式。
RequestsOnly
VPA 僅設定請求,而不更動限制。限制會被遵守,如果使用量超過限制,仍可能觸發節流 (Throttling) 或記憶體不足殺死 (Out-of-memory kills)。

請參閱請求與限制以了解更多關於這兩個概念的資訊。

LimitRange 資源

准入控制器和更新器 VPA 組件會對建議進行後處理,以符合 LimitRanges 中定義的約束。Kubernetes 叢集中會檢查類型為 Pod 和 Container 的 LimitRange 資源。

例如,如果超過了 Container LimitRange 資源中的 max 欄位,兩個 VPA 組件都會將限制降低到 max 欄位中定義的值,並按比例減少請求,以維持 Pod 規格中的請求與限制比率。

接下來

如果您在叢集中配置了自動擴縮,您可能還需要考慮使用節點自動擴縮,以確保您執行的是正確數量的節點。您還可以閱讀關於水平 Pod 自動擴縮的更多資訊。


最後修改日期:2026 年 1 月 28 日 上午 10:39 (PST):新增圖說並參考圖表中的 Mermaid 原始碼 (5be933e662)