【原創】k8s之job和Cronjob


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對象需要apiVersionkindmetadata字段,同樣需要.spec

  1. Pod Template:.spec.template.spec必要的字段,是創建Pod的模板,和pod中的模式一樣,除了它是嵌套的沒有apiVersionkind,此外還需要Pod的字段,Job中的pod template必須指定合適的標簽和重啟策略,RestartPolicy只能設置為NeverOnFailure
  2. Pod Selector:.spec.selector是可選參數,一般不需要指定;
  3. Parallel Jobs:主要有3種類型的task合適作為Job運行:
    1. 非並行Job(Non-parallel):正常只有一個Pod啟動(除非Pod失敗),一旦pod成功終止,Job就完成了;
    2. 固定計數的並行Job:為.spec.completions指定一個非0整數,一個Job代表多個task,在1到.spec.completions范圍內的每個值都有一個成功的pod時完成;
  4. 具有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將會嘗試調度,如果之前的調度仍在運行,那么它將被視為錯過。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM