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

介紹 Suspended Jobs

Jobs 是 Kubernetes API 的一個重要組成部分。雖然其他型別的工作負載,例如 DeploymentsReplicaSetsStatefulSetsDaemonSets 解決了需要 Pod 永久執行的用例,但當 Pod 需要執行完成時,Jobs 非常有用。Jobs 通常用於並行批處理,可用於各種應用程式,從影片渲染和資料庫維護到傳送批次電子郵件和科學計算。

雖然 Job 完成的並行度和條件是可配置的,但 Kubernetes API 缺乏暫停和恢復 Job 的能力。當叢集資源有限,並且更高優先順序的 Job 需要取代另一個 Job 執行時,通常需要這種能力。刪除低優先順序的 Job 是一種糟糕的變通方法,因為 Pod 完成歷史記錄和與 Job 相關的其他指標都將丟失。

隨著 Kubernetes 1.21 版本的釋出,您將能夠透過更新 Job 的 spec 來暫停 Job。該功能目前處於 alpha 階段,需要您在 API 伺服器控制器管理器上啟用 SuspendJob Feature Gate 才能使用它。

API 變更

我們在 Job 的 .spec 中引入了一個新的布林欄位 suspend。假設我建立了以下 Job:

apiVersion: batch/v1
kind: Job
metadata:
  name: my-job
spec:
  suspend: true
  parallelism: 2
  completions: 10
  template:
    spec:
      containers:
      - name: my-container
        image: busybox
        command: ["sleep", "5"]
      restartPolicy: Never

預設情況下,Jobs 不會暫停,因此我在上述 Job 清單的 .spec 中明確將 suspend 欄位設定為 true。在上面的示例中,Job 控制器將避免建立 Pod,直到我準備好啟動 Job,我可以透過將 suspend 更新為 false 來實現。

再舉一個例子,考慮一個建立時省略了 suspend 欄位的 Job。Job 控制器將樂於建立 Pod 以完成 Job。但是,在 Job 完成之前,如果我透過 Job 更新將該欄位明確設定為 true,Job 控制器將終止所有正在執行的活躍 Pod,並將無限期地等待該標誌翻轉回 false。通常,Pod 終止是透過向 Pod 中的所有容器程序傳送 SIGTERM 訊號來完成的;Pod spec 中定義的優雅終止期將得到遵守。以這種方式終止的 Pod 不會被 Job 控制器計為失敗。

重要的是要理解,暫停 Job 後,過去已成功和失敗的 Pod 將繼續存在。也就是說,一旦您恢復 Job,它們將計入 Job 的完成。您可以透過檢視暫停前後 Job 的狀態來驗證這一點。

閱讀文件以全面瞭解此新功能。

這有什麼用?

假設我是一個大型叢集的運營商。我有許多使用者向叢集提交 Jobs,但並非所有 Jobs 都是平等的——有些 Jobs 比其他 Jobs 更重要。叢集資源也不是無限的,因此所有使用者都必須共享資源。如果所有 Jobs 都以暫停狀態建立並放入待處理佇列中,我可以透過按正確順序恢復 Jobs 來實現基於優先順序的 Job 排程。

另一個激勵性的用例是,考慮一個雲計算提供商,其計算資源在晚上比早上便宜。如果我有一個需要多天才能完成的長時間執行的 Job,每天早上暫停 Job,然後在晚上恢復 Job 可以降低成本。

由於此欄位是 Job 規範的一部分,因此 CronJobs 也自動免費獲得了此功能。

參考資料和下一步

如果您對該功能背後的原理和我們所做的決定感興趣,可以閱讀增強提案。有關Job文件中暫停和恢復 Job 的更多詳細資訊。

如前所述,此功能目前處於 alpha 階段,僅當您透過 SuspendJob 功能門明確選擇啟用時才可用。如果您對此功能感興趣,請考慮在您的叢集中測試暫停的 Job 並提供反饋。您可以在 GitHub 上討論此增強功能。SIG Apps 社群也定期開會,可以透過 Slack 或郵件列表聯絡。除非 API 發生意外更改,否則我們打算在 Kubernetes 1.22 中將該功能升級到 beta 版,以便該功能預設可用。