CronJob 可以用来执行基于时间计划的定时任务,类似于Linux/Unix系统中的 crontable(opens new window)

CronJob 执行周期性的重复任务时非常有用,例如备份数据、发送邮件等。CronJob 也可以用来指定将来某个时间点执行单个任务,例如将某项任务定时到系统负载比较低的时候执行。

CronJob 也存在某些限制,例如,在某些情况下,一个 CronJob 可能会创建多个 Job。因此,Job 必须是 幂等 的。

创建CronJob


下面例子中的 CronJob 每分钟,打印一次当前时间并输出 hello world 信息。

  1. apiVersion: batch/v1beta1
  2. kind: CronJob
  3. metadata:
  4. name: hello
  5. spec:
  6. schedule: "*/1 * * * *"
  7. jobTemplate:
  8. spec:
  9. template:
  10. spec:
  11. containers:
  12. - name: hello
  13. image: busybox
  14. args:
  15. - /bin/sh
  16. - -c
  17. - date; echo Hello from the Kubernetes cluster
  18. restartPolicy: OnFailure
  1. <br /> 输出结果如下所示:
  2. ```bash
  3. cronjob.batch/hello created


或者,您也可以直接使用 kubectl run 命令创建 CronJob:

  1. kubectl run hello --schedule="*/1 * * * *" --restart=OnFailure --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster"
  • 执行命令以查看已创建 CronJob 的状态 ```bash kubectl get cronjob hello
  1. <br /> 输出结果如下所示:
  2. ```bash
  3. NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
  4. hello */1 * * * * False 0 <none> 10s


从输出结果可以看到,该 CronJob 还未运行任何 Job。执行一下命令,并等候一分钟左右时间

  1. kubectl get jobs --watch


输出结果如下所示:

  1. NAME COMPLETIONS DURATION AGE
  2. hello-4111706356 0/1 0s
  3. hello-4111706356 0/1 0s 0s
  4. hello-4111706356 1/1 5s 5s


此时,可以看到该 CronJob 创建了一个 “hello-4111706356” Job,并执行结束。这时ctrl + c 停止 watch,并重新查看 Cronjob 的状态:

  1. kubectl get cronjob hello


输出信息如下所示:

  1. NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
  2. hello */1 * * * * False 0 50s 75s


输出结果显示,该 CronJob 在 LAST SCHEDULE 这个时间点成功创建了一个 Job。当前 ACTIVE Job 数为 0,意味着,该 Job 已经成功结束,或者已经失败。

  • 查看 Pod 的输出信息执行命令获取 Pod 的名称 ```bash

    将 “hello-4111706356” 替换成您系统中的 Job name

    pods=$(kubectl get pods —selector=job-name=hello-4111706356 —output=jsonpath={.items[*].metadata.name})
  1. <br />查看 Pod 的日志:
  2. ```bash
  3. kubectl logs $pods


输出结果如下所示:

  1. Fri Feb 22 11:02:09 UTC 2019
  2. Hello from the Kubernetes cluster

删除CronJob


当您不再需要某个 CronJob 时,可以使用命令将其删除 kubectl delete cronjob ,在本例中,可以执行命令:

  1. kubectl delete cronjob hello

或者

  1. kubectl delete -f https://kuboard.cn/statics/learning/job/cronjob.yaml

删除 CronJob 时,将移除该 CronJob 创建的所有 Job 和 Pod,并且 CronJob 控制器将不会为其在创建任何新的 Job。更多信息请参考 垃圾回收

编写CronJob YAML


与其他所有 Kubernetes 对象一样,CronJob 对象需要 apiVersion、kind、metadata 这几个字段。CronJob 还需要 .spec 字段。

TIP 所有对 CronJob 对象作出的修改,尤其是 .spec 的修改,都只对修改之后新建的 Job 有效,已经创建的 Job 不会受到影响

Schedule

.spec.schedule 是一个必填字段。类型为 Cron(opens new window)格式的字符串,例如 0 或者 @hourly,该字段定义了 CronJob 应该何时创建和执行 Job。

该字段同样支持 vixie cron step 值(step values),参考 FreeBSD manual(opens new window)。例如,指定 CronJob 每隔两个小时执行一次,可以有如下三种写法:

  • 0 0,2,4,5,6,8,12,14,16,17,20,22 *)
  • 使用 范围值 + Step 值的写法:0 0-23/2 *
  • Step 也可以跟在一个星号后面,如 0 /2

TIP 问号 ? 与 星号 * 的含义相同,代表着该字段不做限定

Job Template

.spec.jobTemplate 字段是必填字段。该字段的结构与 Job 相同,只是不需要 apiVersion 和 kind。请参考 编写Job的定义

Starting Deadline

.spec.startingDeadlineSeconds 为可选字段,代表着从计划的时间点开始,最迟多少秒之内必须启动 Job。如果超过了这个时间点,CronJob 就不会为其创建 Job,并将其记录为一次错过的执行次数。如果该字段未指定,则 Job 必须在指定的时间点执行。

CronJob 控制器将为每一个 CronJob 记录错过了多少次执行次数,如果错过的执行次数超过 100,则控制器将不会再为该 CronJob 创建新的 Job。如果 .spec.startingDeadlineSeconds 未指定,CronJob 控制器计算从 .status.lastScheduleTime 开始到现在为止总共错过的执行次数。

例如,某一个 CronJob 应该每分钟执行一次,.status.lastScheduleTime 的值是 上午5:00,假设现在已经是上午7:00。这意味着已经有 120 次执行时间点被错过,因此该 CronJob 将不再执行了。

如果 .spec.startingDeadlineSeconds 字段被设置为一个非空的值,则 CronJob 控制器计算将从 .spec.startingDeadlineSeconds 秒以前到现在这个时间段内错过的执行次数。

例如,假设该字段被设置为 200,控制器将只计算过去 200 秒内错过的执行次数。如果在过去 200 秒之内,有超过 100 次错过的执行次数,则 CronJob 将不再执行。

Concurrency Policy

.spec.concurrencyPolicy 是选填字段,指定了如何控制该 CronJob 创建的 Job 的并发性,可选的值有:

  • Allow: 默认值,允许并发运行 Job
  • Forbid: 不允许并发运行 Job;如果新的执行时间点到了,而上一个 Job 还未执行完,则 CronJob 将跳过新的执行时间点,保留仍在运行的 Job,且不会在此刻创建新的 Job
  • Replace: 如果新的执行时间点到了,而上一个 Job 还未执行完,则 CronJob 将创建一个新的 Job 以替代正在执行的 Job

TIP Concurrency policy 只对由同一个 CronJob 创建的 Job 生效。如果有多个 CronJob,则他们各自创建的 Job 之间不会相互影响。

Suspend

.spec.suspend 是选填字段。如果该字段设置为 true,所有的后续执行都将挂起,该字段不会影响到已经创建的 Job。默认值为 false。

警告 挂起(suspend)的时间段内,如果恰好存在有计划的执行时间点,则这些执行时间计划都被记录下来。如果不指定 .spec.startingDeadlineSeconds,并将 .spec.suspend 字段从 true 修改为 false,则挂起这段时间内的执行计划都将被立刻执行。

Job History Limits

.spec.successfulJobsHistoryLimit 和 .spec.failedJobsHistoryLimit 字段是可选的。这些字段指定了 CronJob 应该保留多少个 completed 和 failed 的 Job 记录。

  • .spec.successfulJobsHistoryLimit 的默认值为 3
  • .spec.failedJobsHistoryLimit 的默认值为 1

如果将其设置为 0,则 CronJob 不会保留已经结束的 Job 的记录。