zhangguanzhang's Blog

kubernetes's Job总结和实战以及坑

字数统计: 1.4k阅读时长: 6 min
2018/06/03 Share

Job

有三种主要类型的 Job

Job的Pod运行完可以看到状态为Completed,低版本需要在get pod的时候添加-a或者--show-all才能看到job创建的pod

下面实例先创建一个固定完成数量2,并行数量4的Job

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
[root@k8s-m1 k8s]# cat job.yml 
apiVersion: batch/v1
kind: Job
metadata:
name: test-job
spec:
completions: 2
parallelism: 4
template:
spec:
containers:
- name: test
image: busybox
command: ["sh","-c","echo test && sleep 30"]
restartPolicy: Never
[root@k8s-m1 k8s]# kubectl apply -f job.yml
job.batch "test-job" created
[root@k8s-m1 k8s]# kubectl get pod
NAME READY STATUS RESTARTS AGE
test-job-7p4ds 1/1 Running 0 8s
test-job-crhjw 1/1 Running 0 8s
[root@k8s-m1 k8s]# kubectl get job
NAME DESIRED SUCCESSFUL AGE
test-job 2 0 23s
[root@k8s-m1 k8s]# kubectl get job
NAME DESIRED SUCCESSFUL AGE
test-job 2 2 1m
[root@k8s-m1 k8s]# kubectl get pod
NAME READY STATUS RESTARTS AGE
test-job-7p4ds 0/1 Completed 0 1m
test-job-crhjw 0/1 Completed 0 1m

Job规则和总结

可以通过设置.spec.completions.spec.parallelism的值来组合成三种场景

先说坑后面再说总结

硬性规定:job的重启策略只supported values: “OnFailure”, “Never”

.spec.backoffLimit为在将作业视为失败之前指定重试的次数,默认为6
.spec.activeDeadlineSeconds设置Job的工作时间,优先级高于.spec.backoffLimit

官方说
issue #54870:.spec.template.spec.restartPolicy字段设置为“ OnFailure”时,.spec.backoffLimit可能无效。建议restartPolicy设置为Never

但是Never的话.spec.backoffLimit我设置成次数2测试了下依然无效,见下面

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
[root@k8s-m1 k8s]# cat job.yml 
apiVersion: batch/v1
kind: Job
metadata:
name: test-job
spec:
backoffLimit: 2
template:
spec:
containers:
- name: test
image: busybox
command: ["exit 1"]
restartPolicy: Never
[root@k8s-m1 k8s]# kubectl apply -f job.yml
job.batch "test-job" created
[root@k8s-m1 k8s]# kubectl get pod
NAME READY STATUS RESTARTS AGE
test-job-g4r8w 0/1 ContainerCreating 0 1s
test-job-tqbvl 0/1 ContainerCannotRun 0 3s
[root@k8s-m1 k8s]# kubectl get pod
NAME READY STATUS RESTARTS AGE
test-job-2h5vp 0/1 ContainerCannotRun 0 13s
test-job-2klzs 0/1 ContainerCannotRun 0 15s
test-job-4c2xz 0/1 ContainerCannotRun 0 24s
test-job-6bcqc 0/1 ContainerCannotRun 0 8s
test-job-6r7wq 0/1 ContainerCannotRun 0 11s
test-job-7cz7c 0/1 Terminating 0 8s
test-job-7mkdn 0/1 Terminating 0 16s
test-job-88ws8 0/1 ContainerCannotRun 0 26s
test-job-bqfk4 0/1 ContainerCannotRun 0 22s
test-job-jh7dp 0/1 ContainerCannotRun 0 4s
test-job-k2c4r 0/1 ContainerCannotRun 0 18s
test-job-qfj7m 0/1 ContainerCannotRun 0 6s
test-job-r8794 0/1 ContainerCreating 0 1s
test-job-r9gz6 0/1 Terminating 0 6s
test-job-w4f9r 0/1 Terminating 0 1s
[root@k8s-m1 k8s]# kubectl delete -f job.yml
job.batch "test-job" deleted

