k8s 关于Job与Cronjob - 知乎 k8s 关于Job与Cronjob
容器按照持续运行的时间分为两类:
-
服务类容器:提供持续服务,如http server、daemon、kubernetes的Deployment、ReplicaSet等;
-
工 作类容器:一次性任务,比如批处理程序,完成后容器退出。
一、Job要点
1.1、Job重启与失败认定
重启策略(restartPolicy):
-
Never:pod启动失败时不会重启,而是通过job-controller重新创建pod供节点调度。
-
OnFailure:pod将会在节点重启执行任务。
失败回退策略(backoffLimit):
当Job pod 经过多次重启无果,显然我们应该认定这个Job是一个失败任务,默认失败认定重启次数为6,我们可以通过在spec中添加backoffLimit来改变这一认定。
1.2、Job期限与清理
除了Job执行结束与重启失败认定的Job 终止外还可以通过配置活跃期限(activeDeadlineSeconds)来自动停止Job任务。
spec.activeDeadlineSeconds 设置一个秒数值。 该值适用于 Job 的整个生命期,无论 Job 创建了多少个 Pod。
一旦 Job 运行时间达到 activeDeadlineSeconds 秒,其所有运行中的 Pod 都会被终止,并且 Job 的状态更新为 type: Failed 及 reason: DeadlineExceeded。
添加spec.ttlSecondsAfterFinished使Job在任务完成后一段时间内被清理。
二、一个简单的Job配置文件 myjob.yaml
apiVersion: batch/v1 # 当前Job的apiVersion, 根据kubectl api-resources查到kind: Jobmetadata:name: myjobspec:template:metadata:name: myjobspec:containers:- name: helloimage: busyboxcommand: ["echo", "hell k8s"]restartPolicy: Never # 指定什么情况下需要重启容器;对于Job只能设置为Never或者OnFailure,Job就相当于来执行一个批处理任务,执行完就结束了,如果支持Always的话会陷入了死循环了。对于其他Controller可设为Always
执行
kubectl apply -f myjob.yaml
kubectl get job查看Job的状态、
kubectl get pod查看你Pod的状态:
COMPLETIONS为1/1,表示按照预期启动了一个Pod,并且已经成功执行。
STATUS为Completed,表示任务已经完成。
三、Job运行失败会怎样?
apiVersion: batch/v1 # 当前Job的apiVersionkind: Jobmetadata:name: myjobspec:template:metadata:name: myjobspec:containers:- name: helloimage: busyboxcommand: ["invalid-command", "hello k8s job!"]restartPolicy: Never # 指定什么情况下需要重启容器;对于Job只能设置为Never或者OnFailure。对于其他Controller可设为Always
kubectl apply -f myjob.yaml
创建Job
kubectl get job查看Job的状态:
-
若restartPolicy取值 Never,Job失败,SUCCESSFUL的Pod个数为0。 kubectl get pods查看Pod的状态,看到有多个Pod( 默认 6个),状态均不正常。
Never
下存在多个失败的Pod的原因:当第一个Pod启动时,容器失败退出,根据 restartPolicy:Never,此容器失败后不会被重启,但Job DESIRED的Pod是1,目前SUCCESSFUL为0,不满足,故
J
ob Controller会启动新的Pod,直至SUCCESSFUL为1(
k8s为Job提供spec.bakcofflimits来限制重试次数,默认值为6)。
kubectl edit job myjob:
-
若restartPolicy取值 OnFailure,Job失败,SUCCESSFUL的Pod个数为0, kubectl get job --show-all查看Pod只有1个,RESTARTS为4,而且不断增加,说明OnFailure生效,容器失败后会自动重启。
kubectl describe pod
myjob--1-gxbhb 查看错误原因:
四、并行执行Job
有时希望同时运行多个Pod,提高Job的执行效率。可以通过
parallelism设置。
apiVersion: batch/v1 # 当前Job的apiVersionkind: Jobmetadata:name: myjobspec:parallelism: 2 # 将并行的pod数量设为2template:metadata:name: myjobspec:containers:- name: helloimage: busyboxcommand: ["echo", "hello k8s job!"]restartPolicy: OnFailure # 指定什么情况下需要重启容器;对于Job只能设置为Never或者OnFailure。对于其他Controller可设为Always
Job一共启动了两个pod,在同一时间创建和结束:
通过
completions设置Job成功完成Pod的总数:
apiVersion: batch/v1 # 当前Job的apiVersionkind: Jobmetadata:name: myjobspec:completions: 6parallelism: 2 # 这两行的含义:每次运行两个Pod,直至有6个pod成功完成template:metadata:name: myjobspec:containers:- name: helloimage: busyboxcommand: ["echo", "hello k8s job!"]restartPolicy: OnFailure # 指定什么情况下需要重启容器;对于Job只能设置为Never或者OnFailure。对于其他Controller可设为Always
每次运行两个Pod,直至有6个pod成功完成:
五、定时执行Job
Kubernetes的
CronJob提供了定时执行Job。
apiVersion: batch/v1 # 当前CronJob的apiVersionkind: CronJobmetadata:name: hellospec:schedule: "*/1 * * * *" # 格式与linux cron一致jobTemplate: # 定义job模板spec:template:spec:containers:- name: helloimage: busyboximagePullPolicy: IfNotPresentcommand: ["echo", "hello k8s job!"]restartPolicy: Never # 指定什么情况下需要重启容器;对于Job只能设置为Never或者OnFailure。对于其他Controller可设为Always
直接
kubectl apply -f cronjob.yaml会失败:
因为
kubernetes默认没有enable cronjob功能,需要在kube-apiserver中加入
这个功能,方法如下:
修改kube-apiserver的配置文件/etc/kubernetes/manifests/kube-apiserver.yaml
kube-apiserver 本身也是个 Pod,在启动参数中加上 --runtime-config=batch/v2alpha1=true 即可。
然后重启 kubelet 服务:systemctl restart kubelet.service
kubelet 会重启 kube-apiserver Pod。通过 kubectl api-versions 确认 kube-apiserver 现在已经支持 batch/v2alpha1:
再次
kubectl apply -f cronjob.yaml,ok。通过
kubectl get cronjob 查看 CronJob 的状态:
等待几分钟后,通过
kubectl get jobs查看Job的执行情况:cronjob可以自动清理任务,
默认保留3次成功的任务
每隔1分钟就启动一个Job。执行kubectl logs查看某个Job的运行日志:
hello k8s job!
spec.successfulJobsHistoryLimit:3, 每次限制启动的cronjob的个数为3个:可以修改这个参数改变保留历史任务信息