天天看點

如何優雅的維護 K8S Worker 節點

當我們要進行 K8S 節點維護時往往需要執行 <code>kubectl drain</code>, 等待節點上的 Pod 被驅逐後再進行維護動作。

指令行如下:

待節點排空後再進行維護操作, 核心更新等。

<code>drain</code> 指令有一個問題, 他不會考慮資源所定義的 UpdateStrategy, 而直接強制驅逐或删除 Pod, 這樣就會導緻 Deployment 或 StatefulSet 資源的 Pod 達不到所設定的政策數.

有一個 Deployment 資源, 它使用了如下配置

副本數為 3, 采用了滾動更新, 并且先啟動完成一個 Pod 後再進行舊 Pod 的删除(最大不可用為0,最小可用為2).

當下叢集有 2 個 worker 節點

意味着, 其中一個節點被排程了 2 個 Pod, 其中一個節點被排程了 1 個 Pod.

假設 node1 運作着 pod1 和 pod3, node2 運作着 pod2.

這時候 drain node1, 會出現 Deployment 隻有一個 Pod 可用

Deployment 的 Pod 全部運作在需要維護的節點上, 這時候執行 <code>drain</code> 那将是一個災難, 這個 Deployment 在新的Pod啟動之前它無法在對外提供服務了, 恢複的時間取決于新 Pod 的啟動速度。

GitHub: https://github.com/majian159/kubectl-safe-drain

一個 kubectl 插件, 用于更為安全的排空節點。

對于 Deployment 和 StatefulSet 資源會根據其配置的更新政策先将Pod排程到其它可用節點。

先将需要排空的節點标記為不可排程 (kubectl cordon)

在找到該節點上的 Deployment 和 StatefulSet 資源

修改 Deployment 和 StatefulSet 的 PodTemplate, 讓K8S根據對應的更新政策重新部署Pod, 這時候需要排空的節點不可被排程, 進而達到先将排空節點中的Pod安全重建到其它節點的邏輯。

Deployment

StatefulSet

操作前有兩個可用 Pod

如何優雅的維護 K8S Worker 節點
如何優雅的維護 K8S Worker 節點
如何優雅的維護 K8S Worker 節點
如何優雅的維護 K8S Worker 節點
如何優雅的維護 K8S Worker 節點

從 Deployment watch 的資訊中可見最小 Ready 數沒有小于 2, 從 Pod watch 的資訊中可見 kind-worker2 上承載了 2 個準備就緒的 nginx Pod, 也就是說 nginx 從 kind-worker 安全的移動到了 kind-worker2 節點上。

PDB 隻會保障 Pod 不被驅逐, 而不會幫助它在其它可用節點上重建。

使用了 PDB 後能防止服務不可用的尴尬情況,但它還是需要人工手動遷移 Pod。

理想的情況是搭配 PDB 使用, 防止嚴苛情況下服務不可用的問題。

https://github.com/majian159/kubectl-safe-drain/releases/download/v0.0.1-preview1/kubectl-safe-drain_0.0.1-preview1_windows_amd64.tar.gz

考慮節點親和力和節點選擇器的情況

輸出更為友好的提示資訊

該項目部分代碼源于 kubectl 項目。