容器安装持续运行的时间可分为两类:服务类容器和工作类容器
服务类容器通常持续提供服务,需要一直运行,比如web server,daemon等。工作类容器则是一次性任务,比如批处理程序,完成后容器就退出。
Kubernetes的Deployment、ReplicaSet和DaemonSet都用于管理服务类容器;对于工作类容器,就可以使用Job
运行一次性任务
先来写一个简单的执行Job一次性任务的文件
[root@node1 ~]# vim cyjjob.yml
apiVersion: batch/v1
kind: Job
metadata:
name: cyjjob
spec:
template:
metadata:
name: cyjjob
spec:
containers:
- name: test
image: busybox
command: ["echo","Hello Cyj"]
restartPolicy: Nerver # 一次性任务只能设置Nerver,服务类容器可以设置为Always
运行一次性任务的Pod
[root@node1 ~]# kubectl apply -f cyjjob.yml
job.batch/cyjjob created
查看创建好的Job,默认运行一个
[root@node1 ~]# kubectl get job
NAME COMPLETIONS DURATION AGE
cyjjob 1/1 20s 49s
查看运行完成的Pod,状态显示为完成
[root@node1 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
cyjjob-lzg7x 0/1 Completed 0 2m44s 10.244.1.5 node2
查看一次性任务是否执行成功
[root@node1 ~]# kubectl logs cyjjob-lzg7x
Hello Cyj
一次性任务的失败
先将刚才的一次性任务的pod删除,然后来模拟一个失败的任务
[root@node1 ~]# kubectl delete -f cyjjob.yml
job.batch "cyjjob" deleted
# 将执行的命令修改为不存在的命令,肯定会执行失败
[root@node1 ~]# vim cyjjob.yml
# 修改以下
command: ["cyj","Hello Cyj"]
运行失败的一次性任务
[root@node1 ~]# kubectl apply -f cyjjob.yml
job.batch/cyjjob created
查看创建的Pod
[root@node1 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
cyjjob-2jsnr 0/1 ContainerCannotRun 0 22s 10.244.2.7 node3
cyjjob-ckmfh 0/1 ContainerCannotRun 0 49s 10.244.2.6 node3
cyjjob-dx6lj 0/1 ContainerCannotRun 0 68s 10.244.2.5 node3
cyjjob-krjkx 0/1 ContainerCreating 0 2s <none> node3
发现不指定应该默认只创建一个,但是一直在创建,大概20s左右会增加一个,这就是运行失败的一个bug
查看运行的job,没有一个运行完成的job
[root@node1 ~]# kubectl get job
NAME COMPLETIONS DURATION AGE
cyjjob 0/1 2m34s 2m34s
这时来查看运行失败的Pod的事件信息
[root@node1 ~]# kubectl describe pod cyjjob-2jsnr
# 随便选择一个运行失败的job,查看底部的events信息
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m44s default-scheduler Successfully assigned default/cyjjob-2jsnr to node3
Normal Pulling 2m43s kubelet, node3 Pulling image "busybox"
Normal Pulled 2m28s kubelet, node3 Successfully pulled image "busybox"
Normal Created 2m28s kubelet, node3 Created container test
Warning Failed 2m28s kubelet, node3 Error: failed to start container "test": Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"cyj\": executable file not found in $PATH": unknown
将job分配到了node3节点
正在下载镜像busybox
成功下载镜像
创建容器test
错误:没有启动test,启动过程中没有找到cyj的可执行程序
这种现象的产生是因为,重启策略被设置了为Never,当他失败后,不会去重启Pod,但是Job对Pod的期望值为1,失败就一直为0,不满足1,所以Job会启动新的Pod,直到有一个Pod完成了Job的期望,对于一次性任务的失败来说,永远不会满足期望值,也只能将创建的Job删除
[root@node1 ~]# kubectl delete -f cyjjob.yml
job.batch "cyjjob" deleted
在一开始就提到一次性任务可以设置为Never,这里因为失败的原因又是因为Never,重启策略还有一个值为OnFailure
,如果失败重启Pod,允许重启5次,还是失败就不再重启,也不再创建Pod
修改重启策略
[root@node1 ~]# vim cyjjob.yml
# 修改以下
restartPolicy: OnFailure
再次运行失败的一次性任务
[root@node1 ~]# kubectl apply -f cyjjob.yml
job.batch/cyjjob created
等待一段时间后,查看运行Pod的重启状态,已经重启了5次,但还是失败,5次之后在查看,已经没有pod了
[root@node1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
cyjjob-24q6h 0/1 CrashLoopBackOff 5 102s
并行执行Job
有时候会希望同时允许多个Job,就像Pod的Replicas一样,可以通过parallelism设置,用来提高Job的执行效率
还是上面用过的文件,继续修改,将执行命令也改回正确的格式
先将上面的运行失败的任务删除
[root@node1 ~]# kubectl delete -f cyjjob.yml
job.batch "cyjjob" deleted
修改文件
[root@node1 ~]# vim cyjjob.yml
apiVersion: batch/v1
kind: Job
metadata:
name: cyjjob
spec:
parallelism: 2 # 添加到此位置实现并行允许2个Job
template:
metadata:
name: cyjjob
spec:
containers:
- name: test
image: busybox
command: ["echo","Hello Cyj"]
restartPolicy: OnFailure
运行job文件
[root@node1 ~]# kubectl apply -f cyjjob.yml
job.batch/cyjjob created
查看运行完成的Job
[root@node1 ~]# kubectl get job
NAME COMPLETIONS DURATION AGE
cyjjob 2/1 of 2 5s 67s
查看创建完成的Pod,看到两个Pod的age值相同,说明是并行运行的Job
[root@node1 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
cyjjob-8fpds 0/1 Completed 0 2m57s 10.244.1.6 node2
cyjjob-gdc25 0/1 Completed 0 2m57s 10.244.2.13 node3
查看任务是否执行成功
[root@node1 ~]# kubectl logs cyjjob-8fpds
Hello Cyj
[root@node1 ~]# kubectl logs cyjjob-gdc25
Hello Cyj
并行执行的Job共同完成多次任务
先将上面执行结束的任务删除
[root@node1 ~]# kubectl delete -f cyjjob.yml
job.batch "cyjjob" deleted
通过completions
可以设置Job完成Pod的总数
[root@node1 ~]# vim cyjjob.yml
apiVersion: batch/v1
kind: Job
metadata:
name: cyjjob
spec:
completions: 6 # 指定一共完成6次Pod
parallelism: 2 # 每运行一次Job,同时并行执行2个,也就是3次就执行完了
template:
metadata:
name: cyjjob
spec:
containers:
- name: test
image: busybox
command: ["echo","Hello Cyj"]
restartPolicy: OnFailure
运行job
[root@node1 ~]# kubectl apply -f cyjjob.yml
job.batch/cyjjob created
查看运行的Job,完成了6个Job
[root@node1 ~]# kubectl get job
NAME COMPLETIONS DURATION AGE
cyjjob 6/6 15s 50s
查看运行的Pod
[root@node1 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
cyjjob-7txmn 0/1 Completed 0 73s 10.244.2.18 node3
cyjjob-cp6zm 0/1 Completed 0 78s 10.244.2.16 node3
cyjjob-lnj2g 0/1 Completed 0 75s 10.244.1.10 node2
cyjjob-q9ssx 0/1 Completed 0 83s 10.244.2.15 node3
cyjjob-rklmk 0/1 Completed 0 78s 10.244.1.9 node2
cyjjob-vxc6r 0/1 Completed 0 83s 10.244.1.8 node2
向例子中的Job并行的实际用途并不大,不过现实中确实存在很多需要并行处理的场景。比如批处理程序,每个副本(Pod)都会从任务池中读取任务并执行,副本越多,执行时间就越短,效率就越高。这种类似的场景都可以用 Job 来实现。
定时Job
Linux中有cron程序定时执行任务,Kubernetes的CronJob提供了类似的功能,可以定时执行Job
例:
[root@node1 ~]# vim cronjob.yml
apiVersion: batch/v2alpha1
kind: CronJob
metadata:
name: cyj
spec:
schedule: "*/1 * * * *" # 执行Job的周期
jobTemplate:
spec:
template:
spec:
containers:
- name: cyj
image: busybox
command: ["echo","hello Chai!~"]
restartPolicy: OnFailure
默认使用CronJob的apiVersion是没有在生产环境中加入的,如果现在直接运行文件会报出以下错误
[root@node1 ~]# kubectl apply -f cronjob.yml
error: unable to recognize "cronjob.yml": no matches for kind "CronJob" in version "batch/v2alpha1"
需要将使用的这个apiVersion加入到生产环境中
[root@node1 ~]# vi /etc/kubernetes/manifests/kube-apiserver.yaml
spec:
containers:
- command:
- kube-apiserver
- --runtime-config=batch/v2alpha1=true # 添加此行
然后重启服务
[root@node1 ~]# systemctl restart kubelet
查看所支持的apiVersion
[root@node1 ~]# kubectl api-versions | grep batch
batch/v1
batch/v1beta1
batch/v2alpha1
重新创建CronJob
[root@node1 ~]# kubectl apply -f cronjob.yml
cronjob.batch/cyj created
查看运行的job,根据时间的推移,每一分钟就会执行一个Job
[root@node1 ~]# kubectl get job
NAME COMPLETIONS DURATION AGE
cyj-1589850300 1/1 8s 2m10s
cyj-1589850360 1/1 4s 70s
cyj-1589850420 1/1 7s 10s
查看运行的cronjob
[root@node1 ~]# kubectl get cronjob
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
cyj */1 * * * * False 0 22s 3m38s