job和cronjob的使用
我們在工作中會遇到需要批量處理數據和分析的需求,也會有按時間來進行調度的工作,在k8s集群中,有job和cronjob兩中資源對象來映帶我們的這種需要。
job負責處理任務,僅執行一次的任務,他保證批處理任務的一個或多個pod成功結束。而cronjob則就是在job上加上了時間調度,相當於定時任務。
Job
運行一個官方job示例,計算π到2000位,大約需要10秒鍾:
apiVersion: batch/v1
kind: Jobs
metadata:
name: pi
spec:
template:
backoffLimit: 6 #默認重試6次后才認為執行失敗
activeDeadlineSeconds: 100 #重試工作的持續時間,優先級別高於backoffLimit
spec:
restartPolicy: Never #job只有兩種重啟策略,Never、OnFailure不支持Always,失敗狀態會陷入失敗死循環
containers:
- name: pi
image: perl
command:
- perl
- Mbignum=bpi
- wle
- print bpip(2000)
# 請注意,作業的.spec.activeDeadlineSeconds優先於.spec.backoffLimit。因此,重試一個或多個失敗Pod的Job一旦達到所指定的時間限制activeDeadlineSeconds,就不會部署其他Pod ,即使backoffLimit尚未達到。
parallel(並行) Jobs
適應job運行的三種模式:
-
Non-parallel(非並行) Jobs
- 通常情況,除非pod發生故障,否則僅啟動一個pod
- pod運行成功后,job成complate狀態
-
固定parallel(並行)Jobs一個完成次數
.spec.completion指定一個非零的正值
job是整體任務,在1到范圍內的每個值都有一個成功的Pod時完成 .spec.completions
-
具有工作隊列的parallel(並行)Jobs
- 不指定 .spec.completions ,默認為 .spec.parallelism
- pod必須在彼此之間或外部服務之間進行協調,以確定每個pod應該如何處理。例如一個pod可以從工作隊列中最多獲取N批的批處理
- 每個pod都可以獨立地確定其所有對等方是否都已完成,從而確定整個pod狀態
- 當jobs中任何pod成功終止時,不會創建新的pod
- 所有pod成功終止,則jobs完成
- pod成功推出后,其他pod不應該為此任務再做任何工作或編寫任何輸出。他們都應該退出
對於非並行jobs,您可以同時保留.spec.completions和不.spec.parallelism設置。兩者均未設置時,均默認為1。
對於固定的完成計數jobs,您應該設置.spec.completions為所需的完成數量。您可以設置.spec.parallelism,或不設置它,默認為1。
對於工作隊列 Job,您必須保持未.spec.completions設置狀態,並將其設置.spec.parallelism為非負整數。
有關如何利用不同類型的jobs的更多信息,請參見jobs模式部分。
處理Pod和容器故障
Pod中的容器可能由於多種原因而失敗,例如,由於該容器中的進程以非零退出代碼退出,或者該容器因超出內存限制而被殺死等。如果發生這種情況,請使用.spec.template.spec.restartPolicy = "OnFailure",然后Pod停留在節點上,但是容器重新運行。因此,您的程序需要在本地重新啟動時處理該情況,或者指定.spec.template.spec.restartPolicy = "Never"。有關的更多信息,請參見pod生命周期restartPolicy。
Pod后退失敗策略
在某些情況下,由於配置中的邏輯錯誤等原因,您需要在重試一定次數后使jobs失敗。為此,設置.spec.backoffLimit為指定重試次數,然后再將jobs視為失敗。默認情況下,將退避限制設置為6。與jobs相關聯的失敗Pod由Job控制器重新創建,並且其指數退避延遲(10s,20s,40s…)限制為六分鍾。如果在jobs的下一個狀態檢查之前未出現新的失敗Pod,則會重置退避計數。
注意:版本1.12之前的Kubernetes版本仍然存在問題#54870
注意:如果您的jobs具有
restartPolicy = "OnFailure",請記住,一旦達到jobs退避限制,運行該jobs的容器將被終止。這會使調試jobs的可執行文件更加困難。我們建議restartPolicy = "Never"在調試jobs或使用日志記錄系統時進行設置 ,以確保不會因疏忽而丟失失敗的jobs的輸出。
請注意,作業的.spec.activeDeadlineSeconds優先於.spec.backoffLimit。因此,重試一個或多個失敗Pod的Job一旦達到所指定的時間限制activeDeadlineSeconds,就不會部署其他Pod ,即使backoffLimit尚未達到。
CronJob
CronJob其實就是在Job的基礎上加上了時間調度,我們可以:在給定的時間點運行一個任務,也可以周期性地在給定時間點運行。這個實際上和我們Linux中的crontab就非常類似了。
一個CronJob對象其實就對應中crontab文件中的一行,它根據配置的時間格式周期性地運行一個Job,格式和crontab也是一樣的。
crontab的格式如下:
分 時 日 月 星期 要運行的命令 第1列分鍾0~59 第2列小時0~23) 第3列日1~31 第4列月1~12 第5列星期0~7(0和7表示星期天) 第6列要運行的命令
現在,我們用CronJob來管理我們上面的Job任務,
apiVersion: batch/v2alpha1
kind: CronJob
metadata:
name: cronjob-demo
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: hello
image: busybox
args:
- "bin/sh"
- "-c"
- "for i in 9 8 7 6 5 4 3 2 1; do echo $i; done"
我們這里的Kind是CronJob了,要注意的是.spec.schedule字段是必須填寫的,用來指定任務運行的周期,格式就和crontab一樣,另外一個字段是.spec.jobTemplate, 用來指定需要運行的任務,格式當然和Job是一致的。還有一些值得我們關注的字段.spec.successfulJobsHistoryLimit和.spec.failedJobsHistoryLimit,表示歷史限制,是可選的字段。它們指定了可以保留多少完成和失敗的Job,默認沒有限制,所有成功和失敗的Job都會被保留。然而,當運行一個Cron Job時,Job可以很快就堆積很多,所以一般推薦設置這兩個字段的值。如果設置限制的值為 0,那么相關類型的Job完成后將不會被保留。
