diff --git a/content/zh/docs/tasks/job/automated-tasks-with-cron-jobs.md b/content/zh/docs/tasks/job/automated-tasks-with-cron-jobs.md new file mode 100644 index 0000000000..6739e2f780 --- /dev/null +++ b/content/zh/docs/tasks/job/automated-tasks-with-cron-jobs.md @@ -0,0 +1,362 @@ + + +--- +reviewers: +- chenopis + +title: 使用 CronJob 运行自动化任务 +content_template: templates/task +weight: 10 +--- + +{{% capture overview %}} + + + +你可以利用 [CronJobs](/docs/concepts/workloads/controllers/cron-jobs) 执行基于时间调度的任务。这些自动化任务和 Linux 或者 Unix 系统的 [Cron](https://en.wikipedia.org/wiki/Cron) 任务类似。 + +CronJobs 在创建周期性以及重复性的任务时很有帮助,例如执行备份操作或者发送邮件。CronJobs 也可以在特定时间调度单个任务,例如你想调度低活跃周期的任务。 + +{{< note >}} + +从集群版本1.8开始,`batch/v2alpha1` API 组中的 CronJob 资源已经被废弃。 +你应该切换到 API 服务器默认启用的 `batch/v1beta1` API 组。本文中的所有示例使用了`batch/v1beta1`。 +{{< /note >}} + + + +CronJobs 有一些限制和特点。 +例如,在特定状况下,同一个 CronJob 可以创建多个任务。 +因此,任务应该是幂等的。 +查看更多限制,请参考 [CronJobs](/docs/concepts/workloads/controllers/cron-jobs)。 + +{{% /capture %}} + +{{% capture prerequisites %}} + +* {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} + + +* 你需要一个版本 >=1.8 且工作正常的 Kubernetes 集群。对于更早的版本( <1.8 ),你需要对 API 服务器设置 `--runtime-config=batch/v2alpha1=true` 来开启 `batch/v2alpha1` API,(更多信息请查看 [为你的集群开启或关闭 API 版本](/docs/admin/cluster-management/#turn-on-or-off-an-api-version-for-your-cluster) +), 然后重启 API 服务器和控制管理器。 + +{{% /capture %}} + +{{% capture steps %}} + + + +## 创建 CronJob + +CronJob 需要一个配置文件。 +本例中 CronJob 的`.spec` 配置文件每分钟打印出当前时间和一个问好信息: + +{{< codenew file="application/job/cronjob.yaml" >}} + + + +想要运行示例的 CronJob,可以下载示例文件并执行命令: + +```shell +$ kubectl create -f ./cronjob.yaml +cronjob "hello" created +``` + + + +或者你也可以使用 `kubectl run` 来创建一个 CronJob 而不需要编写完整的配置: + +```shell +$ kubectl run hello --schedule="*/1 * * * *" --restart=OnFailure --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster" +cronjob "hello" created +``` + + + +创建好 CronJob 后,使用下面的命令来获取其状态: + +```shell +$ kubectl get cronjob hello +NAME SCHEDULE SUSPEND ACTIVE LAST-SCHEDULE +hello */1 * * * * False 0 +``` + + + +就像你从命令返回结果看到的那样,CronJob 还没有调度或执行任何任务。大约需要一分钟任务才能创建好。 + +```shell +$ kubectl get jobs --watch +NAME DESIRED SUCCESSFUL AGE +hello-4111706356 1 1 2s +``` + + + +现在你已经看到了一个运行中的任务被 “hello” CronJob 调度。你可以停止监视这个任务,然后再次查看 CronJob 就能看到它调度任务: + +```shell +$ kubectl get cronjob hello +NAME SCHEDULE SUSPEND ACTIVE LAST-SCHEDULE +hello */1 * * * * False 0 Mon, 29 Aug 2016 14:34:00 -0700 +``` + + + +你应该能看到 “hello” CronJob 在 `LAST-SCHEDULE` 声明的时间点成功的调度了一次任务。有0个活跃的任务意味着任务执行完毕或者执行失败。 + +现在,找到最后一次调度任务创建的 Pod 并查看一个 Pod 的标准输出。请注意任务名称和 Pod 名称是不同的。 + + +```shell +# Replace "hello-4111706356" with the job name in your system +$ pods=$(kubectl get pods --selector=job-name=hello-4111706356 --output=jsonpath={.items..metadata.name}) + +$ echo $pods +hello-4111706356-o9qcm + +$ kubectl logs $pods +Mon Aug 29 21:34:09 UTC 2016 +Hello from the Kubernetes cluster +``` + + + +## 删除 CronJob + +当你不再需要 CronJob 时,可以用 `kubectl delete cronjob` 删掉它: + +```shell +$ kubectl delete cronjob hello +cronjob "hello" deleted +``` + + +删除 CronJob 会清除它创建的所有任务和 Pod,并阻止它创建额外的任务。你可以查阅 [垃圾收集](/docs/concepts/workloads/controllers/garbage-collection/)。 + + + +## 编写 CronJob 声明信息 + +像 Kubernetes 的其他配置一样,CronJob 需要 `apiVersion`、 `kind`、 和 `metadata` 域。配置文件的一般信息,请参考 [部署应用](/docs/user-guide/deploying-applications) 和 [使用 kubectl 管理资源](/docs/user-guide/working-with-resources). + +CronJob 配置也需要包括[`.spec`](https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status). + +{{< note >}} + +对 CronJob 的所有改动,特别是它的 `.spec`,只会影响将来的运行实例。 +{{< /note >}} + + + +### 时间安排 + +`.spec.schedule` 是 `.spec` 需要的域。它使用了 [Cron](https://en.wikipedia.org/wiki/Cron) 格式串,例如 `0 * * * *` or `@hourly` ,做为它的任务被创建和执行的调度时间。 + + + +该格式也包含了扩展的 `vixie cron` 步长值。[FreeBSD 手册](https://www.freebsd.org/cgi/man.cgi?crontab%285%29)中解释如下: + + + +> 步长可被用于范围组合。范围后面带有 ``/<数字>'' 可以声明范围内的步幅数值。 +> 例如,``0-23/2'' 可被用在小时域来声明命令在其他数值的小时数执行( V7 标准中对应的方法是``0,2,4,6,8,10,12,14,16,18,20,22'')。 +> 步长也可以放在通配符后面,因此如果你想表达 ``每两小时'',就用 ``*/2'' 。 + +{{< note >}} + +调度中的问号 (`?`) 和星号 `*` 含义相同,表示给定域的任何可用值。 +{{< /note >}} + + + +### 任务模版 + +`.spec.jobTemplate`是任务的模版,它是必须的。它和 [Job](/docs/concepts/workloads/controllers/jobs-run-to-completion/)的语法完全一样,除了它是嵌套的没有 `apiVersion` 和 `kind`。 +编写任务的 `.spec` ,请参考 [编写任务的Spec](/docs/concepts/workloads/controllers/jobs-run-to-completion/#writing-a-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` 时,且没有 [开始的最后期限](#starting-deadline),错过的任务会被立即调度。 +{{< /caution >}} + + + +### 任务历史限制 + +`.spec.successfulJobsHistoryLimit` 和 `.spec.failedJobsHistoryLimit`是可选的。 +这两个域声明了有多少执行完成和失败的任务会被保留。 +默认设置为3和1。限制设置为0代表相应类型的任务完成后不会保留。 + +{{% /capture %}} diff --git a/content/zh/examples/application/job/cronjob.yaml b/content/zh/examples/application/job/cronjob.yaml new file mode 100644 index 0000000000..c9d3893027 --- /dev/null +++ b/content/zh/examples/application/job/cronjob.yaml @@ -0,0 +1,18 @@ +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