在 Kubernetes (K8s) 中,我們常用的 Deployment 或 StatefulSet 物件追求的是「持續運行」,它們會確保指定數量的 Pod 一直處於服務狀態。
而 Job 則完全不同,它追求的是「最終完成」。Job 會建立一個或多個 Pod,並確保其中指定數量的 Pod 能夠成功執行到結束 (Exit Code 0)。一旦達到預期的成功數量,Job 就會宣告完成,並且不會再建立新的 Pod。
Job 非常適合用來執行一次性或批次性的任務,例如:
重要:在 Job 的 Pod 模板中,
spec.template.spec.restartPolicy只能設定為OnFailure或Never,而不能是Always(Deployment 的預設值)。這是因為 Job 的目標是「完成」,而不是「永遠運行」。
這是最簡單的模式。Job 只會啟動一個 Pod,並在該 Pod 成功結束後宣告完成。如果 Pod 失敗,Job 會根據 restartPolicy 和 backoffLimit 來決定是否重啟它。
apiVersion: batch/v1
kind: Job
metadata:
name: pi-calculation
spec:
template:
spec:
containers:
- name: pi
image: perl:5.34.0
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: OnFailure # 或 Never
這是最常見的批次處理模式。您可以指定 Job 總共需要成功完成多少次 (.spec.completions),以及最多可以同時運行多少個 Pod (.spec.parallelism)。
應用場景:假設您有 100 個影片需要轉檔。您可以設定 completions: 100 和 parallelism: 10,這樣 K8s 就會以 10 個 Pod 並行處理,直到 100 個影片都轉檔成功為止。
apiVersion: batch/v1
kind: Job
metadata:
name: video-processing
spec:
completions: 100 # 期望成功完成 100 次
parallelism: 10 # 最多同時運行 10 個 Pod
template:
spec:
containers:
- name: processor
image: my-video-processor
restartPolicy: OnFailure
在這種模式下,您不設定 .spec.completions,只設定 .spec.parallelism。Job 會持續運行指定數量的並行 Pod,直到其中任何一個 Pod 以成功狀態退出,Job 就會被視為完成。
應用場景:當您的 Pod 需要從一個外部的工作佇列(如 RabbitMQ, SQS)中拉取任務來處理時,就適合使用此模式。Pod 之間需要自行協調,確保同一個任務不會被重複處理。一旦某個 Pod 確認佇列已空並成功退出,整個 Job 就結束了。
apiVersion: batch/v1
kind: Job
metadata:
name: message-queue-consumer
spec:
# 不設定 completions
parallelism: 5 # 啟動 5 個消費者
template:
spec:
containers:
- name: consumer
image: my-mq-consumer
restartPolicy: OnFailure
.spec.backoffLimit)如果 Job 中的 Pod 因故失敗(例如:程式 bug 或暫時性網路問題),Job Controller 會在一段延遲後重新建立 Pod。這個延遲時間是指數級增長的(10s, 20s, 40s, ...),最長不超過 6 分鐘。
.spec.backoffLimit 參數定義了整個 Job 可以被標記為「失敗」的重試次數上限。一旦達到這個上限,Job 就會停止重試,並被標記為 Failed。預設值是 6。
spec:
backoffLimit: 4 # 最多重試 4 次
.spec.podFailurePolicy)在某些情況下,您可能希望在特定錯誤發生時,立即讓 Job 失敗,而不要等到 backoffLimit。例如,當 Pod 因為節點映像檔問題而無法啟動時,重試是沒有意義的。
podFailurePolicy 允許您定義一組規則,當 Pod 的失敗符合這些規則時,Job 會立即終止。詳細用法請參考官方文件。
.spec.successPolicy)這是一個較新的功能,允許您在滿足特定條件時,提早宣告 Job 成功。例如,在一個並行 Job 中,只要有任意一個 Pod 成功,就可以終止所有其他 Pod 並宣告整個 Job 成功。詳細用法請參考官方文件。
根據預設,Job 和其關聯的 Pod 在完成後會一直保留在叢集中,以便您查看日誌和狀態。這可能會佔用大量空間。
您可以設定 .spec.ttlSecondsAfterFinished,讓 Job Controller 在 Job 完成(無論成功或失敗)後的一段時間,自動將其刪除。
spec:
ttlSecondsAfterFinished: 100 # Job 完成 100 秒後自動刪除
Job 是 K8s 中處理非持續性任務的強大工具。在許多情況下,您可能會希望定期執行某個 Job,這時就需要 CronJob 了,我們將在下一篇文章中介紹它。