Never下pod失败了不重启也就是Job会新建pod,那么此时的失败次数应该是失败的容器个数,但是我上面实践看根本不是这个个数,不知道是啥已经在上面的issue里回复了这个,等待日后的完善吧

  • 非并行 Job
  • 通常只启动一个Pod,除非Pod运行失败了(失败会重启pod,异常退出下,如果配置重启策略为Never的话则会一直创建新的pod直到pod成功退出job才会完成)。

  • Pod一旦成功终止,Job就完成了。

  • 具有固定完成数量的Job:
  • .spec.completions指定一个非零的正整数值,即正常完成的pod数量达到.spec.completions的值时,整个Job就完成

  • 当1到.spec.completions范围内的每个值都有一个成功的pod时,Job就完成了

  • 此时的.spec.parallelism参数是Job的并行执行Pod的数量,即同时启动几个Pod,未设置下默认值为1,为0会被暂停(例如kubectl scale --replicas=0 job/myjob即可暂停myjob)

  • 如果.spec.parallelism并行的值超过.spec.completions规定完成数量,则.spec.parallelism的高出部分不生效,也就是一次并行.spec.parallelism的个数(参照我上面的例子)

  • 尚未实现:每个Pod在 1 到.spec.completions范围内传递一个不同的索引。

  • 具有工作队列的并行Job
  • 不能指定.spec.completions,此时的.spec.parallelism值是队列的worker(pod)数量(此处应该这样理解,但是官方文档不是这样写的,见最后)

  • Pod 必须与自己或外部服务协调,以确定每个Pod上每个应该工作的内容

  • 每个Pod独立地能够确定是否所有的同伴都已完成工作,从而完成整个工作。

  • 当任一Pod成功退出时,不会再创建新的Pod

  • 一旦至少一个 Pod 已经成功终止,所有 Pod 都会被终止,那么Job就成功完成(队列是一个单向的消费者概念,为空就表明完成job)。

  • 一旦任何 Pod 成功退出,其他 Pod 就不应该继续做任何工作或写任何输出。 他们都应该处于退出的过程。

官方文档有误导?

链接https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
先说下面的

1
Parallel Jobs with a work queue:  - do not specify .spec.completions, default to .spec.parallelism.

此处意思有误导人的嫌疑,我刚开始看到这卡住了,然后才看到下面的

1
For a Work Queue Job, you must leave .spec.completions unset, and set .spec.parallelism to a non-negative integer

官方第一处说的保持默认值是错误说法,应该是用户自行设置,也就是队列的workers数量

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
[root@k8s-m1 k8s]# cat job.yml 
apiVersion: batch/v1
kind: Job
metadata:
name: test-job
spec:
# completions: 2
parallelism: 4
template:
spec:
containers:
- name: pi
image: busybox
command: ["sh","-c","echo test && sleep 30"]
restartPolicy: OnFailure
[root@k8s-m1 k8s]# kubectl apply -f job.yml
[root@k8s-m1 k8s]# kubectl get pod
NAME READY STATUS RESTARTS AGE
test-job-5f8dh 1/1 Running 0 9s
test-job-ddkmt 1/1 Running 0 9s
test-job-hxkjb 1/1 Running 0 9s
test-job-ttrmv 1/1 Running 0 9s
[root@k8s-m1 k8s]# kubectl get pod
NAME READY STATUS RESTARTS AGE
test-job-5f8dh 0/1 Completed 0 1m
test-job-ddkmt 0/1 Completed 0 1m
test-job-hxkjb 0/1 Completed 0 1m
test-job-ttrmv 0/1 Completed 0 1m
[root@k8s-m1 k8s]# kubectl get job
NAME DESIRED SUCCESSFUL AGE
test-job <none> 4 4m

CATALOG
  1. 1. Job
  2. 2. Job规则和总结
    1. 2.1. 先说坑后面再说总结
  3. 3. 官方文档有误导?