本文已超過一年。較舊的文章可能包含過時的內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

Kubernetes 1.27:Kubernetes Pod 的就地資源調整大小(Alpha 版)

如果您已部署指定 CPU 和/或記憶體資源的 Kubernetes Pod,您可能已經注意到,變更資源值需要重新啟動 Pod。對於運行的工作負載來說,這一直是一個破壞性操作...直到現在。

在 Kubernetes v1.27 中,我們新增了一個新的 Alpha 功能,允許使用者調整分配給 Pod 的 CPU/記憶體資源大小,而無需重新啟動容器。為了方便這一點,Pod 容器中的 resources 欄位現在允許對 cpumemory 資源進行變更。只需修補運行的 Pod Spec 即可變更它們。

這也意味著 Pod Spec 中的 resources 欄位不再能作為 Pod 實際資源的指標。監控工具和其他此類應用程式現在必須查看 Pod 狀態中的新欄位。Kubernetes 透過 CRI(容器執行階段介面)API 呼叫到執行階段(例如 containerd)來查詢在運行容器上強制執行的實際 CPU 和記憶體請求和限制,containerd 負責運行容器。來自容器執行階段的回應會反映在 Pod 的狀態中。

此外,還新增了一個新的用於調整大小的 restartPolicy。它可以讓使用者控制在調整資源大小時如何處理他們的容器。

v1.27 中的新功能?

除了在 Pod Spec 中新增調整大小策略外,Pod 狀態中的 containerStatuses 中還新增了一個名為 allocatedResources 的新欄位。此欄位反映了分配給 Pod 容器的節點資源。

此外,容器狀態中還新增了一個名為 resources 的新欄位。此欄位反映了容器執行階段報告的在運行容器上配置的實際資源請求和限制。

最後,Pod 狀態中新增了一個名為 resize 的新欄位,以顯示上次請求調整大小的狀態。值為 Proposed 表示已確認請求的調整大小,並指示請求已驗證並記錄。值為 InProgress 表示節點已接受調整大小請求,並且正在將調整大小請求應用於 Pod 的容器。值為 Deferred 表示目前無法授予請求的調整大小,並且節點將持續重試。當其他 Pod 離開並釋放節點資源時,可能會授予調整大小。值為 Infeasible 是一個訊號,表示節點無法容納請求的調整大小。如果請求的調整大小超過節點永遠可以為 Pod 分配的最大資源,則可能會發生這種情況。

何時使用此功能

以下是一些可能可以使用此功能的範例

  • Pod 正在節點上運行,但資源過多或過少。
  • 由於叢集中 CPU 或記憶體不足,而運行的 Pod 過度配置而導致 Pod 無法排程。
  • 當節點中其他較低優先順序的 Pod 可以縮減大小或移動時,驅逐某些需要更多資源才能將其排程在較大節點上的有狀態 Pod 是一項昂貴或破壞性的操作。

如何使用此功能

為了在 v1.27 中使用此功能,必須啟用 InPlacePodVerticalScaling 功能閘道。可以使用如下所示的方式啟動啟用此功能的本機叢集

root@vbuild:~/go/src/k8s.io/kubernetes# FEATURE_GATES=InPlacePodVerticalScaling=true ./hack/local-up-cluster.sh
go version go1.20.2 linux/arm64
+++ [0320 13:52:02] Building go targets for linux/arm64
    k8s.io/kubernetes/cmd/kubectl (static)
    k8s.io/kubernetes/cmd/kube-apiserver (static)
    k8s.io/kubernetes/cmd/kube-controller-manager (static)
    k8s.io/kubernetes/cmd/cloud-controller-manager (non-static)
    k8s.io/kubernetes/cmd/kubelet (non-static)
...
...
Logs:
  /tmp/etcd.log
  /tmp/kube-apiserver.log
  /tmp/kube-controller-manager.log

  /tmp/kube-proxy.log
  /tmp/kube-scheduler.log
  /tmp/kubelet.log

To start using your cluster, you can open up another terminal/tab and run:

  export KUBECONFIG=/var/run/kubernetes/admin.kubeconfig
  cluster/kubectl.sh

