K8S 1.27 新特性 Pod 無需重啓調整CPU內存資源
如果您已經部署了指定 CPU 或 Memory 資源的 Kubernetes pod,可能已經注意到更改資源值涉及重新啓動 pod。直到現在,這一直是運行工作負載的破壞性操作。
在 Kubernetes v1.27 中,添加了一個新的 alpha 功能,允許用戶在不重啓容器的情況下調整分配給 Pod 的 CPU 或 memory 資源的大小。爲了實現這一點,pod container 中的 resources
字段現在允許對 cpu
和 memory
資源進行更改。可以通過 patch 修改正在運行的 pod spec 來實現。
這也意味着 pod.spec 中 resources
字段不能再作爲 pod 實際資源的指標。監控工具和其他此類應用程序現在必須查看 pod status 中的新字段。Kubernetes 通過 CRI(容器運行時接口)API 調用運行時(例如負責運行容器的 containerd)來查詢實際的 request CPU 和 memory 和 limit。來自容器運行時的響應反映在 pod 的 status 中。
此外,還添加了一個 restartPolicy
字段,它使用戶可以控制:在調整資源大小時如何處理容器。
v1.27 有什麼新內容?
除了在 Pod 的 spec 中添加調整大小策略外,還在 Pod 的 status 中添加了一個名爲 allocatedResources
的新字段。containerStatuses
該字段反映了分配給 Pod 容器的節點資源。
此外,一個名爲resources
的新字段已添加到容器的 status 中。該字段反映容器運行時報告的在運行容器上配置的實際資源 request 和 limit。
最後,一個名爲resize
的新字段已添加到 pod 的 status,以顯示上次請求調整大小的狀態。
Proposed
值是對請求的調整大小的確認,並指示該請求已被驗證和記錄。InProgress
值表示節點已接受調整大小請求,並且正在將調整大小請求應用於 pod 的容器。Deferred
值爲表示此時無法授予請求的調整大小,節點將不斷重試。當其他 pod 離開並釋放節點資源時,可以授予調整大小。Infeasible
的值是一個信號,表明該節點無法適應請求的調整大小。如果請求的調整大小超過節點可以爲 pod 分配的最大資源,就會發生這種情況。
何時使用此功能
以下是此功能可能有用的幾個示例:
- Pod 在節點上運行,但資源過多或過少。
- Pod 沒有被調度是因爲集羣中沒有足夠的 CPU 或內存,而集羣中運行的 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(內存不足)killer 終止進程。
在 KubeCon North America 2022 會議演講 中說明了這個用例。
Java 進程初始化 CPU 要求
某些 Java 應用程序在初始化期間可能需要比正常進程操作期間所需的 CPU 多得多的 CPU。如果此類應用程序指定適合正常操作的 CPU 請求和限制,則它們可能會遇到非常長的啓動時間。這樣的 pod 可以在創建 pod 時請求更高的 CPU 值,並且可以在應用程序完成初始化後調整大小以滿足正常運行需要即可。
已知的問題
在 v1.27 中 此功能處於 alpha 階段。以下是用戶可能會遇到的一些已知問題:
- containerd v1.6.9 以下的版本沒有此功能的完整端到端操作所需的 CRI 支持。嘗試調整 pod 的大小似乎會停留在
InProgress
狀態,並且 pod 狀態中的resources
字段永遠不會更新,即使新資源可能已經在正在運行的容器上生效。 - Pod resize 可能會遇到與其他 pod 更新的競爭條件,從而導致延遲執行 pod resize。
- 在 Pod 的狀態中反映調整大小的容器資源可能需要一段時間。
- 此功能不支持靜態 CPU 管理策略。
本文由mdnice多平臺發佈