Kubernetes K8S之資源控制器Job和CronJob詳解

 

Kubernetes的資源控制器Job和CronJob詳解與示例

 

主機配置規劃

伺服器名稱(hostname) 系統版本 配置 內網IP 外網IP(模擬)
k8s-master CentOS7.7 2C/4G/20G 172.16.1.110 10.0.0.110
k8s-node01 CentOS7.7 2C/4G/20G 172.16.1.111 10.0.0.111
k8s-node02 CentOS7.7 2C/4G/20G 172.16.1.112 10.0.0.112

 

什麼是控制器

kubernetes中內建了很多controller(控制器),這些相當於一個狀態機,用來控制pod的具體狀態和行為。

部分控制器類型如下:
  • ReplicationController 和 ReplicaSet
  • Deployment
  • DaemonSet
  • StatefulSet
  • Job/CronJob
  • HorizontalPodAutoscaler

 

Job

負責批處理任務

Job創建一個或多個Pod,並確保指定數量的Pod成功終止。Pod成功完成後,Job將跟蹤成功完成的情況。當達到指定的成功完成次數時,任務(即Job)就完成了。刪除Job將清除其創建的Pod。

一個簡單的情況是創建一個Job對象,以便可靠地運行一個Pod來完成。如果第一個Pod發生故障或被刪除(例如,由於節點硬體故障或節點重啟),則Job對象將啟動一個新的Pod。

當然還可以使用Job並行運行多個Pod。

 

Job終止和清理

Job完成後,不會再創建其他Pod,但是Pod也不會被刪除。這樣使我們仍然可以查看已完成容器的日誌,以檢查是否有錯誤、警告或其他診斷輸出。Job對象在完成後也將保留下來,以便您查看其狀態。

當我們刪除Job對象時,對應的pod也會被刪除。

特殊說明

  • 單個Pod時,默認Pod成功運行後Job即結束
  • restartPolicy 僅支援Never和OnFailure
  • .spec.completions 標識Job結束所需要成功運行的Pod個數,默認為1
  • .spec.parallelism 標識並行運行的Pod個數,默認為1
  • .spec.activeDeadlineSeconds 為Job的持續時間,不管有多少Pod創建。一旦工作到指定時間,所有的運行pod都會終止且工作狀態將成為type: Failed與reason: DeadlineExceeded。

 

CronJob

Cron Job 創建是基於時間調度的 Jobs

一個 CronJob 對象就像 crontab (cron table) 文件中的一行。它用 Cron 格式進行編寫,並周期性地在給定的調度時間執行 Job。

 

CronJob 限制

CronJob 創建 Job 對象,每個 Job 的執行次數大約為一次。 之所以說 「大約」 ,是因為在某些情況下,可能會創建兩個 Job,或者不會創建任何 Job。雖然試圖使這些情況盡量少發生,但不能完全杜絕。因此,Job 應該是冪等的。

CronJob 僅負責創建與其調度時間相匹配的 Job,而 Job 又負責管理其代表的 Pod。

使用案例:

1、在給定時間點調度Job

2、創建周期性運行的Job。如:數據備份、數倉導數、執行任務、郵件發送、數據拉取、數據推送

 

特殊說明

.spec.schedule 必選,任務被創建和執行的調度時間。同Cron格式串,例如 0 * * * *。

  • .spec.jobTemplate 必選,任務模版。它和 Job的語法完全一樣
  • .spec.startingDeadlineSeconds 可選的。默認未設置。它表示任務如果由於某種原因錯過了調度時間,開始該任務的截止時間的秒數。過了截止時間,CronJob 就不會開始任務。不滿足這種最後期限的任務會被統計為失敗任務。如果沒有該聲明,那任務就沒有最後期限。
  • .spec.concurrencyPolicy 可選的。它聲明了 CronJob 創建的任務執行時發生重疊如何處理。spec 僅能聲明下列規則中的一種:

Allow (默認):CronJob 允許並發任務執行。

Forbid:CronJob 不允許並發任務執行;如果新任務的執行時間到了而老任務沒有執行完,CronJob 會忽略新任務的執行。

Replace:如果新任務的執行時間到了而老任務沒有執行完,CronJob 會用新任務替換當前正在運行的任務。

