学习本节内容之前,希望你已经对Pod和ReplicaSet有了基本的了解。具体请参考这两篇文章:
- Kubernetes对象之Pod
- Kubernetes对象之ReplicaSet
Job对象通常用于运行那些仅需要执行一次的任务(例如数据库迁移,批处理脚本等等)。通过Job对象创建运行的Pod具有高可靠性,因为Job Controller会自动重启运行失败的Pod(例如Pod所在Node重启或宕机)。
Job的本质是确保一个或多个Pod健康地运行直至运行完毕。
1. 创建一个Job对象
下面是创建一个Job对象的例子,这个Job对象会启动一个Pod,用于计算π到小数点后2000位:
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
$ kubectl create -f ./job.yaml
job "pi" created
运行describe命令,查看此Job的详情:
[node1 ~]$ kubectl describe jobs/pi
Name: pi
Namespace: default
Selector: controller-uid=b207edb4-5a54-11e8-8da4-0242788d5821
Labels: controller-uid=b207edb4-5a54-11e8-8da4-0242788d5821
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":{"spec":{"con...
Parallelism: 1
Completions: 1
Start Time: Fri, 18 May 2018 04:34:04 +0000
Pods Statuses: 0 Running / 1 Succeeded / 0 Failed
Pod Template:
Labels: controller-uid=b207edb4-5a54-11e8-8da4-0242788d5821
job-name=pi
Containers:
pi:
Image: perl
Port:
Command:
perl
-Mbignum=bpi
-wle
print bpi(2)
Environment:
Mounts:
Volumes:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 6s job-controller Created pod: pi-57qpr
查看当前正在运行的Pod:
[node1 ~]$ kubectl get pods
NAME READY STATUS RESTARTS AGE
pi-sgklk 1/1 Running 0 6s
如果返回No resources found,则表明这个计算π的Pod已经运行结束了,
get pods
命令只能返回当前正在运行的Pod,加上-a
参数能够返回所有Pod以及对应的status。
2. Job对象参数详解
2.1 .spec.completions和.spec.parallelism
如果指定了.spec.parallelism参数,那么表示此Job可以同时运行指定.spec.parallelism数量的Pod。通常用于从消息队列中读取数据的worker程序,指定了.spec.parallelism后,那么就会同时有多个worker从消息队列中读取数据。
具体的例子请参考:https://kubernetes.io/docs/tasks/job/fine-parallel-processing-work-queue/
如果指定了.spec.completions参数,那么意味着这个Job需要成功.spec.completions个Pod才会结束。因此,Job Controller会依次创建出.spec.completions数量的Pod,直到这些Pod都运行成功为止。
下面是一些具体的例子:
- 上面的pi Job未设置.spec.parallelism和.spec.completions,通过
describe
命令我们发现默认值为:parallelism=1,completions=1。 - 如果只设置pi Job
.spec.completions = 3
,那么此时.spec.parallelism参数采用默认值1,因此Job Controller会首先创建第一个Pod,运行成功后,创建第二个Pod,第二个Pod运行成功后,创建第三个Pod。 - 如果只设置pi Job
.spec.parallelism = 3
,那么意味着此Job能够同时运行3个Pod。因此Job Controller会同时创建三个Pod,当三个Pod运行结束后,Job也设置为结束状态。 - 如果同时设置
.spec.parallelism=3
,.spec.completions = 9
,那么Job Controller会每次创建3个Pod,循环3此后,当存在9个成功运行结束的Pod后,Job成功运行结束。
如果.spec.parallelism的值大于.spec.completions,此时不会同时创建.spec.parallelism个Pod,而是创建出.spec.completions个Pod。
2.2 .spec.template.spec.restartPolicy
.spec.template.spec.restartPolicy
属性拥有三个候选值:OnFailure,Never和Always。默认值为Always。它主要用于描述Pod内容器的重启策略。在Job中只能将此属性设置为OnFailure或Never。
如果.spec.template.spec.restartPolicy = OnFailure
,如果Pod内某个容器的exit code不为0,那么Pod就会在其内部重启这个容器。而如果.spec.template.spec.restartPolicy = Never
,那么Pod内某个容器exit code不为0时,就不会触发容器的重启。
除了针对Pod内容器的.spec.template.spec.restartPolicy
(此属性属于Pod的属性,本质上与Job Controller无关),Job Controller会确保Pod运行成功.spec.completions
次。当一个Pod运行失败时(Pod所在及其宕机,Pod内某个容器运行失败那么Pod运行结束时的状态就也是失败),Job Controller会创建一个新的Pod来运行,直到运行成功的Pod个数等于.spec.completions
。
因此,我们将
.spec.template.spec.restartPolicy
设置为Never,当容器exit code不为0时,Job Controller会创建一个新的Pod来继续运行,这就像ReplicaSet一样提供了Pod的高可用性。
2.3 .spec.backoffLimit
.spec.backoffLimit
用于设置Job的容错次数,默认值为6。当Job运行的Pod失败次数到达.spec.backoffLimit
次时,Job Controller不再新建Pod,直接停止运行这个Job,将其运行结果标记为Failure。另外,Pod运行失败后再次运行的时间间隔呈递增状态,例如10s,20s,40s。。。
2.4 .spec.activeDeadlineSeconds
.spec.activeDeadlineSeconds
属性用于设置Job运行的超时时间。如果Job运行的时间超过了设定的秒数,那么此Job就自动停止运行所有的Pod,并将Job退出状态标记为reason: DeadlineExceeded
。
总结
- 以Bare Pod(通过描述文件直接定义运行的Pod)没有自愈性,如果机器宕机或重启了,那么运行在其上的Pod都不会重启。因此如果要单独运行一个Pod,我们推荐使用Job运行,而不是运行Bare Pod。
- Job的高可用性与Replication Controller有些相似。但是,Replication Controller通常用于管理一些始终处于运行状态的Pod(例如web服务器);而Job则用于管理那些一定会运行结束的Pod。
参考文章
- https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/