Kubernetes定时任务调度控制器
CronJob 按照 cron 表达式周期性地创建 Job,每个周期产生一个 Job 对象,再由 Job 创建 Pod 执行任务。它是「定时任务」在 Kubernetes 中的实现,适合备份、报表生成、缓存清理、证书续期、定期同步等场景。
CronJob 本身不执行任务,它只负责在正确的时间点创建一个 Job。因此排查 CronJob 问题时,顺序永远是:CronJob 状态 → Job 状态 → Pod 状态 → 容器日志。
kubectl [command] cronjob [flags]
CronJob 的常用简写为 cj:
kubectl get cj
kubectl describe cj backup
CronJob 使用标准 cron 格式,共 5 个字段,以空格分隔:
# ┌───────────── 分钟 (0 - 59)
# │ ┌───────────── 小时 (0 - 23)
# │ │ ┌───────────── 日 (1 - 31)
# │ │ │ ┌───────────── 月 (1 - 12)
# │ │ │ │ ┌───────────── 星期 (0 - 6,SUN=0,也可用 SUN、MON 等)
# │ │ │ │ │
# * * * * *
常用写法:
0 * * * * 每小时整点执行
*/5 * * * * 每 5 分钟执行
0 2 * * * 每天 2:00 执行
0 3 * * 0 每周日 3:00 执行
0 0 1 * * 每月 1 日 0:00 执行
30 1 * * 1-5 工作日 1:30 执行
apiVersion: batch/v1
kind: CronJob
metadata:
name: backup
namespace: default
spec:
schedule: "0 2 * * *"
timeZone: "Asia/Shanghai" # v1.27 起 GA,不设置则为 kube-controller-manager 的时区(通常为 UTC)
concurrencyPolicy: Forbid # Allow / Forbid / Replace
suspend: false
startingDeadlineSeconds: 200
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
backoffLimit: 2
activeDeadlineSeconds: 1800
ttlSecondsAfterFinished: 86400
template:
spec:
restartPolicy: OnFailure
containers:
- name: backup
image: bitnami/kubectl:1.31
command:
- /bin/sh
- -c
- 'kubectl get pods -A > /backup/pods-$(date +%F).txt'
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
volumeMounts:
- name: backup
mountPath: /backup
volumes:
- name: backup
persistentVolumeClaim:
claimName: backup-pvc
创建与查看:
kubectl apply -f cronjob.yaml
# 也可以用命令直接创建(注意 --schedule 是必填项)
kubectl create cronjob hello --image=busybox:1.36 \
--schedule="*/1 * * * *" -- date
kubectl get cronjob
kubectl get cj backup -o yaml
kubectl describe cronjob backup
CronJob 的状态里只保留最近一次调度时间,真正的历史在 Job 列表中:
# 查看由 CronJob 产生的所有 Job
kubectl get jobs --selector=job-name
kubectl get jobs -o wide
# 查看某个 Job 的 Pod 与日志
kubectl get pods --selector=job-name=backup-28934560
kubectl logs job/backup-28934560
# 查看 CronJob 上次调度时间与上次成功时间
kubectl get cj backup -o jsonpath='{.status.lastScheduleTime}{"\n"}{.status.lastSuccessfulTime}{"\n"}'
Job 名称由 CronJob 名加上调度时间生成,格式为 <cronjob-name>-<unix 分钟时间戳>,例如 backup-28934560。
# 立即创建一个 Job,不影响原有调度计划
kubectl create job --from=cronjob/backup backup-manual
# 查看结果
kubectl get jobs
kubectl logs job/backup-manual
# 暂停调度(已创建的 Job 不受影响)
kubectl patch cronjob backup -p '{"spec":{"suspend":true}}'
# 恢复调度
kubectl patch cronjob backup -p '{"spec":{"suspend":false}}'
# 也可以直接编辑
kubectl edit cronjob backup
concurrencyPolicy 决定上一次任务还没结束时,新一次调度该怎么办:
Allow 默认值,允许并发运行,可能同时存在多个 Job
Forbid 跳过本次调度,直到上一个 Job 结束
Replace 取消当前正在运行的 Job,用新的 Job 替代
Forbid 是最常用的选择 —— 例如备份任务不能并行执行,否则会互相覆盖文件。
schedule: "0 2 * * *" 在未设置 timeZone 时表示 UTC 2:00,国内用户会看到任务在早上 10 点执行,务必显式设置 timeZone: "Asia/Shanghai"。Cannot determine if job needs to be started. Too many missed start time (> 100),需要调整 startingDeadlineSeconds 或检查节点时钟漂移。startingDeadlineSeconds 若设置得过小,在控制器短暂不可用时会直接跳过任务;不设置则没有截止时间限制。restartPolicy 在 jobTemplate 中同样只能是 Never 或 OnFailure。successfulJobsHistoryLimit 与 failedJobsHistoryLimit 默认分别为 3 和 1,设置为 0 会导致历史记录被立即清理,排查问题时无从下手。suspend: true 只阻止新的调度,已经在运行的 Job 会继续执行完毕。schedule 后不会影响已经创建的 Job,只影响后续调度。kubectl — Kubernetes集群管理工具job — 一次性任务控制器pod — 最小调度单元deployment — 无状态工作负载控制器