請注意,並發性規則僅適用於相同 CronJob 創建的任務。如果有多個 CronJob,它們相應的任務總是允許並發執行的。

  • .spec.suspend 可選的。如果設置為 true ,後續發生的執行都會掛起。這個設置對已經開始執行的Job不起作用。默認是關閉的false。
    備註:在調度時間內掛起的執行都會被統計為錯過的任務。當 .spec.suspend 從 true 改為 false 時,且沒有開始的最後期限,錯過的任務會被立即調度。
  • .spec.successfulJobsHistoryLimit 和 .spec.failedJobsHistoryLimit 可選的。 這兩個聲明了有多少執行完成和失敗的任務會被保留。默認設置為3和1。限制設置為0代表相應類型的任務完成後不會保留。

說明:如果 startingDeadlineSeconds 設置為很大的數值或未設置(默認),並且 concurrencyPolicy 設置為 Allow,則作業將始終至少運行一次。

 

Job示例

yaml文件

 1 [root@k8s-master controller]# pwd
 2 /root/k8s_practice/controller
 3 [root@k8s-master controller]# cat job.yaml 
 4 apiVersion: batch/v1
 5 kind: Job
 6 metadata:
 7   name: pi
 8 spec:
 9   #completions: 3  # 標識Job結束所需要成功運行的Pod個數,默認為1
10   template:
11     spec:
12       containers:
13       - name: pi
14         image: registry.cn-beijing.aliyuncs.com/google_registry/perl:5.26
15         command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
16       restartPolicy: Never
17   backoffLimit: 4

 

創建job,與狀態查看

1 [root@k8s-master controller]# kubectl apply -f job.yaml 
2 job.batch/pi created
3 [root@k8s-master controller]# kubectl get job -o wide
4 NAME   COMPLETIONS   DURATION   AGE   CONTAINERS   IMAGES                                                       SELECTOR
5 pi     0/1           16s        16s   pi           registry.cn-beijing.aliyuncs.com/google_registry/perl:5.26   controller-uid=77004357-fd5e-4395-9bbb-cd0698e19cb9
6 [root@k8s-master controller]# kubectl get pod -o wide
7 NAME       READY   STATUS              RESTARTS   AGE   IP       NODE         NOMINATED NODE   READINESS GATES
8 pi-6zvm5   0/1     ContainerCreating   0          85s   <none>   k8s-node01   <none>           <none>

 

之後再次查看

 1 [root@k8s-master controller]# kubectl get job -o wide
 2 NAME   COMPLETIONS   DURATION   AGE   CONTAINERS   IMAGES                                                       SELECTOR
 3 pi     1/1           14m        44m   pi           registry.cn-beijing.aliyuncs.com/google_registry/perl:5.26   controller-uid=77004357-fd5e-4395-9bbb-cd0698e19cb9
 4 [root@k8s-master controller]# kubectl get pod -o wide
 5 NAME       READY   STATUS      RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
 6 pi-6zvm5   0/1     Completed   0          44m   10.244.4.63   k8s-node01   <none>           <none>
 7 [root@k8s-master controller]# 
 8 [root@k8s-master controller]# kubectl describe job pi
 9 Name:           pi
