0%

控制器-Job

控制器-Job: 只要完成就立即退出,不需要重启或重建。

控制器 - Job

Kubernetes中的 Job 对象将创建一个或多个 Pod,并确保指定数量的 Pod 可以成功执行到进程正常结束:

  • 当 Job 创建的 Pod 执行成功并正常结束时,Job 将记录成功结束的 Pod 数量
  • 当成功结束的 Pod 达到指定的数量时,Job 将完成执行
  • 删除 Job 对象时,将清理掉由 Job 创建的 Pod

一个简单的例子是:创建一个 Job 对象用来确保一个 Pod 的成功执行并结束。在第一个 Pod 执行失败或者被删除(例如,节点硬件故障或机器重启)的情况下,该 Job 对象将创建一个新的 Pod 以重新执行。

当然,也可以使用 Job 对象并行执行多个 Pod。

运行一个Job的例子

在下面这个 Job 的例子中,Pod 执行了一个跟 π 相关的计算,并打印出最终结果,该计算大约需要 10 秒钟执行结束。

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4

创建Job

1
2
[root@k8s-master 0407]# kubectl apply -f  job1.yaml 
job.batch/pi created

查看已创建的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
32
33
34
35
36
37
38
39
40
41
42
[root@k8s-master 0407]# kubectl get job
NAME COMPLETIONS DURATION AGE
pi 0/1 38s 38s

