Wonderingkaho's Blog.

Concept of kubernetes Job

字数统计: 1.4k阅读时长: 6 min
2019/04/28 Share

学习本节内容之前,希望你已经对Pod和ReplicaSet有了基本的了解。具体请参考这两篇文章:

  • Concept of Kubernetes Pod
  • Concept of Kubernetes ReplicaSet

Job对象通常用于运行那些仅需要执行一次的任务(例如数据库迁移,批处理脚本等等)。通过Job对象创建运行的Pod具有高可靠性,因为Job Controller会自动重启运行失败的Pod(例如Pod所在Node重启或宕机)。

Job的本质是确保一个或多个Pod健康地运行直至运行完毕。

创建一个Job对象

下面是创建一个Job对象的例子,这个Job对象会启动一个Pod,用于计算π到小数点后2000位:

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
1
2
$ kubectl create -f ./job.yaml
job "pi" created

运行describe命令,查看此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
[node1 ~]$ kubectl describe jobs/pi
Name: pi
Namespace: default
Selector: controller-uid=c506edb4-68a4-17e8-8da4-02427d875821
Labels: controller-uid=c506edb4-68a4-17e8-8da4-02427d875821
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=c506edb4-68a4-17e8-8da4-02427d875821
job-name=pi
Containers:
pi:
Image: perl
Port: <none>
Command:
perl
-Mbignum=bpi
-wle
print bpi(2)
Environment: <none>
Mounts: <none>
Volumes: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 30s job-controller Created pod: li-89hpr

查看当前正在运行的Pod:

1
2
3
[node1 ~]$ kubectl get pods
NAME READY STATUS RESTARTS AGE
li-89hpr 1/1 Running 0 35s

如果返回No resources found,则表明这个计算π的Pod已经运行结束了,get pods命令只能返回当前正在运行的Pod,加上-a参数能够返回所有Pod以及对应的status。

Job对象参数详解

.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都运行成功为止。

下面是一些具体的例子:

  • 上面的li Job未设置.spec.parallelism和.spec.completions,通过describe命令我们发现默认值为:parallelism=1,completions=1。

  • 如果只设置li Job .spec.completions = 3,那么此时.spec.parallelism参数采用默认值1,因此Job Controller会首先创建第一个Pod,运行成功后,创建第二个Pod,第二个Pod运行成功后,创建第三个Pod。

  • 如果只设置li 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。

.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的高可用性。

.spec.backoffLimit

.spec.backoffLimit用于设置Job的容错次数,默认值为6。当Job运行的Pod失败次数到达.spec.backoffLimit次时,Job Controller不再新建Pod,直接停止运行这个Job,将其运行结果标记为Failure。另外,Pod运行失败后再次运行的时间间隔呈递增状态,例如10s,20s,40s。。。

.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

参考

CATALOG
  1. 1. 创建一个Job对象
  2. 2. Job对象参数详解
    1. 2.1. .spec.completions和.spec.parallelism
    2. 2.2. .spec.template.spec.restartPolicy
    3. 2.3. .spec.backoffLimit
    4. 2.4. .spec.activeDeadlineSeconds
  3. 3. 总结
  4. 4. 参考