10 Namespace:      default
11 Selector:       controller-uid=76680f6f-442c-4a09-91dc-c3d4c18465b0
12 Labels:         controller-uid=76680f6f-442c-4a09-91dc-c3d4c18465b0
13                 job-name=pi
14 Annotations:    kubectl.kubernetes.io/last-applied-configuration:
15                   {"apiVersion":"batch/v1","kind":"Job","metadata":{"annotations":{},"name":"pi","namespace":"default"},"spec":{"backoffLimit":4,"
16 Parallelism:    1
17 Completions:    1
18 Start Time:     Tue, 11 Aug 2020 23:34:44 +0800
19 Completed At:   Tue, 11 Aug 2020 23:35:02 +0800
20 Duration:       18s
21 Pods Statuses:  0 Running / 1 Succeeded / 0 Failed
22 Pod Template:
23   Labels:  controller-uid=76680f6f-442c-4a09-91dc-c3d4c18465b0
24            job-name=pi
25   Containers:
26    pi:
27     Image:      registry.cn-beijing.aliyuncs.com/google_registry/perl:5.26
28     Port:       <none>
29     Host Port:  <none>
30     Command:
31       perl
32       -Mbignum=bpi
33       -wle
34       print bpi(2000)
35     Environment:  <none>
36     Mounts:       <none>
37   Volumes:        <none>
38 Events:
39   Type    Reason            Age    From            Message
40   ----    ------            ----   ----            -------
41   Normal  SuccessfulCreate  2m33s  job-controller  Created pod: pi-6zvm5

 

並查看 Pod 的標準輸出

1 [root@k8s-master controller]# kubectl logs --tail 500 pi-6zvm5
2 3.141592653589793238462643383279502884197169399375105820974944592307816406………………

 

CronJob示例

yaml文件

 1 [root@k8s-master controller]# pwd
 2 /root/k8s_practice/controller
 3 [root@k8s-master controller]# cat cronjob.yaml 
 4 apiVersion: batch/v1beta1
 5 kind: CronJob
 6 metadata:
 7   name: hello
 8 spec:
 9   schedule: "*/1 * * * *"
10   jobTemplate:
11     spec:
12       template:
13         spec:
14           containers:
15           - name: hello
16             image: registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24
17             args:
18             - /bin/sh
19             - -c
20             - date; echo Hello from the Kubernetes cluster
21           restartPolicy: OnFailure

 

啟動cronjob並查看狀態

 1 [root@k8s-master controller]# kubectl apply -f cronjob.yaml 
 2 cronjob.batch/hello created
 3 [root@k8s-master controller]# kubectl get cronjob -o wide
 4 NAME    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE   CONTAINERS   IMAGES                                                          SELECTOR
 5 hello   */1 * * * *   False     1        8s              27s   hello        registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24   <none>
 6 [root@k8s-master controller]# 
 7 [root@k8s-master controller]# kubectl get job -o wide
 8 NAME               COMPLETIONS   DURATION   AGE   CONTAINERS   IMAGES                                                          SELECTOR
 9 hello-1590721020   1/1           2s         21s   hello        registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24   controller-uid=9e0180e8-8362-4a58-8b93-089b92774b5e
10 [root@k8s-master controller]# 
11 [root@k8s-master controller]# kubectl get pod -o wide
12 NAME                     READY   STATUS      RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
13 hello-1590721020-m4fr8   0/1     Completed   0          36s   10.244.4.66   k8s-node01   <none>           <none>

 

幾分鐘之後的狀態資訊

 1 [root@k8s-master controller]# kubectl get cronjob -o wide
 2 NAME    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE     CONTAINERS   IMAGES                                                          SELECTOR
 3 hello   */1 * * * *   False     0        55s             7m14s   hello        registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24   <none>
 4 [root@k8s-master controller]# 
 5 [root@k8s-master controller]# 
 6 [root@k8s-master controller]# kubectl get job -o wide
 7 NAME               COMPLETIONS   DURATION   AGE    CONTAINERS   IMAGES                                                          SELECTOR
 8 hello-1590721260   1/1           1s         3m1s   hello        registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24   controller-uid=0676bd6d-861b-440b-945b-4b2704872728
 9 hello-1590721320   1/1           2s         2m1s   hello        registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24   controller-uid=09c1902e-76ef-4731-b3b4-3188961c13e9
10 hello-1590721380   1/1           2s         61s    hello        registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24   controller-uid=f30dc159-8905-4cfc-b06b-f950c8dcfc28
11 [root@k8s-master controller]# 
12 [root@k8s-master controller]# kubectl get pod -o wide
13 NAME                     READY   STATUS      RESTARTS   AGE    IP            NODE         NOMINATED NODE   READINESS GATES
14 hello-1590721320-m4pxf   0/1     Completed   0          2m6s   10.244.4.70   k8s-node01   <none>           <none>
15 hello-1590721380-wk7jh   0/1     Completed   0          66s    10.244.2.77   k8s-node02   <none>           <none>
16 hello-1590721440-rcx7v   0/1     Completed   0          6s     10.244.4.72   k8s-node01   <none>           <none>
17 [root@k8s-master controller]# 
18 [root@k8s-master controller]# kubectl describe cronjob hello
19 Name:                          hello
20 Namespace:                     default
21 Labels:                        <none>
22 Annotations:                   kubectl.kubernetes.io/last-applied-configuration:
23                                  {"apiVersion":"batch/v1beta1","kind":"CronJob","metadata":{"annotations":{},"name":"hello","namespace":"default"},"spec":{"jobTemplate":{"...
24 Schedule:                      */1 * * * *
25 Concurrency Policy:            Allow
26 Suspend:                       False
27 Successful Job History Limit:  3
28 Failed Job History Limit:      1
29 Starting Deadline Seconds:     <unset>
30 Selector:                      <unset>
31 Parallelism:                   <unset>
32 Completions:                   <unset>
33 Pod Template:
34   Labels:  <none>
35   Containers:
36    hello:
37     Image:      registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24
38     Port:       <none>
39     Host Port:  <none>
40     Args:
41       /bin/sh
42       -c
43       date; echo Hello from the Kubernetes cluster
44     Environment:     <none>
45     Mounts:          <none>
46   Volumes:           <none>
47 Last Schedule Time:  Wed, 12 Aug 2020 00:01:00 +0800
48 Active Jobs:         <none>
49 Events:
50   Type    Reason            Age                  From                Message
51   ----    ------            ----                 ----                -------
52   Normal  SuccessfulCreate  19m                  cronjob-controller  Created job hello-1597160520
53   Normal  SawCompletedJob   19m                  cronjob-controller  Saw completed job: hello-1597160520, status: Complete
54   Normal  SuccessfulCreate  18m                  cronjob-controller  Created job hello-1597160580
55   Normal  SawCompletedJob   18m                  cronjob-controller  Saw completed job: hello-1597160580, status: Complete
56   Normal  SuccessfulCreate  17m                  cronjob-controller  Created job hello-1597160640
57   Normal  SawCompletedJob   17m                  cronjob-controller  Saw completed job: hello-1597160640, status: Complete
58   Normal  SuccessfulCreate  16m                  cronjob-controller  Created job hello-1597160700
59   Normal  SuccessfulDelete  16m                  cronjob-controller  Deleted job hello-1597160520
60   Normal  SawCompletedJob   16m                  cronjob-controller  Saw completed job: hello-1597160700, status: Complete
61   Normal  SuccessfulCreate  15m                  cronjob-controller  Created job hello-1597160760
62   Normal  SawCompletedJob   15m                  cronjob-controller  Saw completed job: hello-1597160760, status: Complete
63   Normal  SuccessfulDelete  15m                  cronjob-controller  Deleted job hello-1597160580
64   Normal  SuccessfulCreate  14m                  cronjob-controller  Created job hello-1597160820
65   Normal  SuccessfulDelete  14m                  cronjob-controller  Deleted job hello-1597160640
66   Normal  SawCompletedJob   14m                  cronjob-controller  Saw completed job: hello-1597160820, status: Complete
67   Normal  SuccessfulCreate  13m                  cronjob-controller  Created job hello-1597160880
68   Normal  SawCompletedJob   13m                  cronjob-controller  Saw completed job: hello-1597160880, status: Complete
69 ………………
70   Normal  SawCompletedJob   11m                  cronjob-controller  Saw completed job: hello-1597161000, status: Complete
71   Normal  SuccessfulDelete  11m                  cronjob-controller  Deleted job hello-1597160820
72   Normal  SawCompletedJob   10m                  cronjob-controller  (combined from similar events): Saw completed job: hello-1597161060, status: Complete
73   Normal  SuccessfulCreate  4m13s (x7 over 10m)  cronjob-controller  (combined from similar events): Created job hello-1597161420

 

找到最後一次調度任務創建的 Pod, 並查看 Pod 的標準輸出。請注意任務名稱和 Pod 名稱是不同的。

1 [root@k8s-master controller]#  kubectl logs pod/hello-1590721740-rcx7v   # 或者 kubectl logs hello-1590721740-rcx7v
2 Fri May 29 03:09:04 UTC 2020
3 Hello from the Kubernetes cluster

 

刪除 CronJob

1 [root@k8s-master controller]# kubectl get cronjob
2 NAME    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
3 hello   */1 * * * *   False     0        32s             19m
4 [root@k8s-master controller]# 
5 [root@k8s-master controller]# kubectl delete cronjob hello  # 或者 kubectl delete -f cronjob.yaml
6 cronjob.batch "hello" deleted
7 [root@k8s-master controller]# kubectl get cronjob   # 可見已刪除
8 No resources found in default namespace.

 

相關閱讀

1、Kubernetes K8S之資源控制器RC、RS、Deployment詳解

2、Kubernetes K8S之資源控制器StatefulSets詳解

3、Kubernetes K8S之資源控制器Daemonset詳解

4、官網:Jobs

5、官網:CronJob

 

完畢!

 


 

 

———END———
如果覺得不錯就關注下唄 (-^O^-) !