0%

K8s学习笔记——Job与CronJob

学习极客时间上的《深入剖析Kubernetes》

秉持眼过千遍不如手过一遍的原则。动手实践并记录结果

对应章节:22 | 撬动离线业务:Job与CronJob

Job

创建Job

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: batch/v1
kind: Job
metadata:
name: my-job
spec:
template:
spec:
containers:
- name: hello
image: busybox
imagePullPolicy: IfNotPresent
command: ["echo", " hello, Job"]
restartPolicy: Never
1
2
3
$ kubectl get jobs -o wide
NAME COMPLETIONS DURATION AGE CONTAINERS IMAGES SELECTOR
my-job 1/1 3s 102s hello busybox controller-uid=c85adfa3-f52f-40f7-a772-cab087df71cf
1
2
3
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
my-job-d4rnl 0/1 Completed 0 2m4s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
$ kubectl describe pod my-job-d4rnl
Name: my-job-d4rnl
Namespace: default
Priority: 0
Node: k8s-node4/10.160.18.184
Start Time: Mon, 03 Aug 2020 14:05:42 +0800
Labels: controller-uid=c85adfa3-f52f-40f7-a772-cab087df71cf
job-name=my-job
Annotations: <none>
Status: Succeeded
IP: 172.1.3.12
IPs:
IP: 172.1.3.12
Controlled By: Job/my-job
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m43s default-scheduler Successfully assigned default/my-job-d4rnl to k8s-node4
Normal Pulled 2m42s kubelet, k8s-node4 Container image "busybox" already present on machine
Normal Created 2m41s kubelet, k8s-node4 Created container hello
Normal Started 2m41s kubelet, k8s-node4 Started container hello

$ kubectl describe jobs my-job
Name: my-job
Namespace: default
Selector: controller-uid=c85adfa3-f52f-40f7-a772-cab087df71cf
Labels: controller-uid=c85adfa3-f52f-40f7-a772-cab087df71cf
job-name=my-job
Annotations: Parallelism: 1
Completions: 1
Start Time: Mon, 03 Aug 2020 14:05:41 +0800
Completed At: Mon, 03 Aug 2020 14:05:44 +0800
Duration: 3s
Pods Statuses: 0 Running / 1 Succeeded / 0 Failed
Pod Template:
Labels: controller-uid=c85adfa3-f52f-40f7-a772-cab087df71cf
job-name=my-job
Containers:
hello:
Image: busybox
Port: <none>
Host Port: <none>
Command:
echo
hello, Job
Environment: <none>
Mounts: <none>
Volumes: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 3m56s job-controller Created pod: my-job-d4rnl
Normal Completed 3m54s job-controller Job completed

$ kubectl logs my-job-d4rnl
hello, Job

分析

Job创建后,pod模版中添加了一个controller-uid为一个随机字符串的label,而job则拥有一个同样id的selector

而job完成后,进入了completed的状态

删除对应的pod

1
2
$ kubectl delete pod my-job-d4rnl
pod "my-job-d4rnl" deleted

删除对应的pod后,会发现没有再创建新的pod

错误的job

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: batch/v1
kind: Job
metadata:
name: my-job
spec:
template:
spec:
containers:
- name: hello
image: busybox
imagePullPolicy: IfNotPresent
command: ["exit 1"]
restartPolicy: Never
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
$ kubectl get jobs -o wide
NAME COMPLETIONS DURATION AGE CONTAINERS IMAGES SELECTOR
my-job 0/1 54s 54s hello busybox controller-uid=9ac8a40c-1548-4683-bbd6-870a236199bf
$ kubectl describe job my-job
Name: my-job
Namespace: default
Selector: controller-uid=9ac8a40c-1548-4683-bbd6-870a236199bf
Labels: controller-uid=9ac8a40c-1548-4683-bbd6-870a236199bf
job-name=my-job
Annotations: Parallelism: 1
Completions: 1
Start Time: Mon, 03 Aug 2020 14:21:59 +0800
Pods Statuses: 1 Running / 0 Succeeded / 4 Failed
Pod Template:
Labels: controller-uid=9ac8a40c-1548-4683-bbd6-870a236199bf
job-name=my-job
Containers:
hello:
Image: busybox
Port: <none>
Host Port: <none>
Command:
exit 1
Environment: <none>
Mounts: <none>
Volumes: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 77s job-controller Created pod: my-job-n8qf2
Normal SuccessfulCreate 75s job-controller Created pod: my-job-j484w
Normal SuccessfulCreate 65s job-controller Created pod: my-job-576nv
Normal SuccessfulCreate 45s job-controller Created pod: my-job-xdk29
Normal SuccessfulCreate 5s job-controller Created pod: my-job-ghfcv
1
2
3
4
5
6
7
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-job-576nv 0/1 ContainerCannotRun 0 109s
my-job-ghfcv 0/1 ContainerCannotRun 0 49s
my-job-j484w 0/1 ContainerCannotRun 0 119s
my-job-n8qf2 0/1 ContainerCannotRun 0 2m1s
my-job-xdk29 0/1 ContainerCannotRun 0 89s