Alternatively, you can write to the default kubeconfig:

  export KUBERNETES_PROVIDER=local

  cluster/kubectl.sh config set-cluster local --server=https://localhost:6443 --certificate-authority=/var/run/kubernetes/server-ca.crt
  cluster/kubectl.sh config set-credentials myself --client-key=/var/run/kubernetes/client-admin.key --client-certificate=/var/run/kubernetes/client-admin.crt
  cluster/kubectl.sh config set-context local --cluster=local --user=myself
  cluster/kubectl.sh config use-context local
  cluster/kubectl.sh

一旦本機叢集啟動並運行,Kubernetes 使用者就可以排程具有資源的 Pod,並透過 kubectl 調整 Pod 的大小。以下示範影片說明了如何使用此功能。

範例使用案例

基於雲端的開發環境

在這種情況下,開發人員或開發團隊在本機編寫程式碼,但在 Kubernetes Pod 中使用反映生產用途的一致配置來建構和測試他們的程式碼。當開發人員編寫程式碼時,此類 Pod 需要最少的資源,但在他們建構程式碼或運行一系列測試時,則需要顯著更多的 CPU 和記憶體。此使用案例可以利用就地 Pod 調整大小功能(在 eBPF 的少量協助下)來快速調整 Pod 的資源大小,並避免核心 OOM(記憶體不足)終結程式終止其進程。

這個 KubeCon North America 2022 會議演講 說明了這個使用案例。

Java 進程初始化 CPU 需求

某些 Java 應用程式在初始化期間可能需要比正常進程運作時間更多的 CPU。如果此類應用程式指定適合正常運作的 CPU 請求和限制,它們可能會遭受非常長的啟動時間。此類 Pod 可以在建立 Pod 時請求更高的 CPU 值,並且一旦應用程式完成初始化,就可以縮減大小以滿足正常的運行需求。

已知問題

此功能在 v1.27 中進入 Alpha 階段。以下是使用者可能會遇到的一些已知問題

  • 低於 v1.6.9 的 containerd 版本沒有此功能的完整端對端操作所需的 CRI 支援。調整 Pod 大小的嘗試似乎卡在 InProgress 狀態,並且 Pod 狀態中的 resources 欄位永遠不會更新,即使新資源可能已在運行容器上實施。
  • Pod 調整大小可能會遇到與其他 Pod 更新的競爭條件,導致 Pod 調整大小的延遲實施。
  • 在 Pod 狀態中反映調整大小的容器資源可能需要一些時間。
  • 此功能不支援靜態 CPU 管理策略。

致謝

此功能是 Kubernetes 社群共同努力的成果。在此特別感謝許多付出無數時間並協助實現這一目標的人們。

  • @thockin 進行注重細節的 API 設計和嚴謹的程式碼審查。
  • @derekwaynecarr 簡化設計以及徹底的 API 和節點審查。
  • @dchen1107 從 Borg 帶來了廣泛的知識,並幫助我們避免了陷阱。
  • @ruiwen-zhao 新增了 containerd 支援,實現了完整的 E2E 實作。
  • @wangchen615 實作了全面的 E2E 測試並推動了排程器修復。
  • @bobbypage 在準備 CI 以及快速調查問題方面提供了寶貴的幫助,並在我休假期間為我分擔工作。
  • @Random-Liu 進行了徹底的 kubelet 審查,並識別出有問題的競爭條件。
  • @Huang-Wei@ahg-g@alculquicondor 協助完成排程器變更。
  • @mikebrow @marosset 在短時間內進行審查,幫助 CRI 變更進入 v1.25。
  • @endocrimes@ehashman 協助確保經常被忽略的測試處於良好狀態。
  • @mrunalp 審查 cgroupv2 變更並確保乾淨地處理 v1 與 v2。
  • @liggitt@gjkim42 追蹤並找出合併後遺漏的重要問題的根本原因。
  • @SergeyKanzhelev 在最後階段支援和引導各種問題。
  • @pdgetrf 將第一個原型變為現實。
  • @dashpole 讓我快速了解「Kubernetes 的做事方式」。
  • @bsalamat@kgolab 在早期階段提供了非常有見地的見解和建議。
  • @sftim@tengqm 確保文件易於理解。
  • @dims 無所不在,並協助在關鍵時刻實現合併。
  • 發佈團隊確保專案保持健康。

並非常感謝我的非常支持的管理層 Dr. Xiaoning DingDr. Ying Xiong 的耐心和鼓勵。

參考文獻

適用於應用程式開發人員

適用於叢集管理員