Update automated-tasks-with-cron-jobs.md
15 KiB
title, content_type, weight, min-kubernetes-server-version
| title | content_type | weight | min-kubernetes-server-version |
|---|---|---|---|
| 使用 CronJob 运行自动化任务 | task | 10 | v1.8 |
你可以利用 CronJobs 执行基于时间调度的任务。这些自动化任务和 Linux 或者 Unix 系统的 Cron 任务类似。
CronJobs 在创建周期性以及重复性的任务时很有帮助,例如执行备份操作或者发送邮件。CronJobs 也可以在特定时间调度单个任务,例如你想调度低活跃周期的任务。
CronJobs 有一些限制和特点。 例如,在特定状况下,同一个 CronJob 可以创建多个任务。 因此,任务应该是幂等的。 查看更多限制,请参考 CronJobs。
{{% heading "prerequisites" %}}
- {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
创建 CronJob
CronJob 需要一个配置文件。
本例中 CronJob 的.spec 配置文件每分钟打印出当前时间和一个问好信息:
{{< codenew file="application/job/cronjob.yaml" >}}
想要运行示例的 CronJob,可以下载示例文件并执行命令:
kubectl create -f https://k8s.io/examples/application/job/cronjob.yaml
cronjob.batch/hello created
创建好 CronJob 后,使用下面的命令来获取其状态:
kubectl get cronjob hello
输出类似于:
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
hello */1 * * * * False 0 50s 75s
就像你从命令返回结果看到的那样,CronJob 还没有调度或执行任何任务。大约需要一分钟任务才能创建好。
kubectl get jobs --watch
NAME COMPLETIONS DURATION AGE
hello-4111706356 0/1 0s
hello-4111706356 0/1 0s 0s
hello-4111706356 1/1 5s 5s
现在你已经看到了一个运行中的任务被 “hello” CronJob 调度。 你可以停止监视这个任务,然后再次查看 CronJob 就能看到它调度任务:
kubectl get cronjob hello
输出类似于:
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
hello */1 * * * * False 0 50s 75s
你应该能看到 “hello” CronJob 在 LAST-SCHEDULE 声明的时间点成功的调度了一次任务。
有 0 个活跃的任务意味着任务执行完毕或者执行失败。
现在,找到最后一次调度任务创建的 Pod 并查看一个 Pod 的标准输出。请注意任务名称和 Pod 名称是不同的。
{{< note >}} Job 名称和 Pod 名称不同。 {{< /note >}}
# 在你的系统上将 "hello-4111706356" 替换为 Job 名称
pods=$(kubectl get pods --selector=job-name=hello-4111706356 --output=jsonpath={.items..metadata.name})
查看 Pod 日志:
kubectl logs $pods
Fri Feb 22 11:02:09 UTC 2019
Hello from the Kubernetes cluster
删除 CronJob
当你不再需要 CronJob 时,可以用 kubectl delete cronjob <cronjob name> 删掉它:
kubectl delete cronjob hello
删除 CronJob 会清除它创建的所有任务和 Pod,并阻止它创建额外的任务。你可以查阅 垃圾收集。
编写 CronJob 声明信息
像 Kubernetes 的其他配置一样,CronJob 需要 apiVersion、kind、和 metadata 域。
配置文件的一般信息,请参考
部署应用 和
使用 kubectl 管理资源.
CronJob 配置也需要包括
.spec.
{{< note >}}
对 CronJob 的所有改动,特别是它的 .spec,只会影响将来的运行实例。
{{< /note >}}
时间安排
.spec.schedule 是 .spec 需要的域。它使用了 Cron
格式串,例如 0 * * * * or @hourly ,做为它的任务被创建和执行的调度时间。
该格式也包含了扩展的 vixie cron 步长值。
FreeBSD 手册中解释如下:
步长可被用于范围组合。范围后面带有
/<数字>可以声明范围内的步幅数值。 例如,0-23/2可被用在小时域来声明命令在其他数值的小时数执行 ( V7 标准中对应的方法是0,2,4,6,8,10,12,14,16,18,20,22)。 步长也可以放在通配符后面,因此如果你想表达 "每两小时",就用*/2。
{{< note >}}
调度中的问号 (?) 和星号 * 含义相同,表示给定域的任何可用值。
{{< /note >}}
任务模版
.spec.jobTemplate是任务的模版,它是必须的。它和
Job的语法完全一样,
除了它是嵌套的没有 apiVersion 和 kind。
编写任务的 .spec ,请参考
编写 Job 的Spec。
开始的最后期限
.spec.startingDeadlineSeconds 域是可选的。
它表示任务如果由于某种原因错过了调度时间,开始该任务的截止时间的秒数。过了截止时间,CronJob 就不会开始任务。
不满足这种最后期限的任务会被统计为失败任务。如果该域没有声明,那任务就没有最后期限。
CronJob 控制器会统计错过了多少次调度。如果错过了100次以上的调度,CronJob 就不再调度了。
当没有设置 .spec.startingDeadlineSeconds 时,CronJob 控制器统计从
status.lastScheduleTime 到当前的调度错过次数。
例如一个 CronJob 期望每分钟执行一次,status.lastScheduleTime是 5:00am,
但现在是 7:00am。那意味着 120 次调度被错过了,所以 CronJob 将不再被调度。
如果设置了 .spec.startingDeadlineSeconds 域(非空),CronJob 控制器统计从
.spec.startingDeadlineSeconds 到当前时间错过了多少次任务。
例如设置了 200,它会统计过去 200 秒内错过了多少次调度。
在那种情况下,如果过去 200 秒内错过了超过 100 次的调度,CronJob 就不再调度。
并发性规则
.spec.concurrencyPolicy 也是可选的。它声明了 CronJob 创建的任务执行时发生重叠如何处理。
spec 仅能声明下列规则中的一种:
Allow(默认):CronJob 允许并发任务执行。Forbid: CronJob 不允许并发任务执行;如果新任务的执行时间到了而老任务没有执行完,CronJob 会忽略新任务的执行。Replace:如果新任务的执行时间到了而老任务没有执行完,CronJob 会用新任务替换当前正在运行的任务。
请注意,并发性规则仅适用于相同 CronJob 创建的任务。如果有多个 CronJob,它们相应的任务总是允许并发执行的。
挂起
.spec.suspend域也是可选的。如果设置为 true ,后续发生的执行都会挂起。
这个设置对已经开始的执行不起作用。默认是关闭的。
{{< caution >}}
在调度时间内挂起的执行都会被统计为错过的任务。当 .spec.suspend 从 true 改为 false 时,
且没有 开始的最后期限,错过的任务会被立即调度。
{{< /caution >}}
任务历史限制
.spec.successfulJobsHistoryLimit 和 .spec.failedJobsHistoryLimit是可选的。
这两个域声明了有多少执行完成和失败的任务会被保留。
默认设置为3和1。限制设置为0代表相应类型的任务完成后不会保留。