[root@k8s-master 0407]# kubectl describe job
Name: pi
Namespace: default
Selector: controller-uid=e1b373ab-1c02-4d49-b386-ead11d012a60
Labels: controller-uid=e1b373ab-1c02-4d49-b386-ead11d012a60
job-name=pi
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"batch/v1","kind":"Job","metadata":{"annotations":{},"name":"pi","namespace":"default"},"spec":{"backoffLimit":4,"template":...
Parallelism: 1
Completions: 1
Start Time: Tue, 07 Apr 2020 16:57:38 +0800
Pods Statuses: 1 Running / 0 Succeeded / 0 Failed
Pod Template:
Labels: controller-uid=e1b373ab-1c02-4d49-b386-ead11d012a60
job-name=pi
Containers:
pi:
Image: perl
Port: <none>
Host Port: <none>
Command:
perl
-Mbignum=bpi
-wle
print bpi(2000)
Environment: <none>
Mounts: <none>
Volumes: <none>
Events:
Type Reason Age From Message

---- ------ ---- ---- -------

Normal SuccessfulCreate 48s job-controller Created pod: pi-nn8pf

[root@k8s-master 0407]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pi-nn8pf 0/1 Completed 0 79s

执行以下命令可获得该 Job 所有 Pod 的名字:

1
2
3
4
5
6
7
[root@k8s-master 0407]# pods=$(kubectl get pods --selector=job-name=pi --output=jsonpath='{.items[*].metadata.name}')
[root@k8s-master 0407]# echo $pods
pi-nn8pf

在这个命令中:
selector 与 Job 定义中的 selector 相同
--output=jsonpath 选项指定了一个表达式,该表达式从返回结果列表中的每一个 Pod 的信息中定位出 name 字段的取值

执行以下命令可查看 Pod 的日志:

1
2
[root@k8s-master 0407]# kubectl logs $pods
3.14159265358979............................4780275901

编写Job的定义

与所有的 Kubernetes 对象一样,Job 对象的 YAML 文件中,都需要包括如下三个字段:

  • .apiVersion
  • .kind
  • .metadata

Job 对象的 YAML 文件,还需要一个 .spec 字段。

Pod Template

除了 Pod 所需的必填字段之外,Job 中的 pod template 必须指定

  • 合适的标签 .spec.template.spec.labels
  • 指定合适的[重启策略 restartPolicy .spec.template.spec.restartPolicy,此处只允许使用 NeverOnFailure 两个取值

处理Pod和容器的失败

Pod 中的容器可能会因为多种原因执行失败,例如:

  • 容器中的进程退出了,且退出码(exit code)不为 0
  • 容器因为超出内存限制而被 Kill
  • 其他原因

如果 Pod 中的容器执行失败,且 .spec.template.spec.restartPolicy = "OnFailure",则 Pod 将停留在该节点上,但是容器将被重新执行。此时,应用程序需要处理在原节点(失败之前的节点)上重启的情况。或者,设置为 .spec.template.spec.restartPolicy = "Never"

整个 Pod 也可能因为多种原因执行失败,例如:

  • Pod 从节点上被驱逐(节点升级、重启、被删除等)
  • Pod 的容器执行失败,且 .spec.template.spec.restartPolicy = "Never"

当 Pod 执行失败时,Job 控制器将创建一个新的 Pod

Pod失败重试

Pod backoff failure policy

某些情况下(例如,配置错误),可以在 Job 多次重试仍然失败的情况下停止该 Job。此时,可通过 .spec.backoffLimit 来设定 Job 最大的重试次数。该字段的默认值为 6.

Job 中的 Pod 执行失败之后,Job 控制器将按照一个指数增大的时间延迟(10s,20s,40s … 最大为 6 分钟)来多次重新创建 Pod。如果没有新的 Pod 执行失败,则重试次数的计数将被重置。

Job的终止和清理

当 Job 完成后:

  • 将不会创建新的 Pod
  • 已经创建的 Pod 也不会被清理掉。此时,您仍然可以继续查看已结束 Pod 的日志,以检查 errors/warnings 或者其他诊断用的日志输出
  • Job 对象也仍然保留着,以便您可以查看该 Job 的状态
  • 由用户决定是否删除已完成的 Job 及其 Pod
    • 可通过 kubectl 命令删除 Job,例如: kubectl delete jobs/pi 或者 kubectl delete -f job.yaml
    • 删除 Job 对象时,由该 Job 创建的 Pod 也将一并被删除

Job 通常会顺利的执行下去,但是在如下情况可能会非正常终止:

  • 某一个 Pod 执行失败(且 restartPolicy=Never
  • 或者某个容器执行出错(且 restartPolicy=OnFailure
    • 此时,Job 按照处理Pod和容器的失败中 .spec.bakcoffLimit 描述的方式进行处理
    • 一旦重试次数达到了 .spec.backoffLimit 中的值,Job 将被标记为失败,且尤其创建的所有 Pod 将被终止
  • Job 中设置了 .spec.activeDeadlineSeconds。该字段限定了 Job 对象在集群中的存活时长,一旦达到 .spec.activeDeadlineSeconds 指定的时长,该 Job 创建的所有的 Pod 都将被终止,Job 的 Status 将变为 type:Failedreason: DeadlineExceeded

Job的自动清理

系统中已经完成的 Job 通常是不在需要里的,长期在系统中保留这些对象,将给 apiserver 带来很大的压力。如果通过更高级别的控制器(例如 CronJobs)来管理 Job,则 CronJob 可以根据其中定义的基于容量的清理策略自动清理Job。

TTL 机制

除了 CronJob 之外,TTL 机制是另外一种自动清理已结束Job(CompletedFinished)的方式:

  • TTL 机制由 TTL 控制器 提供
  • 在 Job 对象中指定 .spec.ttlSecondsAfterFinished 字段可激活该特性

当 TTL 控制器清理 Job 时,TTL 控制器将删除 Job 对象,以及由该 Job 创建的所有 Pod 对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: batch/v1
kind: Job
metadata:
name: pi-with-ttl
spec:
ttlSecondsAfterFinished: 100 ####
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never

字段解释 ttlSecondsAfterFinished

  • Job pi-with-ttlttlSecondsAfterFinished 值为 100,则,在其结束 100 秒之后,将可以被自动删除
  • 如果 ttlSecondsAfterFinished 被设置为 0,则 TTL 控制器在 Job 执行结束后,立刻就可以清理该 Job 及其 Pod
  • 如果 ttlSecondsAfterFinished 值未设置,则 TTL 控制器不会清理该 Job