本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。
Kubernetes 1.24:介紹非平滑節點關閉 Alpha
Kubernetes v1.24 引入了對非體面節點關閉的 Alpha 支援。此功能允許有狀態工作負載在原始節點關閉或處於不可恢復狀態(例如硬體故障或作業系統損壞)後,故障轉移到另一個節點。
這與體面節點關閉有何不同
你可能聽說過 Kubernetes 的體面節點關閉功能,並且想知道非體面節點關閉功能與它有何不同。體面節點關閉允許 Kubernetes 檢測到節點何時被幹淨地關閉,並適當地處理這種情況。節點關閉只有在 kubelet 能夠在實際關閉之前檢測到節點關閉操作時,才能是“體面”的。然而,在某些情況下,節點關閉操作可能無法被 kubelet 檢測到。這可能是因為關閉命令沒有觸發 kubelet 所依賴的 systemd 抑制鎖機制,或者是因為配置錯誤(ShutdownGracePeriod
和 ShutdownGracePeriodCriticalPods
未正確配置)。
體面節點關閉依賴於 Linux 特定的支援。kubelet 不會監視 Windows 節點上即將發生的關閉(這在未來的 Kubernetes 版本中可能會改變)。
當一個節點被關閉但 kubelet 沒有檢測到時,該節點上的 Pod 也會非體面地關閉。對於無狀態應用,這通常不是問題(一旦叢集檢測到受影響的節點或 Pod 發生故障,ReplicaSet 就會新增一個新的 Pod)。對於有狀態應用,情況就更復雜了。如果你使用 StatefulSet,並且該 StatefulSet 的一個 Pod 所在節點發生了非乾淨的故障,那麼受影響的 Pod 將被標記為 terminating;StatefulSet 無法建立替換 Pod,因為該 Pod 仍然存在於叢集中。因此,在 StatefulSet 上執行的應用程式可能會降級甚至離線。如果原始的、已關閉的節點再次啟動,原始節點上的 kubelet 會報告狀態,刪除現有的 Pod,然後控制平面會在另一個正在執行的節點上為該 StatefulSet 建立一個替換 Pod。如果原始節點發生故障並且無法啟動,那些有狀態的 Pod 將無限期地卡在故障節點上的 terminating 狀態。
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web-0 1/1 Running 0 100m 10.244.2.4 k8s-node-876-1639279816 <none> <none>
web-1 1/1 Terminating 0 100m 10.244.1.3 k8s-node-433-1639279804 <none> <none>
試用新的非體面關閉處理
要使用非體面節點關閉處理,你必須為 kube-controller-manager
元件啟用 NodeOutOfServiceVolumeDetach
特性門控。
在節點關閉的情況下,你可以手動將該節點標記為停止服務。在新增該汙點之前,你應該確保該節點確實已經關閉(而不是正在重啟中)。你可以在 kubelet 未能提前檢測和處理的關閉之後新增該汙點;另一個可以使用該汙點的情況是節點由於硬體故障或作業系統損壞而處於不可恢復狀態。你可以為該汙點設定的值是 node.kubernetes.io/out-of-service=nodeshutdown:"NoExecute"
或 node.kubernetes.io/out-of-service=nodeshutdown:"NoSchedule"
。只要你啟用了前面提到的特性門控,在節點上設定停止服務汙點意味著該節點上的 Pod 將被刪除,除非 Pod 上有匹配的容忍度。附加到已關閉節點的持久卷將被分離,對於 StatefulSet,替換 Pod 將在另一個正在執行的節點上成功建立。
$ kubectl taint nodes <node-name> node.kubernetes.io/out-of-service=nodeshutdown:NoExecute
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web-0 1/1 Running 0 150m 10.244.2.4 k8s-node-876-1639279816 <none> <none>
web-1 1/1 Running 0 10m 10.244.1.7 k8s-node-433-1639279804 <none> <none>
注意:在應用停止服務汙點之前,你必須驗證一個節點已經處於關閉或斷電狀態(而不是正在重啟中),這可能是因為使用者有意關閉它,或者節點由於硬體故障、作業系統問題等而宕機。
一旦與停止服務節點相關的所有工作負載 Pod 都移動到了一個新的正在執行的節點上,並且關閉的節點已經恢復,你應該在節點恢復後移除受影響節點上的那個汙點。如果你知道該節點不會再恢復服務,你可以從叢集中刪除該節點。
下一步是什麼?
根據反饋和採用情況,Kubernetes 團隊計劃在 1.25 或 1.26 版本中將非體面節點關閉的實現推向 Beta 階段。
此功能需要使用者手動向節點新增汙點以觸發工作負載故障轉移,並在節點恢復後移除該汙點。未來,我們計劃尋找方法來自動檢測和隔離已關閉/故障的節點,並自動將工作負載故障轉移到另一個節點。
我如何瞭解更多資訊?
請檢視非體面節點關閉的文件。
如何參與?
這個特性有著悠久的歷史。Yassine Tijani (yastij) 在兩年多前開始了 KEP 的工作。Xing Yang (xing-yang) 繼續推動這項工作。SIG Storage、SIG Node 和 API 審查人員之間進行了許多討論,以確定設計細節。Ashutosh Kumar (sonasingh46) 完成了大部分實現,並使其在 Kubernetes 1.24 中進入 Alpha 階段。
我們要感謝以下人員的深刻審查:Tim Hockin (thockin) 在設計上的指導,Jing Xu (jingxu97)、Hemant Kumar (gnufied) 和 Michelle Au (msau42) 從 SIG Storage 方面的審查,以及 Mrunal Patel (mrunalp)、David Porter (bobbypage)、Derek Carr (derekwaynecarr) 和 Danielle Endocrimes (endocrimes) 從 SIG Node 方面的審查。
在此過程中,有許多人幫助審查了設計和實現。我們要感謝所有為這項工作做出貢獻的人,包括在過去幾年裡審查了 KEP 和實現的大約 30 個人。
此功能是 SIG Storage 和 SIG Node 之間的合作。對於有興趣參與 Kubernetes 儲存系統任何部分的設計和開發的人,請加入 Kubernetes 儲存特別興趣小組 (SIG)。對於有興趣參與支援 Pod 和主機資源之間受控互動的元件的設計和開發的人,請加入 Kubernetes Node SIG。