本文已超過一年。較舊的文章可能包含過時的內容。請檢查頁面中的資訊自發布以來是否已變得不正確。
節點優雅關閉功能進入 Beta 階段
節點正常關機,在 1.21 版本中為 Beta 版,使 kubelet 能夠在節點關機期間正常驅逐 Pod。
Kubernetes 是一個分散式系統,因此我們需要為不可避免的故障做好準備 — 節點將會故障、容器可能會崩潰或重新啟動,並且 - 理想情況下 - 您的工作負載將能夠承受這些災難性事件。
常見的問題類別之一是節點關機或重新啟動時的工作負載故障。在關閉節點之前,最佳實務是安全地排空和隔離您的節點。這將確保在此節點上執行的所有 Pod 都可以安全地被驅逐。驅逐將確保您的 Pod 可以遵循預期的Pod 終止生命週期,這表示在您的容器中接收 SIGTERM 和/或執行 preStopHooks
。
在 Kubernetes 1.20 之前(當時正常節點關機是作為 Alpha 功能引入的),安全節點排空並不容易:它需要使用者手動採取行動並事先排空節點。如果有人或某物在未先排空節點的情況下關閉了您的節點,則您的 Pod 很可能無法從您的節點安全地驅逐,並且會突然關機。與這些 Pod 通訊的其他服務可能會因 Pod 突然退出而看到錯誤。這種情況的一些範例可能是由於安全性修補程式或短期雲端運算實例的搶佔而導致的重新啟動。
Kubernetes 1.21 將正常節點關機帶到 Beta 版。正常節點關機讓您可以更控制一些意外的關機情況。透過正常節點關機,kubelet 知道底層系統關機事件,並且可以將這些事件傳播到 Pod,確保容器可以盡可能正常地關機。這讓容器有機會檢查點其狀態或釋放回它們持有的任何資源。
請注意,為了獲得最佳可用性,即使使用正常節點關機,您仍然應該將您的部署設計為能夠承受節點故障。
它是如何運作的?
在 Linux 上,您的系統可以在許多不同的情況下關機。例如
- 使用者或腳本執行
shutdown -h now
或systemctl poweroff
或systemctl reboot
。 - 物理性地按下機器上的電源按鈕。
- 停止雲端供應商上的 VM 實例,例如 GCP 上的
gcloud compute instances stop
。 - 您的雲端供應商可以意外終止搶佔式 VM 或 Spot Instance,但會發出簡短警告。
許多這些情況可能是意外的,並且無法保證叢集管理員在這些事件之前排空了節點。透過正常節點關機功能,kubelet 使用名為"Inhibitor Locks"的 systemd 機制,以便在大多數情況下允許排空。透過使用 Inhibitor Locks,kubelet 指示 systemd 將系統關機延遲指定的持續時間,讓節點有機會排空並驅逐系統上的 Pod。
Kubelet 利用此機制來確保您的 Pod 將被乾淨地終止。當 kubelet 啟動時,它會取得 systemd delay-type inhibitor lock。當系統即將關機時,kubelet 可以使用它先前取得的 delay-type inhibitor lock 將關機延遲可配置的短時間。這為您的 Pod 提供了額外的時間來終止。因此,即使在意外關機期間,您的應用程式也會收到 SIGTERM,preStop hooks 將會執行,並且 kubelet 將正確地將 Ready
節點條件和各自的 Pod 狀態更新到 API 伺服器。
例如,在啟用正常節點關機的節點上,您可以看到 inhibitor lock 由 kubelet 取得
kubelet-node ~ # systemd-inhibit --list
Who: kubelet (UID 0/root, PID 1515/kubelet)
What: shutdown
Why: Kubelet needs time to handle node shutdown
Mode: delay
1 inhibitors listed.
我們在設計此功能時考慮到一個重要的考量是並非所有 Pod 都是相同的。例如,在節點上執行的一些 Pod(例如與日誌記錄相關的 DaemonSet)應盡可能長時間地保持執行,以便在關機期間捕獲重要的日誌。因此,Pod 分為兩類:“常規”和“關鍵”。關鍵 Pod 是指將 priorityClassName
設定為 system-cluster-critical
或 system-node-critical
的 Pod;所有其他 Pod 都被視為常規 Pod。
在我們的範例中,日誌記錄 DaemonSet 將作為關鍵 Pod 執行。在正常節點關機期間,常規 Pod 首先終止,然後是關鍵 Pod。例如,這將允許與日誌記錄 DaemonSet 關聯的關鍵 Pod 繼續運作,並在終止常規 Pod 期間收集日誌。
我們將在 Beta 階段評估是否需要針對不同的 Pod 優先順序類別提供更大的彈性,並在需要時新增支援,如果您有任何情境,請告訴我們。
我該如何使用它?
正常節點關機由 GracefulNodeShutdown
功能閘道 控制,並且預設在 Kubernetes 1.21 中啟用。
您可以使用兩個 kubelet 組態選項來組態正常節點關機行為:ShutdownGracePeriod
和 ShutdownGracePeriodCriticalPods
。若要組態這些選項,您可以編輯透過 --config
標誌傳遞給 kubelet 的 kubelet 組態檔案;如需更多詳細資訊,請參閱透過組態檔案設定 kubelet 參數。
在關機期間,kubelet 分兩個階段終止 Pod。您可以組態每個階段持續多長時間。
- 終止在節點上執行的常規 Pod。
- 終止在節點上執行的關鍵 Pod。
控制關機持續時間的設定為
ShutdownGracePeriod
- 指定節點應延遲關機的總持續時間。這是常規 Pod 和關鍵 Pod 的 Pod 終止總寬限期。
ShutdownGracePeriodCriticalPods
- 指定在節點關機期間用於終止關鍵 Pod 的持續時間。這應該小於
ShutdownGracePeriod
。
- 指定在節點關機期間用於終止關鍵 Pod 的持續時間。這應該小於
例如,如果 ShutdownGracePeriod=30s
且 ShutdownGracePeriodCriticalPods=10s
,則 kubelet 將延遲節點關機 30 秒。在此期間,前 20 秒 (30-10) 將保留用於正常終止常規 Pod,而最後 10 秒將保留用於終止關鍵 Pod。
請注意,預設情況下,上述兩個組態選項 ShutdownGracePeriod
和 ShutdownGracePeriodCriticalPods
都設定為零,因此您需要根據您的環境適當地組態它們才能啟用正常節點關機功能。
我如何能瞭解更多資訊?
我該如何參與?
隨時歡迎您的意見反應!SIG Node 定期舉行會議,可以透過 Slack(頻道 #sig-node
)或 SIG 的郵件列表聯繫