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

平滑節點關閉功能進入 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 例項,但會提供簡短警告。

這些情況中的許多都是意外的,並且無法保證叢集管理員在這些事件發生之前排空了節點。藉助優雅的節點關機功能,kubelet 使用一種名為 “抑制鎖(Inhibitor Locks)” 的 systemd 機制,以允許在大多數情況下進行排空。使用抑制鎖,kubelet 指示 systemd 將系統關機延遲指定的時間,從而為節點排空並驅逐系統上的 Pod 提供機會。

Kubelet 利用此機制確保您的 Pod 將被幹淨地終止。當 kubelet 啟動時,它會獲取一個 systemd 延遲型別抑制鎖。當系統即將關機時,kubelet 可以利用它之前獲取的延遲型別抑制鎖,將關機延遲可配置的短時間。這為您的 Pod 提供了額外的終止時間。因此,即使在意外關機期間,您的應用程式也會收到 SIGTERM,preStop 鉤子將執行,並且 kubelet 將正確更新 `Ready` 節點條件和相應的 Pod 狀態到 api-server。

例如,在啟用了優雅節點關機的節點上,您可以看到 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。您可以配置每個階段的持續時間。

  1. 終止節點上執行的常規 Pod。
  2. 終止節點上執行的關鍵 Pod。

控制關機持續時間的設定為:

  • ShutdownGracePeriod
    • 指定節點應延遲關機的總持續時間。這是常規 Pod 和關鍵 Pod 終止的總優雅終止期限。
  • ShutdownGracePeriodCriticalPods
    • 指定在節點關機期間終止關鍵 Pod 的持續時間。這應該小於 `ShutdownGracePeriod`。

例如,如果 `ShutdownGracePeriod=30s` 且 `ShutdownGracePeriodCriticalPods=10s`,則 kubelet 將節點關機延遲 30 秒。在此期間,前 20 秒(30-10)將用於優雅地終止普通 Pod,最後 10 秒將用於終止關鍵 Pod。

請注意,預設情況下,上述兩個配置選項 `ShutdownGracePeriod` 和 `ShutdownGracePeriodCriticalPods` 都設定為零,因此您需要根據您的環境進行適當配置以啟用優雅的節點關機功能。

我如何瞭解更多資訊?

我如何參與?

我們始終歡迎您的反饋!SIG Node 定期開會,可以透過 Slack(頻道 ` #sig-node `)或 SIG 的郵件列表聯絡我們