一、Job概念定义与功能
Job是用来执行一次性任务的一类资源,可以使用yaml文件来定义,类似于deployment的机制,定义好的Job会根据yaml文件生成对应数量的pod,在运行完成任务后退出,但不会被删除,可以通过查看pod日志了解任务的完成情况。
Job的特性
- job中可以运行多个pod(任务执行多次),且可以并行运行缩短任务完成的时间
- 限制job中的pod的完成时间,即设置超时时间,超时未完成则标记失败
Job控制器的spec字段可嵌套使用以下字段:
必选字段
- template 为pod对象自动添加job控制器
可选字段
Job由以下几个参数配合用于指定完成次数,并发运行,错误重试等操作:
pod数量
- .spec.completions: number
指定job需要成功运行Pods的次数。默认值: 1
- .spec.parallelism: number
指定job在任一时刻应该并发运行Pods的数量。默认值: 1
超时策略
- .spec.activeDeadlineSeconds:number
指定job可运行的时间期限,超过时间还未结束,系统将会尝试进行终止。
pod失败策略
- .spec.backoffLimit:number
指定job失败后进行重试的次数。默认是6次,每次失败后重试会有延迟时间,该时间是指数级增长,最长时间是6min。
- * spec.restartPolicy:
Always——对job控制器不适用,因此需要设定为Never或OnFailure
Never——pod失败后,重新创建pod
OnFailure——pod失败后,重启pod
注意点
- .spec.template.spec.restartPolicy设置为”Onfailure”时,会与.spec.backoffLimit冲突,可以暂时将restartPolicy设置为”Never”进行规避。
- .spec.activeDeadlineSeconds要比.spec.backoffLimit优先级高,如果时间到了,但是backoffLimit还未到,该Job也会被强制停止。
job的yaml文件示例
apiVersion: batch/v1
kind: Job
metadata:
name: job-demo
spec:
# completions: 5 #需要运行的pod数量,不指定则默认一个
# parallelism: 2 #允许并发运行的pod数量
# activeDeadlineSeconds: 360s #pod运行的超时时间
template:
metadata:
name: job-demo
spec:
restartPolicy: Never
containers:
- name: counter
image: busybox
command:
- "bin/sh"
- "-c"
- "for i in 9 8 7 6 5 4 3 2 1; do echo $i; done"
执行结果如下:
[root@k8s-cp ~]# kubectl create -f job.yaml
[root@k8s-cp ~]# kubectl get job
NAME COMPLETIONS DURATION AGE
job-demo 1/1 26s 17h
[root@k8s-cp ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
job-demo-zrpsc 0/1 Completed 0 17h
[root@k8s-cp ~]# kubectl logs job-demo-zrpsc
9
8
7
6
5
4
3
2
1
二、CronJob概念定义与功能
CronJob就是在Job上加上了时间调度功能,通过在定义job的yaml文件中添加对应字段来实现,在job的基础上加上crontab的功能,在指定的时间点运行job任务。
cronjob控制器的spec字段可嵌套使用以下字段:
必选字段
- jobTemplate:job控制器模板,用于为cronjob控制器生成job对象;必选字段
- schedule:cron格式的作业调度运行时间点;必选字段
可选字段
并发策略
- .spec.concurrencyPolicy:并发执行策略,可用值有Allow、Forbid和Replace,用于定义前一次作业运行尚未完成时是否以及如何运行后一次的作业
Allow(默认):允许并发运行 Job
Forbid:禁止并发运行,如果前一个还没有完成,则直接跳过下一个
Replace:取消当前正在运行的 Job,用一个新的来替换
注意,当前策略只能应用于同一个 Cron Job 创建的 Job。如果存在多个 Cron Job,它们创建的 Job 之间总是允许并发运行。
Job历史记录
- .spec.failedJobHistoryLimit:number 为失败的任务执行保留的历史记录数,默认为1
- .spec.successfulJobHistoryLimit:number 为成功的任务执行保留的历史记录数,默认为3
启动策略
- .spec.startingDeadlineSeconds:600 启动 Job 的期限(秒级别),如果因为任何原因而错过了被调度的时间,那么错过执行时间的 Job 将被认为是失败的。如果没有指定,则没有期限。
挂起策略
- .spec.suspend:true/flase 是否挂起后续的任务执行,默认为false,对运行中的作业不会产生影响
CronJob的yaml文件示例
apiVersion: batch/v2alpha1
kind: CronJob
metadata:
name: cronjob-demo
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: hello
image: busybox
args:
- "bin/sh"
- "-c"
- "for i in 9 8 7 6 5 4 3 2 1; do echo $i; done"
执行结果如下:
[root@k8s-cp ~]# kubectl create -f cronjob.yaml
cronjob.batch/cronjob-demo created
[root@k8s-cp ~]# kubectl get cronjob
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
cronjob-demo */1 * * * * False 0 <none> 22s
[root@k8s-cp ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
cronjob-demo-1587436620-7pn2g 0/1 Completed 0 33s
job-demo-zrpsc 0/1 Completed 0 17h
[root@k8s-cp ~]# kubectl logs cronjob-demo-1587436620-7pn2g
9
8
7
6
5
4
3
2
1
注意点:
以schedule: */1 * * * *,17:00开始执行为例
- 一定要设置spec.startingDeadlineSeconds时间,这个参数指容器没有按时启动时,超过该时间就判断改job运行为失败,并且代表改job已经运行,时间设定应该大于cron表达式执行时间,只有设置了这个超时参数,旧的job才永远不会超过100个,不会影响停止应用的操作。
- 如果并发策略使用的是 JobForbid,那么会先运行旧的job,新的job将不会执行 及先执行 17:05-18:00错过的任务
- 如果并发策略使用 Replace,那么旧的job将不会运行,直接运行新的job 及不执行17:05-18:00错过的任务 直接执行18:01的任务
- 设置.spec.successfulJobsHistoryLimit 和 .spec.failedJobsHistoryLimit限制后,该job会保存 但是因为一个job对应一个容器组,所以会有多个容器组存在,会浪费计算资源
补充:
1.13.3版本定义job与cronjob的yaml文件中,apiVersion需要修改为batch/v1beta1
使用v2接口(1.4、1.5及以上默认v2)需要修改配置文件,方法如下:
在/etc/kubernetes/manifests/kube-apiserver.yaml中添加--runtime-config=batch/v2alpha1=true到如下字段
apiVersion: v1
kind: Pod
metadata:
annotations:
scheduler.alpha.kubernetes.io/critical-pod: ""
creationTimestamp: null
labels:
component: kube-apiserver
tier: control-plane
name: kube-apiserver
namespace: kube-system
spec:
containers:
- command:
- kube-apiserver
- --runtime-config=batch/v2alpha1=true
- --authorization-mode=Node,RBAC
修改文件后需要重启kubelet
systemctl restart kubelet