Concepts - Workload Management - Jobs
什麼是 Job?
在 Kubernetes (K8s) 中,我們常用的 Deployment 或 StatefulSet 物件追求的是「持續運行」,它們會確保指定數量的 Pod 一直處於服務狀態。
而 Job 則完全不同,它追求的是「最終完成」。Job 會建立一個或多個 Pod,並確保其中指定數量的 Pod 能夠成功執行到結束 (Exit Code 0)。一旦達到預期的成功數量,Job 就會宣告完成,並且不會再建立新的 Pod。
Job 非常適合用來執行一次性或批次性的任務,例如:
- 資料庫遷移 (Database Migration)
- 批次資料處理與分析
- 備份或還原操作
- CI/CD 流程中的建置或測試任務
重要:在 Job 的 Pod 模板中,
spec.template.spec.restartPolicy
只能設定為OnFailure
或Never
,而不能是Always
(Deployment 的預設值)。這是因為 Job 的目標是「完成」,而不是「永遠運行」。
Job 的三種運行模式
1. 非並行 Job (Non-parallel Job)
這是最簡單的模式。Job 只會啟動一個 Pod,並在該 Pod 成功結束後宣告完成。如果 Pod 失敗,Job 會根據 restartPolicy
和 backoffLimit
來決定是否重啟它。
|
|
2. 固定完成次數的並行 Job (Parallel Job with a fixed completion count)
這是最常見的批次處理模式。您可以指定 Job 總共需要成功完成多少次 (.spec.completions
),以及最多可以同時運行多少個 Pod (.spec.parallelism
)。
應用場景:假設您有 100 個影片需要轉檔。您可以設定 completions: 100
和 parallelism: 10
,這樣 K8s 就會以 10 個 Pod 並行處理,直到 100 個影片都轉檔成功為止。
|
|
3. 工作佇列模式的並行 Job (Parallel Job with a work queue)
在這種模式下,您不設定 .spec.completions
,只設定 .spec.parallelism
。Job 會持續運行指定數量的並行 Pod,直到其中任何一個 Pod 以成功狀態退出,Job 就會被視為完成。
應用場景:當您的 Pod 需要從一個外部的工作佇列(如 RabbitMQ, SQS)中拉取任務來處理時,就適合使用此模式。Pod 之間需要自行協調,確保同一個任務不會被重複處理。一旦某個 Pod 確認佇列已空並成功退出,整個 Job 就結束了。
|
|
控制 Job 的行為
失敗重試 (.spec.backoffLimit
)
如果 Job 中的 Pod 因故失敗(例如:程式 bug 或暫時性網路問題),Job Controller 會在一段延遲後重新建立 Pod。這個延遲時間是指數級增長的(10s, 20s, 40s, …),最長不超過 6 分鐘。
.spec.backoffLimit
參數定義了整個 Job 可以被標記為「失敗」的重試次數上限。一旦達到這個上限,Job 就會停止重試,並被標記為 Failed
。預設值是 6。
|
|
Pod 失敗策略 (.spec.podFailurePolicy
)
在某些情況下,您可能希望在特定錯誤發生時,立即讓 Job 失敗,而不要等到 backoffLimit
。例如,當 Pod 因為節點映像檔問題而無法啟動時,重試是沒有意義的。
podFailurePolicy
允許您定義一組規則,當 Pod 的失敗符合這些規則時,Job 會立即終止。詳細用法請參考官方文件。
成功策略 (.spec.successPolicy
)
這是一個較新的功能,允許您在滿足特定條件時,提早宣告 Job 成功。例如,在一個並行 Job 中,只要有任意一個 Pod 成功,就可以終止所有其他 Pod 並宣告整個 Job 成功。詳細用法請參考官方文件。
自動清理已完成的 Job
根據預設,Job 和其關聯的 Pod 在完成後會一直保留在叢集中,以便您查看日誌和狀態。這可能會佔用大量空間。
您可以設定 .spec.ttlSecondsAfterFinished
,讓 Job Controller 在 Job 完成(無論成功或失敗)後的一段時間,自動將其刪除。
|
|
Job 是 K8s 中處理非持續性任務的強大工具。在許多情況下,您可能會希望定期執行某個 Job,這時就需要 CronJob 了,我們將在下一篇文章中介紹它。