1、失敗任務
apiVersion: batch/v1 kind: Job metadata: name: bad spec: template: metadata: name: bad spec: restartPolicy: Never containers: - name: box image: busybox command: ["/bin/sh", "-c", "exit 1"]
如果你嘗試在你的cluster里面創建以上的Job,你可能會碰到如下的狀態。
$ kubectl describe jobs Name: bad Namespace: default Image(s): busybox Selector: controller-uid=18a6678e-11d1-11e7-8169-525400c83acf Parallelism: 1 Completions: 1 Start Time: Sat, 25 Mar 2017 20:05:41 -0700 Labels: controller-uid=18a6678e-11d1-11e7-8169-525400c83acf job-name=bad Pods Statuses: 1 Running / 0 Succeeded / 24 Failed No volumes. Events: FirstSeen LastSeen Count From SubObjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 1m 1m 1 {job-controller } Normal SuccessfulCreate Created pod: bad-fws8g 1m 1m 1 {job-controller } Normal SuccessfulCreate Created pod: bad-321pk 1m 1m 1 {job-controller } Normal SuccessfulCreate Created pod: bad-2pxq1 1m 1m 1 {job-controller } Normal SuccessfulCreate Created pod: bad-kl2tj 1m 1m 1 {job-controller } Normal SuccessfulCreate Created pod: bad-wfw8q 1m 1m 1 {job-controller } Normal SuccessfulCreate Created pod: bad-lz0hq 1m 1m 1 {job-controller } Normal SuccessfulCreate Created pod: bad-0dck0 1m 1m 1 {job-controller } Normal SuccessfulCreate Created pod: bad-0lm8k 1m 1m 1 {job-controller } Normal SuccessfulCreate Created pod: bad-q6ctf 1m 1s 16 {job-controller } Normal SuccessfulCreate (events with common reason combined)
因為任務快速失敗。Kubernetes認為任務沒能成功啟動,嘗試創建新的容器以恢復這個失敗,導致的Cluster會在短時間創建大量的容器,這樣的結果可能會消耗大量的計算資源。
2、問題處理
apiVersion: batch/v1 kind: Job metadata: name: bad spec: # 指定失敗時可以重試5次 backoffLimit: 5 # 指定存活時長 activeDeadlineSeconds: 100 template: metadata: name: bad spec: restartPolicy: Never containers: - name: box image: busybox command: ["/bin/sh", "-c", "exit 1"]
在Spec中使用.spec.activeDeadlineSeconds來避免這個問題。這個參數定了等待多長時間重試失敗的Job。
其他的差不多,Job對象需要apiVersion
、kind
和metadata
字段,同樣需要.spec
:
- Pod Template:
.spec.template
是.spec
必要的字段,是創建Pod的模板,和pod中的模式一樣,除了它是嵌套的沒有apiVersion
或kind
,此外還需要Pod的字段,Job中的pod template必須指定合適的標簽和重啟策略,RestartPolicy
只能設置為Never
或OnFailure
; - Pod Selector:
.spec.selector
是可選參數,一般不需要指定; - Parallel Jobs:主要有3種類型的task合適作為Job運行:
- 非並行Job(Non-parallel):正常只有一個Pod啟動(除非Pod失敗),一旦pod成功終止,Job就完成了;
- 固定計數的並行Job:為
.spec.completions
指定一個非0整數,一個Job代表多個task,在1到.spec.completions
范圍內的每個值都有一個成功的pod時完成;
- 具有work queue的並行Job:不需要指定
.spec.completions
(默認為.spec.parallelism
),Pod之間自我協調或通過額外的Service決定在哪個Pod上運行,一個pod可以從work queue中獲取一批最多n個元素。每個Pod能夠獨立決定是否完成了對等的任務,因此整個Job完成。當Job中的任意一個Pod完成task成功結束,將不會再創建新的Pod,當最后一個Pod結束時,就意味着所有的Pod都停止了,這時Job完成。
注:
- 對於
non-parallel
Job,可以不設置.spec.completions
和.spec.parallelism
參數(此時它們的默認值為1); - 對於
fixed completion count
Job,需要設置對應的.spec.completions
,此外也可以設置.spec.parallelism
(不設置默認為1); - 對於
work queue
Job,.spec.completions
參數不能設置,.spec.parallelism
對應設置為非負整數; .spec.parallelism
表示並行度(默認為1),當指定為0時,Job將停止直到這個數值增加,但實際的並行度可能會和請求的不一樣。在固定計數的並行Job中,實際並行的Pod數量不會超過剩余數量,.spec.parallelism
將會被忽略;在work queue的並行Job中在Job完成后將不會在啟動新的Pod,但允許剩余Pod執行完成;此外如果Controller創建Pod失敗可能會導實際的Pod比請求的少。
【Pod和Container失敗】
如果Pod失敗了且.spec.template.spec.restartPolicy = "OnFailure"
,Pod將會殘留在節點上,但container是會重新運行的,因此當本地重啟可能需要解決這樣的問題或者指定.spec.template.spec.restartPolicy = "Never"
。對於失敗的策略,比如由於配置文件錯誤的原因在重試過指定次數后直接讓整個Job失敗,back-off限制值.spec.backoffLimit
默認為6,和Job相關的失敗Pod會由Job Controller進行back-off(每次back-off的時間間隔會逐漸增大10s、20s、40s,封頂6min)。
【自動清理已完成的Job】
通常已完成的Job對象需要進行清理,否則會對API Server造成壓力,如果Job是由更高級別的controller管理(比如CronJobs),那Job將會基於指定的容量清理策略被CronJobs清理
3、Cronjob
Cron Job是基於時間進行調度的,CronJob對象就像一行crontab文件,它會在給定的時間定期(以cron格式編寫)地運行一個Job。一個Cron Job創建Job對象基於它的調度執行時間,當然也有可能0個或2個Job會被創建,這些目前都不是確定的,因此Job之間應該保證冪等性,startingDeadlineSeconds
設置為大一點的值或者不設置讓其默認且concurrencyPolicy
設置為Allow
,Job應該至少運行一次。對於CronJob,CronJob Controller將會檢查從上一次調度到現在將會錯過多少調度,如果錯過超過了100個,那它將不會再啟動Job並記錄錯誤:Cannot determine if job needs to be started. Too many missed start time (> 100). Set or decrease .spec.startingDeadlineSeconds or check clock skew.
。如果startingDeadlineSeconds
字段設置了但不是nil
,Controller從startingDeadlineSeconds
開始計算直到現在(即之前的時間內,並不是上次調度到現在)。比如,如果startingDeadlineSeconds
設置為200
,控制器將會計算在剛剛過去的200s中錯失了多少Job。
CronJob是從它在調度時間內創建失敗進行計算的,比如,concurrencyPolicy
設置為Forbid
,CronJob將會嘗試調度,如果之前的調度仍在運行,那么它將被視為錯過。