我们经常需要进行批量数据处理和分析,以及按照时间进行调度执行。可以在Kubenrtes中使用容器技术完成,使用Job和CronJob来执行。这样,可以维护较为干净的执行环境,减少不同任务工具的相互干扰。同时可以在集群上按照任务要求和资源状况进行动态伸缩执行。
-
任务主要包含两种:
- Job负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。
- CronJob是基于调度的Job执行将会自动产生多个job,调度格式参考Linux的cron系统。
-
执行环境:
-
无论是job还是CronJob,
执行时都产生一个pod,然后在里面运行给定的命令
。- 要执行自己的任务,需要一个自己的Docker镜像和yaml格式的job描述文件。
-
执行环境是容器隔离
的,外部存储可以通过pvc/pv等挂载进去,与pod配置参数完全一致。 -
任务可以在整个集群环境中调度执行,因此:
-
资源访问是漂移的,可以使用nodeSelector固定要执行的节点
。
-
-
无论是job还是CronJob,
参考:
-
Cron调度周期制定和CronTab命令用法,
Linux执行定期任务-Cron和CronTab – openthings的个人空间 – OSCHINA – 中文开源技术交流社区
-
Kubernetes官方参考:
Running Automated Tasks with a CronJob | Kubernetes
1、Job,执行一次任务
Job Spec格式
- spec.template格式同Pod。
- RestartPolicy仅支持Never或OnFailure。
- 单个Pod时,默认Pod成功运行后Job即结束。
-
.spec.completions
标志Job结束需要成功运行的Pod个数,默认为1。 -
.spec.parallelism
标志并行运行的Pod的个数,默认为1。 -
spec.activeDeadlineSeconds
标志失败Pod的重试最大时间,超过这个时间不会继续重试。
一个简单的例子:
-
apiVersion: batch/v1beta1
-
kind: Job
-
metadata:
-
name: pi
-
spec:
-
template:
-
metadata:
-
name: pi
-
spec:
-
containers:
-
- name: pi
-
image: perl
-
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
-
restartPolicy: Never
- 注意,里面的template配置方法与Deployment配置参数是完全一样的,用于生成运行时的pod。可以在其中指定挂载卷、运行的命令等等。
执行工作任务:
-
$ kubectl create -f ./job.yaml
-
job "pi" created
-
$ pods=$(kubectl get pods --selector=job-name=pi --output=jsonpath={.items..metadata.name})
-
$ kubectl logs $pods
-
3.141592653589793238462643383279502...
2、CronJob,周期执行任务
Cron Job
管理基于时间的
Job
,即:
- 在给定时间点只运行一次。
- 周期性地在给定时间点运行。
一个 CronJob 对象类似于
crontab
(cron table)文件中的一行。
-
它根据指定的预定计划周期性地运行一个 Job,格式可以参考
Cron
。 -
Cron调度周期制定和CronTab命令用法,
Linux执行定期任务-Cron和CronTab – openthings的个人空间 – OSCHINA – 中文开源技术交流社区
典型的用法如下所示:
- 在给定的时间点调度 Job 运行
- 创建周期性运行的 Job,例如:数据库备份、发送邮件。
注意:
- 预估job的执行时间。给定的间隔一般不应少于该job的执行时间。
- 如果当前job尚未结束,达到时间触发点时,系统仍然会启动新的任务job。
- 如果大量job叠加启动,将会并发访问系统资源,可能导致系统响应变慢、甚至崩溃。
CronJob Spec
-
.spec.schedule
:
调度
,必需字段,指定任务运行周期,格式同
Cron
。 -
.spec.jobTemplate
:
Job 模板
,必需字段,指定需要运行的任务,格式同
Job
。 -
.spec.startingDeadlineSeconds
:
启动 Job 的期限(秒级别)
,该字段是可选的。-
如果因为任何原因而错过了被调度的时间,那么错过执行时间的 Job 将被认为是失败的。
-
如果没有指定,则没有期限。
-
-
.spec.concurrencyPolicy
:
并发策略
,该字段也是可选的。-
它指定了如何处理被 Cron Job 创建的 Job 的并发执行。只允许指定下面策略中的一种。
-
Allow
(默认):允许并发运行 Job。 -
Forbid
:禁止并发运行,如果前一个还没有完成,则直接跳过下一个。 -
Replace
:取消当前正在运行的 Job,用一个新的来替换。
-
-
注意,当前策略只能应用于同一个 Cron Job 创建的 Job。如果存在多个 Cron Job,它们创建的 Job 之间总是允许并发运行。
-
-
.spec.suspend
:
挂起
,该字段也是可选的。-
如果设置为
true
,后续所有执行都会被挂起。 -
它对已经开始执行的 Job 不起作用。默认值为
false
。
-
-
.spec.successfulJobsHistoryLimit
和
.spec.failedJobsHistoryLimit
:
历史限制
,是可选的字段。-
它们指定了可以保留多少完成和失败的 Job。
-
默认没有限制,所有成功和失败的 Job 都会被保留。
-
当运行一个 Cron Job 时,Job 可以很快就堆积很多,推荐设置这两个字段的值。
-
设置限制的值为
0
,相关类型的 Job 完成后将不会被保留。
-
创建任务描述文件
-
apiVersion: batch/v1beta1
-
kind: CronJob
-
metadata:
-
name: hello
-
spec:
-
schedule: "*/1 * * * *"
-
jobTemplate:
-
spec:
-
template:
-
spec:
-
containers:
-
- name: hello
-
image: busybox
-
args:
-
- /bin/sh
-
- -c
-
- date; echo Hello from the Kubernetes cluster
-
restartPolicy: OnFailure
上面的描述文件指定每分钟执行一次,输出一条信息。
启动任务运行
启动调度任务:
-
$ kubectl create -f cronjob.yaml
-
cronjob "hello" created
当然,也可以用
kubectl run
来创建一个CronJob:
kubectl run hello --schedule="*/1 * * * *" --restart=OnFailure --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster"
-
$ kubectl get cronjob
-
NAME SCHEDULE SUSPEND ACTIVE LAST-SCHEDULE
-
hello */1 * * * * False 0 <none>
-
$ kubectl get jobs
-
NAME DESIRED SUCCESSFUL AGE
-
hello-1202039034 1 1 49s
-
$ pods=$(kubectl get pods --selector=job-name=hello-1202039034 --output=jsonpath={.items..metadata.name} -a)
-
$ kubectl logs $pods
-
Mon Aug 29 21:34:09 UTC 2016
-
Hello from the Kubernetes cluster
-
# 注意,删除cronjob的时候不会自动删除job,这些job可以用kubectl delete job来删除
-
$ kubectl delete cronjob hello
-
cronjob "hello" deleted
Cron Job 限制
Cron Job 在每次调度运行时间内
“大概”
会创建一个 Job 对象。我们之所以说
“大概”
,是因为在特定的环境下可能会创建两个 Job,或者一个 Job 都没创建。我们尝试少发生这种情况,但却不能完全避免。因此,创建 Job 操作应该是
幂等的
。
Job 根据它所创建的 Pod 的并行度,负责重试创建 Pod,并就决定这一组 Pod 的成功或失败。Cron Job 根本就不会去检查 Pod。
删除 Cron Job
一旦不再需要 Cron Job,简单地可以使用
kubectl
命令删除它:
-
$ kubectl delete cronjob hello
-
cronjob "hello" deleted
这将会终止正在创建的 Job。然而,运行中的 Job 将不会被终止,不会删除 Job 或 它们的 Pod。为了清理那些 Job 和 Pod,需要列出该 Cron Job 创建的全部 Job,然后删除它们:
-
$ kubectl get jobs
-
NAME DESIRED SUCCESSFUL AGE
-
hello-1201907962 1 1 11m
-
hello-1202039034 1 1 8m
-
...
-
$ kubectl delete jobs hello-1201907962 hello-1202039034 ...
-
job "hello-1201907962" deleted
-
job "hello-1202039034" deleted
-
...
一旦 Job 被删除,由 Job 创建的 Pod 也会被删除。注意,所有由名称为“hello” 的 Cron Job 创建的 Job 会以前缀字符串 “hello-” 进行命名。如果想要删除当前 Namespace 中的所有 Job,可以通过命令
kubectl delete jobs --all
立刻删除它们。
转载于:https://my.oschina.net/u/2306127/blog/1784978