任務
任務會建立一個或多個 Pod,並持續重試 Pod 的執行,直到指定數量的 Pod 成功終止。當 Pod 成功完成時,任務會追蹤成功的完成次數。當達到指定數量的成功完成次數時,任務(即任務)即完成。刪除任務將清理其建立的 Pod。暫停任務將刪除其作用中的 Pod,直到再次恢復任務。
一個簡單的案例是建立一個任務物件,以便可靠地執行一個 Pod 直到完成。如果第一個 Pod 失敗或被刪除(例如,由於節點硬體故障或節點重新啟動),任務物件將啟動一個新的 Pod。
您也可以使用任務並行執行多個 Pod。
如果您想要排程執行任務(單一任務或多個並行任務),請參閱CronJob。
執行範例任務
以下是一個範例任務組態。它計算 π 到小數點後 2000 位並列印出來。它大約需要 10 秒才能完成。
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl:5.34.0
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
您可以使用此命令執行範例
kubectl apply -f https://kubernetes.dev.org.tw/examples/controllers/job.yaml
輸出類似於此
job.batch/pi created
使用 kubectl
檢查任務的狀態
Name: pi
Namespace: default
Selector: batch.kubernetes.io/controller-uid=c9948307-e56d-4b5d-8302-ae2d7b7da67c
Labels: batch.kubernetes.io/controller-uid=c9948307-e56d-4b5d-8302-ae2d7b7da67c
batch.kubernetes.io/job-name=pi
...
Annotations: batch.kubernetes.io/job-tracking: ""
Parallelism: 1
Completions: 1
Start Time: Mon, 02 Dec 2019 15:20:11 +0200
Completed At: Mon, 02 Dec 2019 15:21:16 +0200
Duration: 65s
Pods Statuses: 0 Running / 1 Succeeded / 0 Failed
Pod Template:
Labels: batch.kubernetes.io/controller-uid=c9948307-e56d-4b5d-8302-ae2d7b7da67c
batch.kubernetes.io/job-name=pi
Containers:
pi:
Image: perl:5.34.0
Port: <none>
Host Port: <none>
Command:
perl
-Mbignum=bpi
-wle
print bpi(2000)
Environment: <none>
Mounts: <none>
Volumes: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 21s job-controller Created pod: pi-xf9p4
Normal Completed 18s job-controller Job completed
apiVersion: batch/v1
kind: Job
metadata:
annotations: batch.kubernetes.io/job-tracking: ""
...
creationTimestamp: "2022-11-10T17:53:53Z"
generation: 1
labels:
batch.kubernetes.io/controller-uid: 863452e6-270d-420e-9b94-53a54146c223
batch.kubernetes.io/job-name: pi
name: pi
namespace: default
resourceVersion: "4751"
uid: 204fb678-040b-497f-9266-35ffa8716d14
spec:
backoffLimit: 4
completionMode: NonIndexed
completions: 1
parallelism: 1
selector:
matchLabels:
batch.kubernetes.io/controller-uid: 863452e6-270d-420e-9b94-53a54146c223
suspend: false
template:
metadata:
creationTimestamp: null
labels:
batch.kubernetes.io/controller-uid: 863452e6-270d-420e-9b94-53a54146c223
batch.kubernetes.io/job-name: pi
spec:
containers:
- command:
- perl
- -Mbignum=bpi
- -wle
- print bpi(2000)
image: perl:5.34.0
imagePullPolicy: IfNotPresent
name: pi
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Never
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
status:
active: 1
ready: 0
startTime: "2022-11-10T17:53:57Z"
uncountedTerminatedPods: {}
若要檢視已完成任務的 Pod,請使用 kubectl get pods
。
若要以機器可讀取的格式列出屬於任務的所有 Pod,您可以使用類似於此的命令
pods=$(kubectl get pods --selector=batch.kubernetes.io/job-name=pi --output=jsonpath='{.items[*].metadata.name}')
echo $pods
輸出類似於此
pi-5rwd7
在此,選擇器與任務的選擇器相同。--output=jsonpath
選項指定一個運算式,其中包含傳回清單中每個 Pod 的名稱。
檢視其中一個 Pod 的標準輸出
kubectl logs $pods
檢視任務記錄的另一種方式
kubectl logs jobs/pi
輸出類似於此
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275901
編寫任務規格
與所有其他 Kubernetes 組態一樣,任務需要 apiVersion
、kind
和 metadata
欄位。
當控制平面為任務建立新的 Pod 時,任務的 .metadata.name
是命名這些 Pod 的基礎之一。任務的名稱必須是有效的DNS 子網域值,但這可能會為 Pod 主機名稱產生非預期的結果。為了獲得最佳相容性,名稱應遵循更嚴格的DNS 標籤規則。即使名稱是 DNS 子網域,名稱長度也不得超過 63 個字元。
任務也需要.spec
區段。
任務標籤
任務標籤將具有 batch.kubernetes.io/
前綴,用於 job-name
和 controller-uid
。
Pod 範本
.spec.template
是 .spec
中唯一必要的欄位。
.spec.template
是Pod 範本。它與Pod具有完全相同的結構描述,除了它是巢狀的且沒有 apiVersion
或 kind
。
除了 Pod 的必要欄位外,任務中的 Pod 範本還必須指定適當的標籤(請參閱Pod 選擇器)和適當的重新啟動策略。
僅允許RestartPolicy
等於 Never
或 OnFailure
。
Pod 選擇器
.spec.selector
欄位是選用的。在幾乎所有情況下,您都不應指定它。請參閱指定您自己的 Pod 選擇器區段。
任務的並行執行
有三種主要類型的任務適合作為任務執行
- 非並行任務
- 通常,只會啟動一個 Pod,除非 Pod 失敗。
- 任務在其 Pod 成功終止後立即完成。
- 具有固定完成計數的並行任務
- 為
.spec.completions
指定非零正值。 - 任務代表整體任務,當有
.spec.completions
個成功的 Pod 時,任務即完成。 - 當使用
.spec.completionMode="Indexed"
時,每個 Pod 在 0 到.spec.completions-1
的範圍內取得不同的索引。
- 為
- 具有工作佇列的並行任務
- 請勿指定
.spec.completions
,預設為.spec.parallelism
。 - Pod 必須在彼此之間或外部服務之間協調,以判斷每個 Pod 應處理的內容。例如,Pod 可能會從工作佇列中提取最多 N 個項目的批次。
- 每個 Pod 都能夠獨立判斷其所有對等節點是否已完成,從而判斷整個任務是否已完成。
- 當任務中的任何 Pod 以成功終止時,不會建立新的 Pod。
- 一旦至少有一個 Pod 以成功終止且所有 Pod 都已終止,則任務即完成並成功。
- 一旦任何 Pod 成功結束,就不應再有其他 Pod 繼續為此任務執行工作或寫入輸出。它們都應該處於結束程序中。
- 請勿指定
對於非平行的 Job,您可以將 .spec.completions
和 .spec.parallelism
都保持未設定。當兩者都未設定時,預設值均為 1。
對於固定完成計數的 Job,您應該將 .spec.completions
設定為所需的完成次數。您可以設定 .spec.parallelism
,或者保持未設定,它將預設為 1。
對於工作佇列的 Job,您必須保持 .spec.completions
未設定,並將 .spec.parallelism
設定為非負整數。
有關如何使用不同類型 Job 的更多資訊,請參閱任務模式章節。
控制平行性
請求的平行性 (.spec.parallelism
) 可以設定為任何非負值。如果未指定,則預設為 1。如果指定為 0,則 Job 會有效地暫停,直到增加此值。
實際平行性(任何時刻執行的 Pod 數量)可能多於或少於請求的平行性,原因有很多
- 對於固定完成計數的 Job,並行執行的 Pod 實際數量不會超過剩餘完成次數。較高的
.spec.parallelism
值實際上會被忽略。 - 對於工作佇列的 Job,在任何 Pod 成功後,都不會啟動新的 Pod — 但允許剩餘的 Pod 完成。
- 如果 Job 控制器沒有時間做出反應。
- 如果 Job 控制器由於任何原因(缺少
ResourceQuota
、缺少權限等)而無法建立 Pod,則 Pod 數量可能少於請求的數量。 - 由於同一個 Job 中先前 Pod 失敗次數過多,Job 控制器可能會限制新 Pod 的建立。
- 當 Pod 正常關閉時,需要時間停止。
完成模式
Kubernetes v1.24 [stable]
具有固定完成計數的 Job - 也就是說,具有非空值 .spec.completions
的任務 - 可以具有在 .spec.completionMode
中指定的完成模式
NonIndexed
(預設):當有.spec.completions
個成功完成的 Pod 時,Job 會被視為已完成。換句話說,每個 Pod 的完成彼此同源。請注意,具有空值.spec.completions
的 Job 隱含地是NonIndexed
。Indexed
:Job 的 Pod 會獲得從 0 到.spec.completions-1
的關聯完成索引。索引可透過四種機制取得- Pod 註釋
batch.kubernetes.io/job-completion-index
。 - Pod 標籤
batch.kubernetes.io/job-completion-index
(適用於 v1.28 及更新版本)。請注意,必須啟用功能閘道PodIndexLabel
才能使用此標籤,且預設為啟用。 - 作為 Pod 主機名稱的一部分,遵循
$(job-name)-$(index)
模式。當您將 Indexed Job 與 Service 結合使用時,Job 內的 Pod 可以使用確定性的主機名稱,透過 DNS 互相尋址。有關如何設定此功能的更多資訊,請參閱使用 Pod 到 Pod 通訊的 Job。 - 從容器化的任務中,在環境變數
JOB_COMPLETION_INDEX
中。
當每個索引都有一個成功完成的 Pod 時,Job 會被視為已完成。有關如何使用此模式的更多資訊,請參閱用於靜態工作分配的索引式 Job 並行處理。
- Pod 註釋
注意
雖然很少見,但同一個索引可能會啟動多個 Pod(由於節點故障、kubelet 重新啟動或 Pod 驅逐等多種原因)。在這種情況下,只有第一個成功完成的 Pod 會計入完成計數,並更新 Job 的狀態。一旦偵測到,同一個索引的其他正在執行或已完成的 Pod 將被 Job 控制器刪除。處理 Pod 和容器故障
Pod 中的容器可能會因多種原因而失敗,例如因為其中的進程以非零退出碼退出,或者容器因超出記憶體限制而被終止等等。如果發生這種情況,且 .spec.template.spec.restartPolicy = "OnFailure"
,則 Pod 會保留在節點上,但容器會重新執行。因此,您的程式需要處理在本機重新啟動的情況,或者指定 .spec.template.spec.restartPolicy = "Never"
。有關 restartPolicy
的更多資訊,請參閱Pod 生命周期。
整個 Pod 也可能因多種原因而失敗,例如當 Pod 從節點中移除(節點升級、重新啟動、刪除等),或者如果 Pod 的容器失敗且 .spec.template.spec.restartPolicy = "Never"
。當 Pod 失敗時,Job 控制器會啟動一個新的 Pod。這表示您的應用程式需要處理在新 Pod 中重新啟動的情況。特別是,它需要處理先前執行導致的暫存檔、鎖定、不完整的輸出等。
預設情況下,每次 Pod 失敗都會計入 .spec.backoffLimit
限制,請參閱Pod 退避失敗策略。但是,您可以透過設定 Job 的 Pod 失敗策略來自訂 Pod 失敗的處理方式。
此外,您可以選擇透過設定 .spec.backoffLimitPerIndex
欄位,針對 Indexed Job 的每個索引獨立計算 Pod 失敗次數(如需更多資訊,請參閱每個索引的退避限制)。
請注意,即使您指定 .spec.parallelism = 1
和 .spec.completions = 1
以及 .spec.template.spec.restartPolicy = "Never"
,同一個程式有時也可能會啟動兩次。
如果您同時指定 .spec.parallelism
和 .spec.completions
都大於 1,則可能會有多個 Pod 同時執行。因此,您的 Pod 也必須能容忍並行性。
如果您指定 .spec.podFailurePolicy
欄位,則 Job 控制器不會將終止中的 Pod(設定了 .metadata.deletionTimestamp
欄位的 Pod)視為失敗,直到該 Pod 終止(其 .status.phase
為 Failed
或 Succeeded
)。但是,一旦終止變得明顯,Job 控制器就會建立一個替換 Pod。一旦 Pod 終止,Job 控制器會評估相關 Job 的 .backoffLimit
和 .podFailurePolicy
,並將現在已終止的 Pod 納入考量。
如果這些要求中的任何一個未滿足,Job 控制器會將終止中的 Pod 視為立即失敗,即使該 Pod 後來以 phase: "Succeeded"
終止。
Pod 退避失敗策略
在某些情況下,您可能希望在由於組態等方面的邏輯錯誤而重試多次後,讓 Job 失敗。為此,請設定 .spec.backoffLimit
以指定在將 Job 視為失敗之前的重試次數。預設情況下,退避限制設定為 6。與 Job 關聯的失敗 Pod 會由 Job 控制器以指數退避延遲(10 秒、20 秒、40 秒...)重新建立,上限為六分鐘。
重試次數以兩種方式計算
.status.phase = "Failed"
的 Pod 數量。- 當使用
restartPolicy = "OnFailure"
時,.status.phase
等於Pending
或Running
的 Pod 中所有容器的重試次數。
如果任一計算達到 .spec.backoffLimit
,則 Job 會被視為失敗。
注意
如果您的 Job 具有restartPolicy = "OnFailure"
,請記住,一旦達到 Job 退避限制,執行 Job 的 Pod 將會終止。這可能會使除錯 Job 的可執行檔變得更加困難。我們建議在除錯 Job 時設定 restartPolicy = "Never"
,或使用記錄系統以確保不會意外遺失失敗 Job 的輸出。每個索引的退避限制
Kubernetes v1.29 [beta]
當您執行 indexed Job 時,您可以選擇針對每個索引獨立處理 Pod 失敗的重試。為此,請設定 .spec.backoffLimitPerIndex
以指定每個索引的最大 Pod 失敗次數。
當索引的每個索引退避限制超出時,Kubernetes 會將該索引視為失敗,並將其新增至 .status.failedIndexes
欄位。成功索引(具有成功執行的 Pod 的索引)會記錄在 .status.completedIndexes
欄位中,無論您是否設定 backoffLimitPerIndex
欄位。
請注意,失敗的索引不會中斷其他索引的執行。一旦您指定了每個索引的退避限制的 Job 的所有索引都完成,如果至少有一個索引確實失敗,則 Job 控制器會將整體 Job 標記為失敗,方法是在狀態中設定 Failed 條件。即使某些索引(可能幾乎所有索引)都已成功處理,Job 仍會被標記為失敗。
您可以額外限制標記為失敗的索引最大數量,方法是設定 .spec.maxFailedIndexes
欄位。當失敗索引的數量超過 maxFailedIndexes
欄位時,Job 控制器會觸發終止該 Job 的所有剩餘執行中 Pod。一旦所有 Pod 都終止,整個 Job 會被 Job 控制器標記為失敗,方法是在 Job 狀態中設定 Failed 條件。
以下是定義 backoffLimitPerIndex
的 Job 的範例資訊清單
apiVersion: batch/v1
kind: Job
metadata:
name: job-backoff-limit-per-index-example
spec:
completions: 10
parallelism: 3
completionMode: Indexed # required for the feature
backoffLimitPerIndex: 1 # maximal number of failures per index
maxFailedIndexes: 5 # maximal number of failed indexes before terminating the Job execution
template:
spec:
restartPolicy: Never # required for the feature
containers:
- name: example
image: python
command: # The jobs fails as there is at least one failed index
# (all even indexes fail in here), yet all indexes
# are executed as maxFailedIndexes is not exceeded.
- python3
- -c
- |
import os, sys
print("Hello world")
if int(os.environ.get("JOB_COMPLETION_INDEX")) % 2 == 0:
sys.exit(1)
在上述範例中,Job 控制器允許每個索引重新啟動一次。當失敗索引的總數超過 5 時,整個 Job 將會終止。
一旦 Job 完成,Job 狀態看起來如下所示
kubectl get -o yaml job job-backoff-limit-per-index-example
status:
completedIndexes: 1,3,5,7,9
failedIndexes: 0,2,4,6,8
succeeded: 5 # 1 succeeded pod for each of 5 succeeded indexes
failed: 10 # 2 failed pods (1 retry) for each of 5 failed indexes
conditions:
- message: Job has failed indexes
reason: FailedIndexes
status: "True"
type: FailureTarget
- message: Job has failed indexes
reason: FailedIndexes
status: "True"
type: Failed
Job 控制器新增 FailureTarget
Job 條件以觸發 Job 終止和清理。當所有 Job Pod 都終止時,Job 控制器會新增 Failed
條件,其 reason
和 message
值與 FailureTarget
Job 條件相同。如需詳細資訊,請參閱Job Pod 的終止。
此外,您可能想要將每個索引的退避與 Pod 失敗策略一起使用。當使用每個索引的退避時,有一個新的 FailIndex
動作可用,可讓您避免索引內不必要的重試。
Pod 失敗策略
Kubernetes v1.31 [stable]
(預設啟用:true)透過 .spec.podFailurePolicy
欄位定義的 Pod 失敗策略,可讓您的叢集根據容器退出碼和 Pod 條件來處理 Pod 失敗。
在某些情況下,您可能希望比 Pod 退避失敗策略提供的控制更精細地控制 Pod 失敗的處理方式,後者是基於 Job 的 .spec.backoffLimit
。以下是一些使用案例範例
- 為了最佳化執行工作負載的成本,避免不必要的 Pod 重新啟動,您可以在其中一個 Pod 因退出碼指示軟體錯誤而失敗時立即終止 Job。
- 為了保證即使發生中斷,您的 Job 也能完成,您可以忽略由中斷(例如搶佔、API 啟動的驅逐或污點式驅逐)引起的 Pod 失敗,以便它們不計入
.spec.backoffLimit
重試限制。
您可以在 .spec.podFailurePolicy
欄位中設定 Pod 失敗策略,以滿足上述使用案例。此策略可以根據容器退出碼和 Pod 條件來處理 Pod 失敗。
以下是定義 podFailurePolicy
的 Job 的資訊清單
apiVersion: batch/v1
kind: Job
metadata:
name: job-pod-failure-policy-example
spec:
completions: 12
parallelism: 3
template:
spec:
restartPolicy: Never
containers:
- name: main
image: docker.io/library/bash:5
command: ["bash"] # example command simulating a bug which triggers the FailJob action
args:
- -c
- echo "Hello world!" && sleep 5 && exit 42
backoffLimit: 6
podFailurePolicy:
rules:
- action: FailJob
onExitCodes:
containerName: main # optional
operator: In # one of: In, NotIn
values: [42]
- action: Ignore # one of: Ignore, FailJob, Count
onPodConditions:
- type: DisruptionTarget # indicates Pod disruption
在上述範例中,Pod 失敗策略的第一條規則指定,如果 main
容器以退出碼 42 失敗,則應將 Job 標記為失敗。以下是專門針對 main
容器的規則
- 退出碼 0 表示容器成功
- 退出碼 42 表示整個 Job 失敗
- 任何其他退出碼都表示容器失敗,進而導致整個 Pod 失敗。如果重新啟動總次數低於
backoffLimit
,則將重新建立 Pod。如果達到backoffLimit
,則整個 Job 失敗。
注意
由於 Pod 範本指定了restartPolicy: Never
,因此 kubelet 不會在該特定 Pod 中重新啟動 main
容器。Pod 失敗策略的第二條規則,指定針對條件為 DisruptionTarget
的失敗 Pod 的 Ignore
動作,將 Pod 中斷排除在計入 .spec.backoffLimit
重試限制之外。
注意
如果 Job 失敗,無論是透過 Pod 失敗策略還是 Pod 退避失敗策略,且 Job 正在執行多個 Pod,則 Kubernetes 會終止該 Job 中所有仍在 Pending 或 Running 狀態的 Pod。以下是 API 的一些需求和語意
- 如果您想要為 Job 使用
.spec.podFailurePolicy
欄位,您還必須使用設定為Never
的.spec.restartPolicy
定義該 Job 的 Pod 範本。 - 您在
spec.podFailurePolicy.rules
下指定的 Pod 失敗策略規則會依序評估。一旦規則符合 Pod 失敗,則會忽略其餘規則。當沒有規則符合 Pod 失敗時,則會套用預設處理方式。 - 您可以透過在
spec.podFailurePolicy.rules[*].onExitCodes.containerName
中指定容器名稱,將規則限制為特定容器。如果未指定,則規則適用於所有容器。如果指定,則應符合 Pod 範本中的一個容器或initContainer
名稱。 - 您可以指定在符合 Pod 失敗策略時採取的動作,方法是使用
spec.podFailurePolicy.rules[*].action
。可能的值為FailJob
:用於指示應將 Pod 的 Job 標記為 Failed,並終止所有執行中的 Pod。Ignore
:用於指示不應遞增朝向.spec.backoffLimit
的計數器,且應建立替換 Pod。Count
:用於指示應以預設方式處理 Pod。應遞增朝向.spec.backoffLimit
的計數器。FailIndex
:將此動作與 每個索引的退避限制一起使用,以避免失敗 Pod 的索引內不必要的重試。
注意
當您使用podFailurePolicy
時,Job 控制器只會比對處於 Failed
階段的 Pod。具有刪除時間戳記但未處於終端階段(Failed
或 Succeeded
)的 Pod 會被視為仍在終止中。這表示終止中的 Pod 會保留 追蹤終止器,直到它們達到終端階段。自 Kubernetes 1.27 起,Kubelet 會將已刪除的 Pod 轉換為終端階段(請參閱:Pod 階段)。這可確保已刪除的 Pod 的終止器會由 Job 控制器移除。注意
從 Kubernetes v1.28 開始,當使用 Pod 失敗策略時,Job 控制器只會在終止中的 Pod 達到終端Failed
階段後才重新建立它們。此行為類似於 podReplacementPolicy: Failed
。如需更多資訊,請參閱Pod 替換策略。當您使用 podFailurePolicy
,且 Job 因 Pod 符合具有 FailJob
動作的規則而失敗時,Job 控制器會透過新增 FailureTarget
條件來觸發 Job 終止程序。如需更多詳細資訊,請參閱Job 終止和清理。
成功策略
Kubernetes v1.31 [beta]
(預設啟用:true)建立 Indexed Job 時,您可以根據成功的 Pod,使用 .spec.successPolicy
定義何時可以將 Job 宣告為成功。
預設情況下,當成功 Pod 的數量等於 .spec.completions
時,Job 會成功。以下是一些您可能希望額外控制宣告 Job 成功的狀況
- 當執行具有不同參數的模擬時,您可能不需要所有模擬都成功,整體 Job 才能成功。
- 當遵循領導者-工作者模式時,只有領導者的成功才能決定 Job 的成功或失敗。MPI 和 PyTorch 等框架就是這方面的範例。
您可以在 .spec.successPolicy
欄位中設定成功策略,以滿足上述使用案例。此策略可以根據成功的 Pod 處理 Job 成功。在 Job 符合成功策略後,Job 控制器會終止剩餘的 Pod。成功策略由規則定義。每個規則可以採用以下形式之一
- 當您僅指定
succeededIndexes
時,一旦succeededIndexes
中指定的所有索引都成功,Job 控制器會將 Job 標記為成功。succeededIndexes
必須是 0 到.spec.completions-1
之間的間隔列表。 - 當您僅指定
succeededCount
時,一旦成功索引的數量達到succeededCount
,Job 控制器會將 Job 標記為成功。 - 當您同時指定
succeededIndexes
和succeededCount
時,一旦來自succeededIndexes
中指定的索引子集的成功索引數量達到succeededCount
,Job 控制器會將 Job 標記為成功。
請注意,當您在 .spec.successPolicy.rules
中指定多個規則時,Job 控制器會依序評估規則。一旦 Job 符合規則,Job 控制器會忽略其餘規則。
以下是具有 successPolicy
的 Job 的資訊清單
apiVersion: batch/v1
kind: Job
metadata:
name: job-success
spec:
parallelism: 10
completions: 10
completionMode: Indexed # Required for the success policy
successPolicy:
rules:
- succeededIndexes: 0,2-3
succeededCount: 1
template:
spec:
containers:
- name: main
image: python
command: # Provided that at least one of the Pods with 0, 2, and 3 indexes has succeeded,
# the overall Job is a success.
- python3
- -c
- |
import os, sys
if os.environ.get("JOB_COMPLETION_INDEX") == "2":
sys.exit(0)
else:
sys.exit(1)
restartPolicy: Never
在上述範例中,同時指定了 succeededIndexes
和 succeededCount
。因此,當指定的索引 0、2 或 3 中任一個成功時,Job 控制器將會將 Job 標記為成功並終止剩餘的 Pod。符合成功策略的 Job 會獲得具有 SuccessPolicy
原因的 SuccessCriteriaMet
條件。在移除剩餘 Pod 的指令發出後,Job 會獲得 Complete
條件。
請注意,succeededIndexes
以連字號分隔的間隔表示。數字以系列的第一個和最後一個元素表示,並以連字號分隔。
注意
當您同時指定成功策略和一些終止策略(例如.spec.backoffLimit
和 .spec.podFailurePolicy
)時,一旦 Job 符合任一策略,Job 控制器會優先考慮終止策略並忽略成功策略。Job 終止和清理
當 Job 完成時,不會再建立更多 Pod,但 Pod 通常也不會被刪除。保留它們可讓您仍然檢視已完成 Pod 的日誌,以檢查錯誤、警告或其他診斷輸出。Job 物件在完成後也會保留,以便您可以檢視其狀態。在注意到其狀態後,由使用者自行刪除舊 Job。使用 kubectl
刪除 Job(例如 kubectl delete jobs/pi
或 kubectl delete -f ./job.yaml
)。當您使用 kubectl
刪除 Job 時,它建立的所有 Pod 也會被刪除。
預設情況下,Job 將不間斷地執行,除非 Pod 失敗(restartPolicy=Never
)或容器以錯誤退出(restartPolicy=OnFailure
),在這種情況下,Job 會遵從上述 .spec.backoffLimit
。一旦達到 .spec.backoffLimit
,Job 將被標記為失敗,且任何執行中的 Pod 都將被終止。
終止 Job 的另一種方法是設定活動期限。方法是將 Job 的 .spec.activeDeadlineSeconds
欄位設定為秒數。activeDeadlineSeconds
適用於 Job 的持續時間,無論建立了多少 Pod。一旦 Job 達到 activeDeadlineSeconds
,其所有執行中的 Pod 都將被終止,且 Job 狀態將變為 type: Failed
,reason: DeadlineExceeded
。
請注意,Job 的 .spec.activeDeadlineSeconds
優先於其 .spec.backoffLimit
。因此,即使 backoffLimit
尚未達到,重試一個或多個失敗 Pod 的 Job 一旦達到 activeDeadlineSeconds
指定的時間限制,將不會部署其他 Pod。
範例
apiVersion: batch/v1
kind: Job
metadata:
name: pi-with-timeout
spec:
backoffLimit: 5
activeDeadlineSeconds: 100
template:
spec:
containers:
- name: pi
image: perl:5.34.0
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
請注意,Job 規格和 Job 內的Pod 範本規格都具有 activeDeadlineSeconds
欄位。請確保您在適當的層級設定此欄位。
請記住,restartPolicy
適用於 Pod,而不適用於 Job 本身:一旦 Job 狀態為 type: Failed
,就不會自動重新啟動 Job。也就是說,透過 .spec.activeDeadlineSeconds
和 .spec.backoffLimit
啟動的 Job 終止機制會導致永久的 Job 失敗,需要手動介入才能解決。
終端 Job 條件
Job 有兩種可能的終端狀態,每種狀態都有對應的 Job 條件
- Succeeded:Job 條件
Complete
- Failed:Job 條件
Failed
Job 會因以下原因而失敗
- Pod 失敗次數超過 Job 規格中指定的
.spec.backoffLimit
。如需詳細資訊,請參閱Pod 退避失敗策略。 - Job 執行時間超過指定的
.spec.activeDeadlineSeconds
- 使用
.spec.backoffLimitPerIndex
的索引式 Job 具有失敗的索引。如需詳細資訊,請參閱每個索引的退避限制。 - Job 中失敗索引的數量超過指定的
spec.maxFailedIndexes
。如需詳細資訊,請參閱每個索引的退避限制 - 失敗的 Pod 符合
.spec.podFailurePolicy
中具有FailJob
動作的規則。有關 Pod 失敗策略規則如何影響失敗評估的詳細資訊,請參閱Pod 失敗策略。
Job 會因以下原因而成功
- 成功 Pod 的數量達到指定的
.spec.completions
- 符合
.spec.successPolicy
中指定的條件。如需詳細資訊,請參閱成功策略。
在 Kubernetes v1.31 及更新版本中,Job 控制器會延遲新增終端條件 Failed
或 Complete
,直到所有 Job Pod 都終止。
在 Kubernetes v1.30 及更早版本中,一旦觸發 Job 終止程序且所有 Pod 終止器都已移除,Job 控制器就會立即新增 Complete
或 Failed
Job 終端條件。但是,在新增終端條件時,某些 Pod 仍可能正在執行或終止中。
在 Kubernetes v1.31 及更新版本中,控制器僅在所有 Pod 都終止後才新增 Job 終端條件。您可以使用 JobManagedBy
和 JobPodReplacementPolicy
(預設均為啟用)功能閘道來控制此行為。
Job Pod 的終止
在 Job 符合成功或失敗條件後,Job 控制器會新增 FailureTarget
條件或 SuccessCriteriaMet
條件至 Job,以觸發 Pod 終止。
諸如 terminationGracePeriodSeconds
之類的因素可能會增加從 Job 控制器新增 FailureTarget
條件或 SuccessCriteriaMet
條件到所有 Job Pod 終止且 Job 控制器新增終端條件(Failed
或 Complete
)之間的時間長度。
您可以使用 FailureTarget
或 SuccessCriteriaMet
條件來評估 Job 是否已失敗或成功,而無需等待控制器新增終端條件。
例如,您可能想要決定何時建立替換失敗 Job 的替換 Job。如果您在 FailureTarget
條件出現時替換失敗的 Job,您的替換 Job 會更快執行,但可能會導致失敗 Job 和替換 Job 的 Pod 同時執行,從而使用額外的運算資源。
或者,如果您的叢集資源容量有限,您可以選擇等待 Job 上出現 Failed
條件,這會延遲您的替換 Job,但可確保您透過等待直到所有失敗的 Pod 都移除後再執行,來節省資源。
自動清理已完成的 Job
已完成的 Job 通常不再需要在系統中。將它們保留在系統中會對 API 伺服器造成壓力。如果 Job 由更高等級的控制器直接管理,例如CronJobs,則可以由 CronJobs 根據指定的基於容量的清理策略來清理 Job。
已完成 Job 的 TTL 機制
Kubernetes v1.23 [stable]
自動清理已完成 Job(Complete
或 Failed
)的另一種方法是使用 TTL 控制器為已完成資源提供的 TTL 機制,方法是指定 Job 的 .spec.ttlSecondsAfterFinished
欄位。
當 TTL 控制器清理 Job 時,它將以串聯方式刪除 Job,即將其依賴物件(例如 Pod)與 Job 一起刪除。請注意,當 Job 被刪除時,其生命週期保證(例如終止器)將會受到尊重。
例如
apiVersion: batch/v1
kind: Job
metadata:
name: pi-with-ttl
spec:
ttlSecondsAfterFinished: 100
template:
spec:
containers:
- name: pi
image: perl:5.34.0
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
Job pi-with-ttl
將在完成後 100
秒符合自動刪除的資格。
如果欄位設定為 0
,則 Job 將在完成後立即符合自動刪除的資格。如果欄位未設定,則此 Job 在完成後不會由 TTL 控制器清理。
注意
建議設定 ttlSecondsAfterFinished
欄位,因為未受管理的 Job(您直接建立的 Job,而不是透過 CronJob 等其他工作負載 API 間接建立的 Job)具有 orphanDependents
的預設刪除策略,導致未受管理的 Job 建立的 Pod 在該 Job 完全刪除後仍會保留。即使控制平面最終會垃圾收集已刪除 Job 中的 Pod,在它們失敗或完成後,有時這些剩餘的 Pod 可能會導致叢集效能下降,或者在最壞的情況下,由於這種效能下降而導致叢集離線。
您可以使用 LimitRanges 和 ResourceQuotas 來限制特定命名空間可以消耗的資源量。
Job 模式
Job 物件可用於處理一組獨立但相關的工作項目。這些可能是要傳送的電子郵件、要呈現的影格、要轉碼的檔案、NoSQL 資料庫中要掃描的索引鍵範圍等等。
在複雜的系統中,可能有多組不同的工作項目。這裡我們僅考量使用者想要一起管理的一組工作項目 — 一個批次任務。
平行運算有多種不同的模式,每種模式都有其優點和缺點。以下是權衡考量:
- 每個工作項目一個 Job 物件,與所有工作項目一個 Job 物件。每個工作項目一個 Job 會為使用者和系統管理大量 Job 物件產生一些額外負擔。對於大量項目來說,所有工作項目使用單一 Job 會更好。
- 建立的 Pod 數量等於工作項目數量,與每個 Pod 可以處理多個工作項目。當 Pod 數量等於工作項目數量時,Pods 通常需要較少的程式碼和容器修改。讓每個 Pod 處理多個工作項目對於大量項目來說會更好。
- 幾種方法使用工作佇列。這需要執行佇列服務,並修改現有的程式或容器以使其使用工作佇列。其他方法更容易適用於現有的容器化應用程式。
- 當 Job 與無頭服務相關聯時,您可以讓 Job 中的 Pod 彼此通訊,以協同運算。
權衡考量在此總結,第 2 至 4 欄對應於上述權衡考量。模式名稱也是範例和更詳細描述的連結。
模式 | 單一 Job 物件 | Pod 數量少於工作項目數量? | 使用未修改的應用程式? |
---|---|---|---|
每個工作項目一個 Pod 的佇列 | ✓ | 有時 | |
可變 Pod 計數的佇列 | ✓ | ✓ | |
具有靜態工作分配的索引 Job | ✓ | ✓ | |
具有 Pod 對 Pod 通訊的任務 | ✓ | 有時 | 有時 |
Job 範本擴展 | ✓ |
當您使用 .spec.completions
指定完成次數時,Job 控制器建立的每個 Pod 都具有相同的spec
。這表示任務的所有 Pod 都將具有相同的命令列和相同的映像檔、相同的磁碟區以及(幾乎)相同的環境變數。這些模式是安排 Pod 處理不同事物的方式。
此表格顯示每個模式的 .spec.parallelism
和 .spec.completions
的必要設定。此處,W
是工作項目的數量。
模式 | .spec.completions | .spec.parallelism |
---|---|---|
每個工作項目一個 Pod 的佇列 | W | 任何 |
可變 Pod 計數的佇列 | null | 任何 |
具有靜態工作分配的索引 Job | W | 任何 |
具有 Pod 對 Pod 通訊的任務 | W | W |
Job 範本擴展 | 1 | 應為 1 |
進階用法
暫停 Job
Kubernetes v1.24 [stable]
當建立 Job 時,Job 控制器會立即開始建立 Pod 以滿足 Job 的需求,並將持續執行直到 Job 完成。但是,您可能希望暫時暫停 Job 的執行並稍後恢復,或在暫停狀態下啟動 Job,並讓自訂控制器稍後決定何時啟動它們。
要暫停 Job,您可以將 Job 的 .spec.suspend
欄位更新為 true;稍後,當您想要再次恢復它時,將其更新為 false。建立 .spec.suspend
設定為 true 的 Job 將以暫停狀態建立它。
當 Job 從暫停狀態恢復時,其 .status.startTime
欄位將重設為目前時間。這表示當 Job 暫停和恢復時,.spec.activeDeadlineSeconds
計時器將停止並重設。
當您暫停 Job 時,任何沒有 Completed
狀態的執行中 Pod 都將使用 SIGTERM 訊號終止。Pod 的正常終止期間將受到尊重,您的 Pod 必須在此期間處理此訊號。這可能涉及儲存進度以供稍後使用或還原變更。以這種方式終止的 Pod 將不計入 Job 的 completions
計數。
暫停狀態的 Job 定義範例如下
kubectl get job myjob -o yaml
apiVersion: batch/v1
kind: Job
metadata:
name: myjob
spec:
suspend: true
parallelism: 1
completions: 5
template:
spec:
...
您也可以使用命令列修補 Job 來切換 Job 暫停狀態。
暫停活動 Job
kubectl patch job/myjob --type=strategic --patch '{"spec":{"suspend":true}}'
恢復已暫停的 Job
kubectl patch job/myjob --type=strategic --patch '{"spec":{"suspend":false}}'
可以使用 Job 的狀態來判斷 Job 是否已暫停或過去是否已暫停
kubectl get jobs/myjob -o yaml
apiVersion: batch/v1
kind: Job
# .metadata and .spec omitted
status:
conditions:
- lastProbeTime: "2021-02-05T13:14:33Z"
lastTransitionTime: "2021-02-05T13:14:33Z"
status: "True"
type: Suspended
startTime: "2021-02-05T13:13:48Z"
類型為 "Suspended" 且狀態為 "True" 的 Job 條件表示 Job 已暫停;lastTransitionTime
欄位可用於判斷 Job 已暫停多久。如果該條件的狀態為 "False",則表示 Job 之前已暫停,現在正在執行。如果 Job 的狀態中不存在此類條件,則表示 Job 從未停止過。
當 Job 暫停和恢復時,也會建立事件
kubectl describe jobs/myjob
Name: myjob
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 12m job-controller Created pod: myjob-hlrpl
Normal SuccessfulDelete 11m job-controller Deleted pod: myjob-hlrpl
Normal Suspended 11m job-controller Job suspended
Normal SuccessfulCreate 3s job-controller Created pod: myjob-jvb44
Normal Resumed 3s job-controller Job resumed
最後四個事件,特別是 "Suspended" 和 "Resumed" 事件,是直接切換 .spec.suspend
欄位的結果。在這兩個事件之間的時間內,我們看到沒有建立 Pod,但一旦 Job 恢復,Pod 建立就會重新開始。
可變排程指令
Kubernetes v1.27 [穩定]
在大多數情況下,平行 Job 會希望 Pod 在具有約束條件的情況下執行,例如都在同一個區域中,或都在 GPU 型號 x 或 y 上,而不是兩者混合。
暫停欄位是實現這些語意學的第一步。暫停允許自訂佇列控制器決定何時應啟動 Job;但是,一旦 Job 取消暫停,自訂佇列控制器就無法影響 Job 的 Pod 實際部署的位置。
此功能允許在 Job 啟動之前更新 Job 的排程指令,這使自訂佇列控制器能夠影響 Pod 放置,同時將實際的 Pod 到節點分配卸載到 kube-scheduler。這僅適用於從未取消暫停的已暫停 Job。
Job 的 Pod 範本中可以更新的欄位包括節點親和性、節點選取器、容忍度、標籤、註釋和排程閘道。
指定您自己的 Pod 選取器
通常,當您建立 Job 物件時,您不會指定 .spec.selector
。系統預設邏輯會在建立 Job 時新增此欄位。它會選取一個選取器值,該值不會與任何其他 Job 重疊。
但是,在某些情況下,您可能需要覆寫此自動設定的選取器。若要執行此操作,您可以指定 Job 的 .spec.selector
。
執行此操作時請非常小心。如果您指定的標籤選取器對於該 Job 的 Pod 不是唯一的,並且與不相關的 Pod 相符,則可能會刪除不相關 Job 的 Pod,或者此 Job 可能會將其他 Pod 計算為已完成它,或者一個或兩個 Job 都可能拒絕建立 Pod 或執行完成。如果選擇了非唯一的選取器,則其他控制器(例如 ReplicationController)及其 Pod 也可能以不可預測的方式運作。當您指定 .spec.selector
時,Kubernetes 不會阻止您犯錯。
以下是一個您可能想要使用此功能的案例範例。
假設 Job old
已經在執行。您希望現有的 Pod 繼續執行,但您希望它建立的其餘 Pod 使用不同的 Pod 範本,並且 Job 具有新的名稱。您無法更新 Job,因為這些欄位不可更新。因此,您刪除 Job old
,但讓其 Pod 保持執行,使用 kubectl delete jobs/old --cascade=orphan
。在刪除它之前,請記下它使用的選取器
kubectl get job old -o yaml
輸出類似於此
kind: Job
metadata:
name: old
...
spec:
selector:
matchLabels:
batch.kubernetes.io/controller-uid: a8f3d00d-c6d2-11e5-9f87-42010af00002
...
然後,您建立一個名為 new
的新 Job,並且您明確指定相同的選取器。由於現有的 Pod 具有標籤 batch.kubernetes.io/controller-uid=a8f3d00d-c6d2-11e5-9f87-42010af00002
,因此它們也由 Job new
控制。
由於您沒有使用系統通常為您自動產生的選取器,因此您需要在新的 Job 中指定 manualSelector: true
。
kind: Job
metadata:
name: new
...
spec:
manualSelector: true
selector:
matchLabels:
batch.kubernetes.io/controller-uid: a8f3d00d-c6d2-11e5-9f87-42010af00002
...
新的 Job 本身將具有與 a8f3d00d-c6d2-11e5-9f87-42010af00002
不同的 uid。設定 manualSelector: true
會告知系統您知道自己在做什麼,並允許這種不符。
使用 Finalizers 追蹤 Job
Kubernetes v1.26 [穩定]
控制平面會追蹤屬於任何 Job 的 Pod,並注意是否從 API 伺服器中移除任何此類 Pod。為此,Job 控制器會使用 Finalizer batch.kubernetes.io/job-tracking
建立 Pod。控制器僅在 Pod 已在 Job 狀態中被計算後才移除 Finalizer,從而允許其他控制器或使用者移除 Pod。
注意
如果您觀察到來自 Job 的 Pod 卡在追蹤 Finalizer 中,請參閱我的 Pod 保持在終止中。彈性索引 Job
Kubernetes v1.31 [stable]
(預設啟用:true)您可以同時變更 .spec.parallelism
和 .spec.completions
來擴增或縮減索引 Job,使得 .spec.parallelism == .spec.completions
。縮減時,Kubernetes 會移除索引較高的 Pod。
彈性索引 Job 的使用案例包括需要擴展索引 Job 的批次工作負載,例如 MPI、Horovod、Ray 和 PyTorch 訓練 Job。
延遲建立替換 Pod
Kubernetes v1.29 [beta]
預設情況下,Job 控制器會在 Pod 失敗或終止(具有刪除時間戳記)後立即重新建立 Pod。這表示,在給定時間,當某些 Pod 正在終止時,Job 的執行中 Pod 數量可能大於 parallelism
或每個索引一個 Pod(如果您正在使用索引 Job)。
您可以選擇僅在終止 Pod 完全終止(具有 status.phase: Failed
)時才建立替換 Pod。若要執行此操作,請設定 .spec.podReplacementPolicy: Failed
。預設替換策略取決於 Job 是否設定了 podFailurePolicy
。如果未為 Job 定義 Pod 失敗策略,則省略 podReplacementPolicy
欄位會選取 TerminatingOrFailed
替換策略:控制平面會在 Pod 刪除時立即建立替換 Pod(一旦控制平面看到此 Job 的 Pod 已設定 deletionTimestamp
)。對於設定了 Pod 失敗策略的 Job,預設 podReplacementPolicy
為 Failed
,並且不允許其他值。請參閱Pod 失敗策略以瞭解有關 Job 的 Pod 失敗策略的更多資訊。
kind: Job
metadata:
name: new
...
spec:
podReplacementPolicy: Failed
...
如果您的叢集已啟用功能閘道,您可以檢查 Job 的 .status.terminating
欄位。該欄位的值是 Job 擁有的目前正在終止的 Pod 數量。
kubectl get jobs/myjob -o yaml
apiVersion: batch/v1
kind: Job
# .metadata and .spec omitted
status:
terminating: 3 # three Pods are terminating and have not yet reached the Failed phase
將 Job 物件的管理委派給外部控制器
Kubernetes v1.32 [Beta 版]
(預設為停用:false)此功能允許您針對特定 Job 停用內建 Job 控制器,並將 Job 的協調委派給外部控制器。
您可以透過為 spec.managedBy
欄位設定自訂值(kubernetes.io/job-controller 以外的任何值)來指示協調 Job 的控制器。欄位的值是不可變的。
注意
使用此功能時,請確保已安裝欄位指示的控制器,否則可能根本不會協調 Job。注意
在開發外部 Job 控制器時,請注意您的控制器需要以符合 Job 物件的 API 規格和狀態欄位定義的方式運作。
請在Job API 中詳細檢閱這些內容。我們也建議您執行 Job 物件的 e2e 一致性測試,以驗證您的實作。
最後,在開發外部 Job 控制器時,請確保它不使用 batch.kubernetes.io/job-tracking
Finalizer,此 Finalizer 保留給內建控制器。
警告
如果您正在考慮停用JobManagedBy
功能閘道,或將叢集降級到未啟用功能閘道的版本,請檢查是否有名為 spec.managedBy
欄位的自訂值的 Job。如果有此類 Job,則在操作後,它們可能由兩個控制器協調:內建 Job 控制器和欄位值指示的外部控制器。替代方案
裸 Pod
當 Pod 執行的節點重新啟動或失敗時,Pod 會終止且不會重新啟動。但是,Job 會建立新的 Pod 來替換終止的 Pod。因此,即使您的應用程式僅需要單一 Pod,我們也建議您使用 Job 而不是裸 Pod。
Replication Controller
Job 是Replication Controller 的補充。Replication Controller 管理預期不會終止的 Pod(例如 Web 伺服器),而 Job 管理預期會終止的 Pod(例如批次任務)。
如Pod 生命周期中所討論,Job
僅適用於 RestartPolicy
等於 OnFailure
或 Never
的 Pod。(注意:如果未設定 RestartPolicy
,則預設值為 Always
。)
單一 Job 啟動控制器 Pod
另一種模式是讓單一 Job 建立一個 Pod,然後該 Pod 建立其他 Pod,充當這些 Pod 的自訂控制器。這提供了最大的彈性,但入門可能有些複雜,並且與 Kubernetes 的整合較少。
此模式的一個範例是 Job 啟動一個 Pod,該 Pod 執行一個腳本,該腳本又啟動 Spark master 控制器(請參閱Spark 範例)、執行 Spark 驅動程式,然後清理。
這種方法的優點是整體流程獲得了 Job 物件的完成保證,但保持了對建立哪些 Pod 以及如何將工作分配給它們的完全控制。
下一步
- 瞭解有關Pod的資訊。
- 閱讀有關執行 Job 的不同方式
- 使用工作佇列進行粗略平行處理
- 使用工作佇列進行精細平行處理
- 使用索引 Job 進行具有靜態工作分配的平行處理
- 根據範本建立多個 Job:使用擴展進行平行處理
- 追蹤自動清理已完成的 Job內的連結,以瞭解有關您的叢集如何清理已完成和/或失敗任務的更多資訊。
Job
是 Kubernetes REST API 的一部分。閱讀Job 物件定義,以瞭解 Job 的 API。- 閱讀有關
CronJob
的資訊,您可以使用它來定義一系列將根據排程執行的 Job,類似於 UNIX 工具cron
。 - 根據逐步範例,練習如何設定可重試和不可重試 Pod 失敗的處理方式,使用
podFailurePolicy
。