由于restartPolicy=Never,可以看到,对应的pod的RESTARTS始终为0,job-controller会不停的创建新的pod。

现在,讲restartPolicy改为OnFailure

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$ kubectl describe job my-job
Name: my-job
Namespace: default
Selector: controller-uid=d404af28-5d83-4943-85cf-301c2910d967
Labels: controller-uid=d404af28-5d83-4943-85cf-301c2910d967
job-name=my-job
Annotations: Parallelism: 1
Completions: 1
Start Time: Mon, 03 Aug 2020 14:28:45 +0800
Pods Statuses: 1 Running / 0 Succeeded / 0 Failed
Pod Template:
Labels: controller-uid=d404af28-5d83-4943-85cf-301c2910d967
job-name=my-job
Containers:
hello:
Image: busybox
Port: <none>
Host Port: <none>
Command:
exit 1
Environment: <none>
Mounts: <none>
Volumes: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 2m50s job-controller Created pod: my-job-2ndzd
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
my-job-2ndzd 0/1 CrashLoopBackOff 3 96s

可以看到,对应的pod在不断的重启

并行作业

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: batch/v1
kind: Job
metadata:
name: my-job
spec:
parallelism: 2
completions: 4
template:
metadata:
labels:
name: my-job
spec:
containers:
- name: my-job
image: busybox
imagePullPolicy: IfNotPresent
command: ["echo", "hello Job"]
restartPolicy: Never
1
2
3
4
5
6
$ kubectl get pods -l name=my-job
NAME READY STATUS RESTARTS AGE
my-job-2x4lc 0/1 Completed 0 10s
my-job-lnhxx 0/1 Completed 0 7s
my-job-md4nr 0/1 Completed 0 10s
my-job-s5znf 0/1 Completed 0 7s
1
2
3
$ kubectl get jobs
NAME COMPLETIONS DURATION AGE
my-job 4/4 5s 16s

可以根据pod的时间看出,my-job-2x4lcmy-job-md4nr是同一时间创建的,而另外两个pod则在其之后3s创建的。

CronJob

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
imagePullPolicy: IfNotPresent
args:
- /bin/sh
- -c
- date; echo Hello from Kubernetes Cluster
restartPolicy: OnFailure
1
2
3
4
5
6
7
8
9
10
11
12
$ kubectl get cronjobs.batch
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
hello */1 * * * * False 0 46s 2m39s
$ kubectl get jobs
NAME COMPLETIONS DURATION AGE
hello-1596438780 1/1 2s 2m38s
hello-1596438840 1/1 1s 98s
hello-1596438900 1/1 2s 38s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-1596438720-2j5t4 0/1 Completed 0 3s
hello-1596438780-lbwnz 0/1 Completed 0 12s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ kubectl describe pod hello-1596438960-4c5ft
Name: hello-1596438960-4c5ft
Namespace: default
Priority: 0
Node: k8s-node4/10.160.18.184
Start Time: Mon, 03 Aug 2020 15:16:03 +0800
Labels: controller-uid=e421bffd-df9f-4342-8c3f-a852076deb6e
job-name=hello-1596438960
Annotations: <none>
Status: Succeeded
IP: 172.1.3.42
IPs:
IP: 172.1.3.42
Controlled By: Job/hello-1596438960
1
2
3
4
5
6
7
8
$ kubectl describe job hello-1596438960
Name: hello-1596438960
Namespace: default
Selector: controller-uid=e421bffd-df9f-4342-8c3f-a852076deb6e
Labels: controller-uid=e421bffd-df9f-4342-8c3f-a852076deb6e
job-name=hello-1596438960
Annotations: <none>
Controlled By: CronJob/hello

分析

从yaml文件中可以看到,jobTemplate的描述同Job,所以,CronJob实际上是一个job的调度器。

CronJob创建了以hello-+随机串的方式,创建了随后的多个Job,再由Job控制Pod运行

而从pod一层一层往上追溯:

  • Pod测controller为Job
  • Job的controller为CronJob

小结

本章节主要了解了一下Job和CronJob。需要理解的是:

  • Job控制pod,且Job仅运行一次
  • CronJob通过定时创建Job来运行