**服务类的Pod容器:**RC、RS、DS、Deployment
**工作类的Pod容器:**Job—>执行一次,或者批量执行处理程序,完成之后退出容器。
注意: 如果容器内执行任务有误,会根据容器的重启策略操作容器,不过这里
的容器重启策略只能是: Never和 OnFailure。
在有些场景下,是想要运行一些容器执行某种特定的任务,任务一旦执行完成,容器也就没有存在的必要了。在这种场景下,创建pod就显得不那么合适。于是就是了Job,Job指的就是那些一次性任务。通过Job运行一个容器,当其任务执行完以后,就自动退出,集群也不再重新将其唤醒。
从程序的运行形态上来区分,可以将Pod分为两类:长时运行服务(jboss、mysql等)和一次性任务(数据计算、测试)。RC创建的Pod都是长时运行的服务,Job多用于执行一次性任务、批处理工作等,执行完成后便会停止(status.phase变为Succeeded)。
主机 | IP地址 | 服务 |
---|---|---|
master | 192.168.1.21 | k8s |
node01 | 192.168.1.22 | k8s |
node02 | 192.168.1.23 | k8s |
基于 https://blog.51cto.com/14320361/2464655 的实验继续进行
- 非并行job:通常创建一个pod直至其成功结束。
- 固定结束次数的job:设置spec.completions,创建多个pod,直到.spec.completions个pod成功结束。
- 带有工作队列的并行job:设置.spec.Parallelism但不设置.spec.completions,当所有pod结束并且至少一个成功时,job就认为是成功。
Job Controller负责根据Job Spec创建pod,并持续监控pod的状态,直至其成功结束,如果失败,则根据restartPolicy(只支持OnFailure和Never,不支持Always)决定是否创建新的pod再次重试任务。
[root@master yaml]# vim jop.yaml
kind: Job
apiVersion: batch/v1
metadata:
name: test-job
spec:
template:
metadata:
name: test-job
spec:
containers:
- name: hello
image: busybox
command: ["echo","hello k8s job!"]
restartPolicy: Never
[root@master yaml]# kubectl apply -f jop.yaml
[root@master yaml]# kubectl get pod
[root@master yaml]# kubectl logs test-job-gs45w
我们可以看到job与其他资源对象不同,仅执行一次性任务,默认pod借宿运行后job即结束,状态为Completed。
[root@master yaml]# vim jop.yaml
kind: Job
apiVersion: batch/v1
metadata:
name: test-job
spec:
template:
metadata:
name: test-job
spec:
containers:
- name: hello
image: busybox
command: ["asdasxsddwefew","hello k8s job!"] #修改
restartPolicy: Never
[root@master yaml]# kubectl delete jobs.batch test-job
[root@master yaml]# kubectl apply -f jop.yaml
[root@master yaml]# kubectl get pod -w
它会一直创建pod直到完成命令。
[root@master yaml]# vim jop.yaml
kind: Job
apiVersion: batch/v1
metadata:
name: test-job
spec:
template:
metadata:
name: test-job
spec:
containers:
- name: hello
image: busybox
command: ["asdasxsddwefew","hello k8s job!"]
restartPolicy: OnFailure
[root@master yaml]# kubectl delete jobs.batch test-job
[root@master yaml]# kubectl apply -f jop.yaml
[root@master yaml]# kubectl get pod -w
它会一直重启pod完成命令,直到重启到一定次数就会删除job。
[root@master yaml]# vim jop.yaml
kind: Job
apiVersion: batch/v1
metadata:
name: test-job
spec:
parallelism: 2 #同时启用几个pod
template:
metadata:
name: test-job
spec:
containers:
- name: hello
image: busybox
command: ["echo","hello k8s job!"]
restartPolicy: OnFailure
[root@master yaml]# kubectl apply -f jop.yaml
[root@master yaml]# kubectl get pod
[root@master yaml]# vim jop.yaml
kind: Job
apiVersion: batch/v1
metadata:
name: test-job
spec:
complations: 8 #运行pod的总数量8个
parallelism: 2 #同时运行2个pod
template:
metadata:
name: test-job
spec:
containers:
- name: hello
image: busybox
command: ["echo","hello k8s job!"]
restartPolicy: OnFailure
job 字段解释:
标志Job结束需要成功运行的Pod个数,默认为1
parallelism:标志并行运行的Pod的个数,默认为1
activeDeadlineSeconds:标志失败Pod的重试最大时间,超过这个时间不会继续重试.
[root@master yaml]# kubectl delete jobs.batch test-job
[root@master yaml]# kubectl apply -f jop.yaml
[root@master yaml]# kubectl get pod
可以看到pod是两个两个的启动的。
[root@master yaml]# vim cronjop.yaml
kind: CronJob
apiVersion: batch/v1beta1
metadata:
name: hello
spec:
schedule: "*/1 * * * *" #限定时间
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
command: ["echo","hello","cronjob"]
restartPolicy: OnFailure
[root@master yaml]# kubectl delete jobs.batch test-job
[root@master yaml]# kubectl apply -f jop.yaml
[root@master yaml]# kubectl get pod
[root@master yaml]# kubectl get cronjobs.batch
此时查看Pod的状态,会发现,每分钟都会运行一个新的Pod来执行命令规定的任
务。
[root@master yaml]# vim cronjop.yaml
kind: CronJob
apiVersion: batch/v1beta1
metadata:
name: hello
spec:
schedule: "5 10 15 1 *" #限定时间
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
command: ["echo","hello","cronjob"]
restartPolicy: OnFailure
[root@master yaml]# kubectl delete cronjobs.batch hello
[root@master yaml]# kubectl apply -f jop.yaml
[root@master yaml]# kubectl get pod
这时会发现,如果规定具体时间,可能并不会执行任务。
[root@master yaml]# vim /etc/kubernetes/manifests/kube-apiserver.yaml
spec:
containers:
- command:
- kube-apiserver
- --runtime-config=batch/v2alpha1=true #添加
[root@master yaml]# systemctl restart kubelet.service
[root@master yaml]# kubectl api-versions
[root@master yaml]# vim cronjop.yaml
kind: CronJob
apiVersion: batch/v1beta1
metadata:
name: hello
spec:
schedule: "47 10 15 1 *" #限定时间
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
command: ["echo","hello","cronjob"]
restartPolicy: OnFailure
[root@master yaml]# kubectl apply -f jop.yaml
[root@master yaml]# kubectl get pod -w
注意:此时仍然不能正常运行指定时间的Job,这是因为K8s官方在cronjob这个资源对象的支持中还没有完善此功能,还待开发。
跟Job资源一样在cronjob.spec.jobTemplate.spec 下同样支持并发Job参数:
parallelism,也支持完成Pod的总数参数: completionsr
Job 作为 Kubernetes 中用于处理任务的资源,与其他的资源没有太多的区别,它也使用 Kubernetes 中常见的控制器模式,监听 Informer 中的事件并运行 syncHandler
同步任务
而 CronJob 由于其功能的特殊性,每隔 10s 会从 apiserver 中取出资源并进行检查是否应该触发调度创建新的资源,需要注意的是 CronJob 并不能保证在准确的目标时间执行,执行会有一定程度的滞后。
两个控制器的实现都比较清晰,只是边界条件比较多,分析其实现原理时一定要多注意。