Kubernetes v1.34: Job 的 Pod 替換策略進入 GA 階段
在 Kubernetes v1.34 中,**Pod 替換策略(Pod replacement policy)** 特性已達到正式釋出(GA)階段。這篇博文將介紹 Pod 替換策略特性以及如何在你的 Job 中使用它。
關於 Pod 替換策略
預設情況下,Job 控制器會在 Pod 失敗或開始終止(當它們具有刪除時間戳時)時立即重新建立 Pod。
因此,在某些 Pod 正在終止時,一個 Job 的正在執行的 Pod 總數可能會暫時超過指定的並行度。對於 Indexed Job,這甚至可能意味著多個 Pod 同時為同一個索引執行。
這種行為對許多工作負載來說沒有問題,但在某些情況下可能會導致問題。
例如,像 TensorFlow 和 JAX 這樣流行的機器學習框架,期望每個工作程式索引(worker index)只有一個 Pod。如果兩個 Pod 同時執行,你可能會遇到類似下面的錯誤:
/job:worker/task:4: Duplicate task registration with task_name=/job:worker/replica:0/task:4
此外,在舊 Pod 完全終止之前啟動替換 Pod 可能會導致:
- 由於節點仍被佔用,kube-scheduler 會出現排程延遲。
- 為了容納替換的 Pod,叢集會進行不必要的擴容。
- 像 Kueue 這樣的工作負載編排器會暫時繞過配額檢查。
有了 Pod 替換策略,Kubernetes 讓你能夠控制控制平面何時替換正在終止的 Pod,從而幫助你避免這些問題。
Pod 替換策略的工作原理
這項增強意味著 Kubernetes 中的 Job 有一個可選欄位 .spec.podReplacementPolicy
。
你可以選擇以下兩種策略之一:
TerminatingOrFailed
(預設):一旦 Pod 開始終止就替換它們。Failed
:僅在 Pod 完全終止並轉換到Failed
階段後才替換它們。
將策略設定為 Failed
可以確保只有在前一個 Pod 完全終止後才會建立新的 Pod。
對於具有 Pod 失效策略(Pod Failure Policy)的 Job,預設的 podReplacementPolicy
是 Failed
,並且不允許其他值。要了解更多關於 Job 的 Pod 失效策略的資訊,請參閱Pod 失效策略。
你可以透過檢查 Job 的 .status.terminating
欄位來檢視當前有多少 Pod 正在終止:
kubectl get job myjob -o=jsonpath='{.status.terminating}'
示例
下面是一個 Job 示例,它並行執行一個任務兩次(spec.completions: 2
),並行度為 2(spec.parallelism: 2
),並且僅在 Pod 完全終止後才替換它們(spec.podReplacementPolicy: Failed
):
apiVersion: batch/v1
kind: Job
metadata:
name: example-job
spec:
completions: 2
parallelism: 2
podReplacementPolicy: Failed
template:
spec:
restartPolicy: Never
containers:
- name: worker
image: your-image
如果 Pod 收到 SIGTERM 訊號(刪除、驅逐、搶佔...),它將開始終止。當容器優雅地處理終止時,清理工作可能需要一些時間。
當 Job 啟動時,我們會看到兩個 Pod 正在執行:
kubectl get pods
NAME READY STATUS RESTARTS AGE
example-job-qr8kf 1/1 Running 0 2s
example-job-stvb4 1/1 Running 0 2s
讓我們刪除其中一個 Pod(example-job-qr8kf
)。
使用 TerminatingOrFailed
策略時,一旦一個 Pod(example-job-qr8kf
)開始終止,Job 控制器會立即建立一個新的 Pod(example-job-b59zk
)來替換它。
kubectl get pods
NAME READY STATUS RESTARTS AGE
example-job-b59zk 1/1 Running 0 1s
example-job-qr8kf 1/1 Terminating 0 17s
example-job-stvb4 1/1 Running 0 17s
使用 Failed
策略時,當舊 Pod(example-job-qr8kf
)正在終止時,不會建立新的 Pod(example-job-b59zk
)。
kubectl get pods
NAME READY STATUS RESTARTS AGE
example-job-qr8kf 1/1 Terminating 0 17s
example-job-stvb4 1/1 Running 0 17s
當正在終止的 Pod 完全轉換到 Failed
階段時,才會建立一個新的 Pod:
kubectl get pods
NAME READY STATUS RESTARTS AGE
example-job-b59zk 1/1 Running 0 1s
example-job-stvb4 1/1 Running 0 25s
如何瞭解更多?
- 閱讀使用者文件中關於Pod 替換策略、按索引的回退限制和Pod 失效策略的部分。
- 閱讀 KEP(Kubernetes Enhancement Proposals)文件:Pod 替換策略、按索引的回退限制和Pod 失效策略。
致謝
與任何 Kubernetes 特性一樣,許多人都為完成這項工作做出了貢獻,從測試、提交錯誤到程式碼審查。
在這個特性經過 2 年的發展進入穩定階段之際,我們想感謝以下人員:
- Kevin Hannon - 編寫了 KEP 和初始實現。
- Michał Woźniak - 提供了指導、輔導和審查。
- Aldo Culquicondor - 提供了指導、輔導和審查。
- Maciej Szulik - 提供了指導、輔導和審查。
- Dejan Zele Pejchev - 接手了該特性,並將其從 Alpha 階段推進到 Beta 階段,最終達到 GA 階段。
參與其中
這項工作由 Kubernetes 批處理工作組(batch working group)贊助,並與 SIG Apps 社群密切合作。
如果你有興趣在該領域開發新功能,我們建議你訂閱我們的 Slack 頻道並參加定期的社群會議。