Kubernetes技术详解-从理论到实践-(15)-控制器-CronJob
·
1 CronJob定时任务控制器简介
CronJob是指在Kubernetes集群里按照类Unix cron语法周期性地创建Job,适合定时备份、统计、清理、巡检等到点就跑一次的任务。
2 CronJob的特点
| 特性 | 说明 |
|---|---|
| 调度语法 | 与Linux crontab 相同:分 时 日 月 周(0-59 0-23 1-31 1-12 0-6) |
| 并发策略 | concurrencyPolicy: Allow/Forbid/Replace决定是否允许多个Job同时跑 |
| 历史限制 | successfulJobsHistoryLimit/failedJobsHistoryLimit控制保留已结束Job的数量,防止etcd膨胀 |
| 时区支持 | 集群可设.spec.timeZone: “Asia/Shanghai”(需开启特性,1.24+版本支持) |
| 一次性或索引 | 底层仍是Job,可跑单个Pod也可跑并行索引作业 |
3 CronJob常用场景
| 场景 | 举例 |
|---|---|
| 定时备份 | 数据库、ETCD、GitLab 仓库快照 |
| 日志/数据清理 | 删除7天前日志、压缩旧数据 |
| 统计报表 | 每日凌晨生成销售日报、资源使用率报告 |
| 证书续期 | 每天03:00检查并更新Encrypt证书 |
| 镜像/缓存刷新 | 周期性重新拉取最新基础镜像 |
| 健康巡检 | 每10分钟扫描一次集群安全策略 |
4 CronJob与Job的区别
| 维度 | Job | CronJob |
|---|---|---|
| 触发方式 | 手动/一次性 | 定时自动 |
| 对象类型 | batch/v1 Job | batch/v1 CronJob |
| 历史记录 | 手动删除 | 自动保留可配置份数 |
| 并发控制 | 无 | 有concurrencyPolicy |
5 一个典型的CronJob控制器资源清单文件
下面是一份生产中常用的定时备份资源清单。
这份CronJob资源清单的功能是:
每天02:30(上海时区)触发一次,生成Job、启动Pod、mysqldump全库压缩及上传MinIO分布式对象存储系统,并发被禁止、历史记录保留3份、失败重试3次、全程不超过1小时。
apiVersion: batch/v1 # 1. API版本:batch/v1为CronJob稳定版本
kind: CronJob # 2. 资源类型:CronJob(定时任务)
metadata:
name: mysql-backup # 3. 对象名称,集群内唯一
namespace: default # 4. 所属命名空间,可省略(默认 default)
spec:
schedule: "30 2 * * *" # 5. crontab语法:每天02:30触发
concurrencyPolicy: Forbid # 6. 并发策略:上一次未跑完则跳过新一次
successfulJobsHistoryLimit: 3 # 7. 保留成功Job历史数(0=不保留)
failedJobsHistoryLimit: 3 # 8. 保留失败Job历史数
timeZone: "Asia/Shanghai" # 9. 1.24+集群支持:使用上海时区
startingDeadlineSeconds: 200 # 10. 调度窗口:02:30后200s内必须启动,否则标为Failed
jobTemplate: # 11. Job模板:每次调度生成一个Job对象
spec:
backoffLimit: 3 # 12. Job级别重试次数(Pod失败3次即放弃)
activeDeadlineSeconds: 3600 # 13. Job全局超时1h,到点强制删除仍在运行的Pod
template: # 14. Pod模板
spec:
restartPolicy: OnFailure # 15. 容器异常退出才重启;成功即Completed
containers:
- name: mysqldump # 16. 主容器:执行备份命令
image: mysql:8.0-debian # 17. 自带mysqldump客户端
env:
- name: MYSQL_PWD # 18. 通过环境变量注入密码,避免命令行泄漏
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
command: ["/bin/bash", "-c"]
args: # 19. 备份、压缩、上传到MinIO分布式对象存储系统
- |
set -e
DATE=$(date +%F-%H-%M)
mysqldump -h mysql -u root --all-databases --single-transaction --quick --lock-tables=false \
| gzip > /tmp/all-${DATE}.sql.gz
mc alias set minio http://minio:9000 ${MINIO_ACCESS_KEY} ${MINIO_SECRET_KEY}
mc cp /tmp/all-${DATE}.sql.gz minio/backups/mysql/
echo "Backup ${DATE} uploaded"
env:
- name: MINIO_ACCESS_KEY
valueFrom: {secretKeyRef: {name: minio-secret, key: accesskey}}
- name: MINIO_SECRET_KEY
valueFrom: {secretKeyRef: {name: minio-secret, key: secretkey}}
volumeMounts: # 20. 临时目录,避免容器层满
- name: tmp
mountPath: /tmp
volumes:
- name: tmp # 21. emptyDir卷,Pod删除即清理
emptyDir: {}
上述yaml的重要字段及作用:
| 字段 | 作用 |
|---|---|
| schedule | 标准5位crontab,双引号必填 |
| concurrencyPolicy | Allow(默认)/Forbid/Replace |
| startingDeadlineSeconds | 错过调度窗口后不再补跑 |
| successfulJobsHistoryLimit | 值为0表示完成后立即删除Job,不留历史 |
| timeZone | 需集群版本1.24+并开启CronJobTimeZone特性 |
| jobTemplate.spec.backoffLimit | 单个Job内Pod重启次数上限 |
| activeDeadlineSeconds | 整个Job最长存活时间,防挂死 |
使用方法
kubectl apply -f mysql-backup-cronjob.yaml # 创建CronJob对象
kubectl get cronjob mysql-backup # 查看CronJob对象
kubectl get job -l app=mysql-backup # 查看每次生成的Job对象
kubectl logs -f job/mysql-backup-*** # 查看备份实时日志
6 CronJob示例
接下来在一个控制平面节点和两个工作节点的集群运行一个CronJob示例,每隔1分钟向/root/k8s-test/datatime-cronjob.log文件写一行带时间戳的日志文件。
(1) 编写CronJob资源清单文件
该CronJob为定时任务,每分钟执行一次,schedule的语法规则和Uninx的cron语法规则相同。
[root@master 15-cronjob]# cat busybox-cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: time-writer-cj
spec:
schedule: "*/1 * * * *" # one time per minute
jobTemplate:
spec:
template:
spec:
containers:
- name: writer
image: busybox:1.34.1
command:
- /bin/sh
- -c
- |
echo "$(date '+%F %T') - hello from busybox" >> /opt/cronjob/time-cronjob.log
volumeMounts:
- name: hostdir
mountPath: /opt/cronjob
restartPolicy: OnFailure
volumes:
- name: hostdir
hostPath:
path: /root/k8s-test/data
type: DirectoryOrCreate
(2) 创建CronJob
# 查看Job,CronJob,Pod,可以看到只有上次Job任务的Job和Pod
[root@master 15-cronjob]# kubectl get job
NAME COMPLETIONS DURATION AGE
time-writer-job 1/1 3s 6m32s
[root@master 15-cronjob]# kubectl get cronjob
No resources found in default namespace.
[root@master 15-cronjob]# kubectl get pod
NAME READY STATUS RESTARTS AGE
time-writer-job-cxr4c 0/1 Completed 0 6m40s
# 创建CronJob
[root@master 15-cronjob]# kubectl apply -f busybox-cronjob.yaml
cronjob.batch/time-writer-cj created
(3) 查看CronJob
# SCHEDULE为任务调度,这里为每分钟调度一次
[root@master 15-cronjob]# kubectl get cronjob
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
time-writer-cj */1 * * * * False 1 2s 7s
# cronjob会在触发调度时创建一个job
[root@master 15-cronjob]# kubectl get job
NAME COMPLETIONS DURATION AGE
time-writer-cj-29246273 1/1 3s 7s
time-writer-job 1/1 3s 7m1s
# 每次执行任务都会创建一个job
[root@master 15-cronjob]# kubectl get job
NAME COMPLETIONS DURATION AGE
time-writer-cj-29246273 1/1 3s 103s
time-writer-cj-29246274 1/1 3s 43s
time-writer-job 1/1 3s 8m37s
# 第三个job
[root@master 15-cronjob]# kubectl get job
NAME COMPLETIONS DURATION AGE
time-writer-cj-29246273 1/1 3s 2m12s
time-writer-cj-29246274 1/1 3s 72s
time-writer-cj-29246275 1/1 3s 12s
time-writer-job 1/1 3s 9m6s
# 可以看到cronjob被调度到了worker1节点
[root@master 15-cronjob]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
time-writer-cj-29246273-nc8m8 0/1 Completed 0 2m30s 10.42.1.3 worker1 <none> <none>
time-writer-cj-29246274-fmkc7 0/1 Completed 0 90s 10.42.1.4 worker1 <none> <none>
time-writer-cj-29246275-8xfq2 0/1 Completed 0 30s 10.42.1.5 worker1 <none> <none>
time-writer-job-cxr4c 0/1 Completed 0 9m24s 10.42.1.2 worker1 <none> <none>
[root@master 15-cronjob]#
(4) 查看CronJob的输出文件
【本步骤在worker1虚拟机执行】
由于本CronJob被调度到了worker1节点,所以需要进入worker1查看。
# 进入worker1节点宿主机目录
[root@worker1 data]# pwd
/root/k8s-test/data
# 可以看到生成了一个time-cronjob.log文件
[root@worker1 data]# ls
time-cronjob.log time-job.log
# 查看cronjob的输出,每秒执行一次
[root@worker1 data]# cat time-cronjob.log
2025-08-09 21:51:59 - hello from busybox
2025-08-09 21:52:59 - hello from busybox
2025-08-09 21:53:59 - hello from busybox
[root@worker1 data]#
更多推荐


所有评论(0)