本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。
Kubernetes 1.31: Job 的 Pod 故障策略進入 GA 階段
這篇博文介紹了 **Pod 故障策略**,該策略在 Kubernetes 1.31 中升級為穩定版,以及如何在你的 Job 中使用它。
關於 Pod 故障策略
當你在 Kubernetes 上執行工作負載時,Pod 可能會因各種原因而失敗。理想情況下,像 Job 這樣的工作負載應該能夠忽略瞬態、可重試的故障並繼續執行直至完成。
為了允許這些瞬態故障,Kubernetes Job 包含 `backoffLimit` 欄位,該欄位允許你指定在 Job 執行期間願意容忍的 Pod 故障次數。但是,如果你為 `backoffLimit` 欄位設定一個大值,並且僅依賴此欄位,你可能會注意到操作成本不必要地增加,因為 Pod 會過度重啟,直到達到 `backoffLimit` 為止。
當執行具有數千個長時間執行的 Pods 的大規模 Job 跨數千個節點時,這變得尤為棘手。
Pod 故障策略透過以下方式擴充套件了退避限制機制,幫助你降低成本:
- 一旦發生不可重試的 Pod 故障,即可控制 Job 失敗。
- 允許你忽略可重試錯誤,而無需增加 `backoffLimit` 欄位。
例如,你可以使用 Pod 故障策略,透過忽略優雅節點關機導致的 Pod 故障,在更經濟的 Spot 虛擬機器上執行你的工作負載。
該策略允許你根據容器退出程式碼或失敗 Pod 中的 Pod 條件區分可重試和不可重試的 Pod 故障。
工作原理
你在 Job 規範中指定 Pod 故障策略,表示為規則列表。
對於定義的每個規則,你根據以下屬性之一定義**匹配要求**:
- 容器退出程式碼:`onExitCodes` 屬性。
- Pod 條件:`onPodConditions` 屬性。
此外,對於每個規則,你指定以下操作之一,以便在 Pod 匹配規則時執行:
Ignore
:不將故障計入 `backoffLimit` 或 `backoffLimitPerIndex`。FailJob
:使整個 Job 失敗並終止所有正在執行的 Pod。FailIndex
:使與失敗 Pod 對應的索引失敗。此操作與每個索引的退避限制功能配合使用。Count
:將故障計入 `backoffLimit` 或 `backoffLimitPerIndex`。這是預設行為。
當正在執行的 Job 中發生 Pod 故障時,Kubernetes 會按照指定的順序,將失敗 Pod 的狀態與 Pod 故障策略規則列表進行匹配,並對第一個匹配的規則執行相應的操作。
請注意,在指定 Pod 故障策略時,你還必須將 Job 的 Pod 模板設定為 `restartPolicy: Never`。這可以防止 kubelet 和 Job 控制器在計算 Pod 故障時出現競爭條件。
Kubernetes 啟動的 Pod 中斷
為了允許將 Pod 故障策略規則與 Kubernetes 啟動的中斷導致的故障進行匹配,此功能引入了 `DisruptionTarget` Pod 條件。
Kubernetes 會向任何因可重試的中斷場景而失敗的 Pod 新增此條件,無論該 Pod 是否由 Job 控制器管理。`DisruptionTarget` 條件包含以下與這些中斷場景對應的原因之一:
PreemptionByKubeScheduler
:`kube-scheduler` 為了容納更高優先順序的 Pod 而搶佔。DeletionByTaintManager
- Pod 將因 `kube-controller-manager` 刪除,因為 Pod 不容忍 `NoExecute` 汙點。EvictionByEvictionAPI
- Pod 將因API 啟動的驅逐而被刪除。DeletionByPodGC
- Pod 繫結到一個不再存在的節點,並將因Pod 垃圾回收而被刪除。TerminationByKubelet
- Pod 因優雅節點關機、節點壓力驅逐或系統關鍵 Pods 的搶佔而終止。
在所有其他中斷場景中,例如因超出 Pod 容器限制而導致的驅逐,Pod 不會收到 `DisruptionTarget` 條件,因為中斷很可能是由 Pod 引起的,並且在重試時會再次發生。
示例
以下 Pod 故障策略程式碼片段演示了一個示例用法:
podFailurePolicy:
rules:
- action: Ignore
onPodConditions:
- type: DisruptionTarget
- action: FailJob
onPodConditions:
- type: ConfigIssue
- action: FailJob
onExitCodes:
operator: In
values: [ 42 ]
在此示例中,Pod 故障策略執行以下操作:
- 忽略任何具有內建 `DisruptionTarget` 條件的失敗 Pod。這些 Pod 不計入 Job 的退避限制。
- 如果任何失敗的 Pod 具有自定義使用者提供的 `ConfigIssue` 條件(由自定義控制器或 webhook 新增),則 Job 失敗。
- 如果任何容器以退出程式碼 42 退出,則 Job 失敗。
- 所有其他 Pod 故障都計入預設的 `backoffLimit`(如果使用 `backoffLimitPerIndex`,則計入 `backoffLimitPerIndex`)。
瞭解更多
- 有關使用 Pod 故障策略的實踐指南,請參閱使用 Pod 故障策略處理可重試和不可重試的 Pod 故障
- 閱讀有關Pod 故障策略和每個索引的退避限制的文件
- 閱讀有關Pod 中斷條件的文件
- 閱讀Pod 故障策略的 KEP
相關工作
基於 Pod 故障策略引入的概念,以下額外工作正在進行中:
- JobSet 整合:可配置的故障策略 API
- Pod 故障策略擴充套件,以新增更精細的故障原因
- 透過 JobSet 在Kubeflow Training v2 中支援 Pod 故障策略
- 提案:應從端點中移除中斷的 Pod
參與其中
這項工作由批處理工作組贊助,並與 SIG Apps、SIG Node 和 SIG Scheduling 社群密切合作。
如果你有興趣在該領域開發新功能,我們建議你訂閱我們的 Slack 頻道並參加定期的社群會議。
致謝
我要感謝這些年來參與這個專案的每一個人——這是一個漫長的旅程,也是一項共同的社群努力!下面的列表是我盡力回憶和表彰那些做出貢獻的人。謝謝大家!
- Aldo Culquicondor 在整個過程中給予指導和評論
- Jordan Liggitt 進行 KEP 和 API 審查
- David Eads 進行 API 審查
- Maciej Szulik 從 SIG Apps 角度進行 KEP 審查
- Clayton Coleman 提供指導和 SIG Node 審查
- Sergey Kanzhelev 從 SIG Node 角度進行 KEP 審查
- Dawn Chen 從 SIG Node 角度進行 KEP 審查
- Daniel Smith 從 SIG API 機制角度進行審查
- Antoine Pelisse 從 SIG API 機制角度進行審查
- John Belamaric 進行 PRR 審查
- Filip Křepinský 從 SIG Apps 角度進行全面審查和錯誤修復
- David Porter 從 SIG Node 角度進行全面審查
- Jensen Lo 參與早期需求討論、測試和問題報告
- Daniel Vega-Myhre 推動 JobSet 整合和問題報告
- Abdullah Gharaibeh 參與早期設計討論和指導
- Antonio Ojea 進行測試審查
- Yuki Iwai 進行審查並協調相關 Job 功能的實現
- Kevin Hannon 進行審查並協調相關 Job 功能的實現
- Tim Bannister 進行文件審查
- Shannon Kularathna 進行文件審查
- Paola Cortés 進行文件審查