title: K8s 系列 | 第 19 天:Job 与 CronJob:批处理与定时任务实战
tags:
– Kubernetes
– K8s系列
– DevOps
– Job
– CronJob
– 批处理
– 定时任务
K8s 系列 | 第 19 天:Job 与 CronJob:批处理与定时任务实战
第 19/30 天
一、引言
在生产环境中,我们不仅需要运行长期守护的 Web 服务(如 Nginx、API Server),还需要处理大量一次性或周期性的计算任务:数据批处理、数据库备份、日志清理、模型训练、报表生成等。Kubernetes 为此提供了两个专用控制器——Job 和 CronJob。
- Job:管理一次性任务,确保 Pod 成功执行到完成状态。
- CronJob:基于 Cron 表达式定时触发 Job,适用于周期性任务。
本文将深入讲解 Job 和 CronJob 的核心机制、实战用法、常见陷阱以及生产最佳实践。
二、Job 核心概念
2.1 什么是 Job?
Job 是 Kubernetes 的工作负载资源之一,用于运行有限次数的 Pod,并在 Pod 成功退出(exit code 0)后标记为完成。与 Deployment 不断重启 Pod 不同,Job 的 Pod 运行结束后就停止。
2.2 Job 的关键参数
| 参数 | 作用 | 默认值 |
|---|---|---|
.spec.completions |
需要成功完成的 Pod 数量 | 1 |
.spec.parallelism |
允许并行运行的 Pod 数量 | 1 |
.spec.backoffLimit |
失败重试次数上限 | 6 |
.spec.activeDeadlineSeconds |
Job 总运行时间上限 | 无 |
.spec.ttlSecondsAfterFinished |
完成后自动清理的等待时间 | 无 |
2.3 Job 的三种运行模式
- 单 Pod 模式(默认):
completions=1, parallelism=1— 一个 Pod 运行一次。 - 固定完成次数:
completions=N, parallelism=1— 串行执行 N 个 Pod。 - 工作队列模式:
completions=N, parallelism=M— 并行执行,共完成 N 个。 - 并行非队列模式:
completions=1, parallelism=M— M 个 Pod 同时运行,任意一个成功即完成。
三、Job 实战
3.1 创建一个简单的 Job
apiVersion: batch/v1
kind: Job
metadata:
name: pi-job
spec:
template:
spec:
containers:
- name: pi
image: perl:5.34
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4
运行并查看结果:
# 创建 Job
kubectl apply -f pi-job.yaml
# 查看 Job 状态
kubectl get job pi-job
# 查看 Pod 日志(Job 完成后 Pod 仍在,可查阅)
kubectl logs job/pi-job
3.2 并行 Job:数据处理场景
apiVersion: batch/v1
kind: Job
metadata:
name: data-processor
spec:
completions: 5
parallelism: 3
template:
spec:
containers:
- name: worker
image: busybox:1.36
command:
- sh
- -c
- |
echo "Processing batch $(date +%s) ..."
sleep 5
echo "Done."
restartPolicy: Never
backoffLimit: 2
# 查看并行进度
kubectl get pods -w
这里 parallelism=3 表示最多同时运行 3 个 Pod,completions=5 表示总共需要成功完成 5 个 Pod。如果某个 Pod 失败,Job 控制器会自动创建新的替换它,直到达到 backoffLimit。
3.3 限制 Job 运行时长
apiVersion: batch/v1
kind: Job
metadata:
name: timeout-job
spec:
activeDeadlineSeconds: 30
template:
spec:
containers:
- name: sleeper
image: busybox:1.36
command: ["sleep", "60"]
restartPolicy: Never
超过 30 秒后,Job 会被标记为 Failed,所有相关 Pod 被终止(DeadlineExceeded)。
3.4 自动清理已完成 Job
apiVersion: batch/v1
kind: Job
metadata:
name: cleanup-after-job
spec:
ttlSecondsAfterFinished: 60
template:
spec:
containers:
- name: echo
image: busybox:1.36
command: ["echo", "This job will be deleted after 60 seconds"]
restartPolicy: Never
设置 ttlSecondsAfterFinished 后,Kubernetes 会在 Job 完成后等待指定秒数,然后自动回收 Job 及其 Pod 对象。
四、CronJob 核心概念
4.1 什么是 CronJob?
CronJob 在 Job 的基础上增加了时间调度能力,使用标准的 Unix Cron 表达式定义执行周期。每次调度时,CronJob 控制器会创建一个新的 Job 对象。
4.2 CronJob 关键参数
| 参数 | 作用 | 默认值 |
|---|---|---|
.spec.schedule |
Cron 表达式(必需) | — |
.spec.jobTemplate |
创建的 Job 模板 | — |
.spec.startingDeadlineSeconds |
启动截止时间 | 无 |
.spec.concurrencyPolicy |
并发策略:Allow/Forbid/Replace | Allow |
.spec.successfulJobsHistoryLimit |
保留的成功 Job 数 | 3 |
.spec.failedJobsHistoryLimit |
保留的失败 Job 数 | 1 |
.spec.suspend |
暂停调度 | false |
4.3 Cron 表达式说明
K8s 使用标准 5 字段 Cron 格式(分 时 日 月 周),支持特殊语法:
* * * * *
│ │ │ │ │
│ │ │ │ └── 星期 (0-6, 0=周日)
│ │ │ └──── 月份 (1-12)
│ │ └────── 日期 (1-31)
│ └──────── 小时 (0-23)
└────────── 分钟 (0-59)
常用示例:
| 表达式 | 含义 |
|---|---|
*/5 * * * * |
每 5 分钟 |
0 */1 * * * |
每小时整点 |
0 2 * * * |
每天凌晨 2 点 |
0 0 * * 0 |
每周日凌晨 0 点 |
0 0 1 * * |
每月 1 日凌晨 0 点 |
五、CronJob 实战
5.1 创建定时备份 CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: db-backup
spec:
schedule: "0 3 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: bitnami/kubectl:latest
command:
- /bin/sh
- -c
- |
echo "Starting database backup at $(date)..."
kubectl exec db-pod -- pg_dump -U admin mydb > /backups/db-$(date +%Y%m%d).sql
echo "Backup complete: db-$(date +%Y%m%d).sql"
restartPolicy: OnFailure
successfulJobsHistoryLimit: 5
failedJobsHistoryLimit: 2
# 创建 CronJob
kubectl apply -f db-backup-cronjob.yaml
# 查看 CronJob
kubectl get cronjob db-backup
# 查看触发的 Job
kubectl get jobs --watch
5.2 并发策略详解
当上一个 Job 尚未完成而下一个调度时间已到时,concurrencyPolicy 决定行为:
apiVersion: batch/v1
kind: CronJob
metadata:
name: hourly-report
spec:
schedule: "0 * * * *"
concurrencyPolicy: Forbid # 不允许并发,跳过重叠执行
jobTemplate:
spec:
template:
spec:
containers:
- name: reporter
image: busybox:1.36
command:
- sh
- -c
- |
echo "Generating report... $(date)"
sleep 300 # 耗时 5 分钟
echo "Report done."
restartPolicy: Never
三种并发策略:
– Allow(默认):允许同时运行多个 Job 实例。
– Forbid:若前一个 Job 仍在运行,跳过本次调度。
– Replace:终止前一个 Job,创建新的 Job。
5.3 暂停与恢复 CronJob
# 暂停调度(保留已有 Job 运行)
kubectl patch cronjob db-backup -p '{"spec":{"suspend":true}}'
# 恢复调度
kubectl patch cronjob db-backup -p '{"spec":{"suspend":false}}'
# 手动触发一次(创建一次性的 Job)
kubectl create job --from=cronjob/db-backup manual-backup-$(date +%s)
六、常见问题与避坑指南
6.1 Job 不会自动重启 Pod
Job 默认的 restartPolicy 是 Never 或 OnFailure,不能设为 Always(K8s 会拒绝)。两者的区别:
Never:Pod 失败后,Job 控制器创建全新的 Pod 重试。OnFailure:Pod 失败时,kubelet 在原地重启容器。
建议使用 Never,配合 backoffLimit 控制重试次数,避免同一节点反复重启导致资源泄漏。
6.2 Job 完成后的 Pod 残留
默认情况下,Job 完成后 Pod 不会被自动删除,方便查看日志。生产环境建议设置:
spec:
ttlSecondsAfterFinished: 3600 # 一小时后自动清理
6.3 CronJob 的时间偏差问题
CronJob 控制器基于控制平面的系统时间调度。如果集群节点间时间不同步,可能导致:
- 调度时间不准确
- Job 启动延迟
✅ 最佳实践:保证所有节点部署 NTP 服务(chrony / ntpd)。
6.4 大量历史 Job 累积
长时间运行的 CronJob 会积累大量已完成的 Job 对象,给 etcd 带来压力:
spec:
successfulJobsHistoryLimit: 3 # 只保留最近 3 个成功记录
failedJobsHistoryLimit: 1 # 只保留最近 1 个失败记录
默认值分别是 3 和 1,已比较合理。如果日志审计需求强,建议将日志输出到外部存储(如 Elasticsearch)而非依赖 K8s 保留 Job 对象。
6.5 时区问题
CronJob 的 schedule 基于 kube-controller-manager 的时区(默认 UTC)。如果需要特定时区:
spec:
timeZone: "Asia/Shanghai"
schedule: "0 8 * * *"
⚠️
timeZone字段从 Kubernetes 1.27 开始 GA(CronJobTimeZone特性门控),更早版本不支持。
七、生产最佳实践总结
| 场景 | 推荐方案 |
|---|---|
| 一次性数据迁移 | Job(completions=1) |
| 并行数据处理 | Job(completions=N, parallelism=M) |
| 每天凌晨备份数据库 | CronJob(0 3 * * *) |
| 每 5 分钟清理临时文件 | CronJob(*/5 * * * *) |
| 不重叠的长时间任务 | CronJob(concurrencyPolicy: Forbid) |
| 自动清理历史记录 | ttlSecondsAfterFinished + historyLimit |
八、下期预告
第 20 天:PriorityClass 与抢占式调度机制
在生产集群中,如何确保关键业务 Pod 在资源紧张时优先获得调度?PriorityClass 是什么?抢占式调度(Preemption)如何工作?下一篇文章将为你深入解析 K8s 的优先级调度体系。
📚 系列目录
[K8s 系列 | 第 1 天:Kubernetes 是什么?核心概念与架构全景解析] → [第 2 天:kubeadm 搭建集群] → [第 3 天:Pod 详解] → … → [第 19 天:Job 与 CronJob] → 持续更新中…全部 30 篇文章,从基础到生产运维,每天一篇,欢迎收藏关注!















暂无评论内容