CronJob 按照预定的时间计划(schedule)创建 Job。一个 CronJob 对象类似于 crontab (cron table) 文件中的一行记录。该对象根据 Cron 格式定义的时间计划,周期性地创建 Job 对象。
CronJob 执行周期性的重复任务时非常有用,例如备份数据、发送邮件等。CronJob 也可以用来指定将来某个时间点执行单个任务,例如将某项任务定时到系统负载比较低的时候执行。
Schedule 所有 CronJob 的
schedule
中所定义的时间,都是基于 master 所在时区来进行计算的。
CronJob 的限制
一个 CronJob 在时间计划中的每次执行时刻,都创建 大约 一个 Job 对象。这里用到了 大约 ,是因为在少数情况下会创建两个 Job 对象,或者不创建 Job 对象。尽管 K8S 尽最大的可能性避免这种情况的出现,但是并不能完全杜绝此现象的发生。因此,Job 程序必须是 幂等的。
当以下两个条件都满足时,Job 将至少运行一次:
- startingDeadlineSeconds 被设置为一个较大的值,或者不设置该值(默认值将被采纳)
- concurrencyPolicy 被设置为 Allow
对于每一个 CronJob,CronJob 控制器将检查自上一次执行的时间点到现在为止有多少次执行被错过了。如果错过的执行次数超过了 100,则 CronJob 控制器将不再创建 Job 对象,并记录如下错误:
Cannot determine if job needs to be started. Too many missed start time (> 100). Set or decrease .spec.startingDeadlineSeconds or check clock skew.
非常重要的一点是,如果设置了 startingDeadlineSeconds
(非空 nil
),控制器将按照从 startingDeadlineSeconds
秒之前到现在为止的时间段计算被错过的执行次数,而不是按照从上一次执行的时间点到现在为止的时间段来计算被错过的执行次数。例如,如果 startingDeadlineSeconds
被设置为 200,则,控制器将计算过去 200 秒内,被错过的执行次数。
当 CronJob 在其计划的时间点应该创建 Job 时却创建失败,此时 CronJob 被认为错过了一次执行。例如,如果 concurrencyPolicy 被设置为 Forbid 且 CronJob 上一次创建的 Job 仍然在运行,此时 CronJob 再次遇到一个新的计划执行的时间点并尝试创建一个 Job,该此创建尝试将失败,并被认为错过了一次执行。
又例如,假设某个 CronJob 被设置为:自 08:30:00 开始,每分钟创建一个新的 Job,且 CronJob 的 startingDeadlineSeconds 字段未被设置。如果 CronJob 控制器恰好在 08:29:00 到 10:21:00 这个时间段出现故障(例如 Crash),则该 CronJob 将不会再次执行,因为其错过的执行次数已经超过了 100。
为了进一步解释这个概念,我们再列举一个例子,假设某个 CronJob 被设置为:自 08:30:00 开始,每分钟创建一个新的 Job,且 CronJob 的 startingDeadlineSeconds 字段被设置为 200 秒。同样,如果 CronJob 控制器恰好在 08:29:00 到 10:21:00 这个时间段出现故障(时间段与上个例子相同),此时 CronJob 控制器将在 10:22:00 为该 CronJob 创建一个 Job。这是因为,在这个例子中,控制器将只计算过去 200 秒中错过的执行次数(大约 3 次),而不是从上一次执行的时间点开始计算错过的执行次数。
CronJob 只负责按照时间计划的规定创建 Job 对象,由 Job 来负责管理具体 Pod 的创建和执行。
CronJob yml文件相关格式
Schedule
Job Template
Starting Deadline
Concurrency Policy
Suspend
Job History Limits
CronJob的使用
创建
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
kubectl get cronjob hello
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
hello */1 * * * * False 0 <none> 11s
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
hello */1 * * * * False 1 14s 2m48s
kubectl get jobs --watch
输出结果如下所示:
NAME COMPLETIONS DURATION AGE
hello-1585709460 1/1 34s 2m58s
hello-1585709520 1/1 29s 118s
hello-1585709580 1/1 19s 58s
hello-1585709640 0/1 0s
删除
删除 CronJob 时,将移除该 CronJob 创建的所有 Job 和 Pod,并且 CronJob 控制器将不会为其在创建任何新的 Job。
方法1:
kubectl delete cronjob hello
方法2:
kubectl delete -f cronjob.yaml
异常错误排查
kubectl describe cronjob [job-name] -n [namespace-Name]