Kubernetes Job 和 CronJob 详解

文章目录
- Kubernetes Job 和 CronJob 详解
-
- 1. Job
-
- 1.1 Job 的类型
- 1.2 Job 的关键字段
- 1.3 Job 的生命周期
- 1.4 示例:并行计算圆周率
- 1.5 Job 的常见用途
- 2. CronJob
-
- 2.1 CronJob 的关键字段
- 2.2 CronJob 的工作机制
- 2.3 示例:每分钟打印时间
- 2.4 CronJob 的常见用途
- 3. 高级特性与最佳实践
-
- 3.1 索引 Job(Indexed Job)
- 3.2 Pod 失败策略(Pod Failure Policy)
- 3.3 资源管理和限制
- 3.4 监控与日志
- 3.5 清理历史
- 4. 总结
在 Kubernetes 中,
Job 和
CronJob 是用于管理
批处理型或
定时型工作负载的控制器。它们负责创建并确保一定数量的 Pod 成功运行终止,适用于一次性任务、并行计算、数据迁移、定时备份等场景。
1. Job
Job 会创建一个或多个 Pod,并持续重试直到指定数量的 Pod 成功退出。当 Pod 成功完成后,Job 记录完成状态;如果 Pod 失败,Job 会根据配置进行重试。适用于运行一次就结束的任务(如数据处理、计算任务)。
1.1 Job 的类型
根据 spec.completions 和 spec.parallelism 的不同组合,Job 可以分为三种常见模式:
| 非并行 Job | 通常只启动一个 Pod,Pod 成功退出后 Job 即完成。completions 和 parallelism 默认为 1。 | 单次任务,如数据库迁移、一次性脚本。 |
| 固定完成数并行 | 指定 completions 为总数,parallelism 为并发数。控制器会启动 Pod 直至成功数量达到 completions。 | 需要处理多个独立工作单元,如处理消息队列中的消息。 |
| 工作队列 Job | 不设置 completions(或设为 null),parallelism 设置并发数。Pod 自行判断何时所有工作已完成(通过外部信号或检查队列为空),然后 Pod 退出成功。此时 Job 视为完成。 | 并行消费任务队列,工作项数未知。 |
1.2 Job 的关键字段
apiVersion: batch/v1
kind: Job
metadata:
name: pi–job
spec:
parallelism: 2 最大并发 Pod 数
completions: 4 总共需要成功完成的 Pod 数
backoffLimit: 4 失败重试次数上限(超过则 Job 标记为失败)
activeDeadlineSeconds: 300 Job 整体运行时间上限(超过则终止)
ttlSecondsAfterFinished: 100 完成后自动清理的时间
template: Pod 模板
spec:
restartPolicy: Never Job 通常使用 Never 或 OnFailure
containers:
– name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
- spec.template:Pod 模板,必须设置 restartPolicy 为 Never 或 OnFailure(不能是 Always)。
- spec.parallelism:允许同时运行的 Pod 数量。默认为 1。
- spec.completions:期望成功完成的 Pod 数量。默认为 1。
- spec.backoffLimit:失败重试次数。当失败次数达到此值后,Job 标记为失败(状态显示 Failed)。默认 6。
- spec.activeDeadlineSeconds:Job 运行的最长时间(秒),超过后 Job 被终止(Pod 也会被删除),状态为 Failed(原因 DeadlineExceeded)。
- spec.ttlSecondsAfterFinished:Job 完成后(Finished 状态)自动删除的延迟时间。用于清理 Job 资源。需要开启 TTLAfterFinished 特性门控(1.12+ 默认开启)。
- spec.podFailurePolicy(1.25+ 稳定):根据 Pod 失败原因定义不同的处理策略(如忽略、重试、终止 Job)。
- spec.successPolicy(1.30+ alpha):基于某些条件的成功判断。
1.3 Job 的生命周期
- 创建 Job 后,控制器根据 parallelism 启动 Pod。
- Pod 运行并退出(成功或失败)。
- 成功:增加成功计数,如果达到 completions,Job 状态变为 Complete。
- 失败:根据 backoffLimit 决定是否重试;若超过限制,Job 变为 Failed。
- Job 完成后,若设置了 ttlSecondsAfterFinished,到期后 Job 会被自动删除(级联删除 Pod)。
1.4 示例:并行计算圆周率
kubectl apply -f – <<EOF
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
parallelism: 2
completions: 4
template:
spec:
restartPolicy: Never
containers:
– name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
EOF
此 Job 会启动 2 个并发 Pod,总共需要 4 个 Pod 成功计算圆周率。等待所有完成:
kubectl get jobs -w
1.5 Job 的常见用途
- 批处理任务(图像处理、日志分析)
- 数据库迁移或数据初始化
- 一次性脚本运行
- 并行测试执行
2. CronJob
CronJob 基于 Linux crontab 的调度格式,在指定时间点创建 Job 对象。由 CronJob 创建的 Job 名称会附加调度时间戳,避免命名冲突。
2.1 CronJob 的关键字段
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *" 每分钟执行一次
timeZone: "Asia/Shanghai" 可选(1.24+ beta),指定时区
startingDeadlineSeconds: 30 因各种原因错过调度后,最晚启动时间(秒)
concurrencyPolicy: Forbid 并发策略:Allow/Forbid/Replace
suspend: false 是否暂停调度
successfulJobsHistoryLimit: 3 保留的成功 Job 历史数
failedJobsHistoryLimit: 1 保留的失败 Job 历史数
jobTemplate: 定义要创建的 Job 模板
spec:
template:
spec:
restartPolicy: OnFailure
containers:
– name: hello
image: busybox
command: ["echo", "Hello, Kubernetes!"]
- spec.schedule:Cron 格式字符串(分钟 小时 日 月 星期)。支持 @daily、@hourly 等预定义调度。
- spec.timeZone:指定时区(如 "Asia/Shanghai"),需集群启用 CronJobTimeZone 特性门控(1.24+ beta,1.27+ GA)。
- spec.startingDeadlineSeconds:如果 Job 因为某种原因(节点故障、资源不足等)错过了预定时间,控制器会尝试在此时间窗口内补创建。如果超过此时间仍未开始,则视为失败并记录 MissSchedule。
- spec.concurrencyPolicy:
- Allow:允许并发运行多个 Job(默认)。
- Forbid:禁止并发,如果上一次创建的 Job 尚未完成,则跳过本次调度。
- Replace:取消当前正在运行的 Job,并用新 Job 替换。
- spec.suspend:为 true 时暂停所有后续调度,已运行的 Job 不受影响。
- spec.successfulJobsHistoryLimit / failedJobsHistoryLimit:保留历史 Job 的数量,超过的会被删除。默认为 3 和 1。
2.2 CronJob 的工作机制
每个 CronJob 会在其指定的调度时间创建一个 Job 对象,然后由 Job 控制器负责管理 Pod。CronJob 控制器使用最近一次调度时间判断是否错过了调度。如果集群负载高或控制器重启,可能会导致调度延迟或错过,因此设置合理的 startingDeadlineSeconds 很重要。
2.3 示例:每分钟打印时间
kubectl create cronjob print-time –image=busybox –schedule="*/1 * * * *" — date
查看 CronJob 和其创建的 Job:
kubectl get cronjobs
kubectl get jobs –watch
2.4 CronJob 的常见用途
- 定期备份数据库或文件
- 定时生成报表
- 定时清理资源
- 周期性健康检查
- 与 CI/CD 集成定期运行测试
3. 高级特性与最佳实践
3.1 索引 Job(Indexed Job)
从 Kubernetes 1.21 开始,可以为 Job 启用完成索引模式,通过设置 spec.completionMode: Indexed(默认 NonIndexed)。每个 Pod 会获得一个从 0 到 completions-1 的索引,通过环境变量 JOB_COMPLETION_INDEX 或 hostname 获取。适用于需要分片处理数据的场景(如每个 Pod 处理特定分片)。
apiVersion: batch/v1
kind: Job
metadata:
name: indexed–job
spec:
completions: 5
parallelism: 2
completionMode: Indexed
template:
spec:
restartPolicy: Never
containers:
– name: worker
image: busybox
command: ["sh", "-c", "echo processing index $JOB_COMPLETION_INDEX"]
代码解读:
最后一句话(command: ["sh", "-c", "echo processing index $JOB_COMPLETION_INDEX"])定义了容器启动时执行的命令。它做了以下几件事:
3.2 Pod 失败策略(Pod Failure Policy)
通过 spec.podFailurePolicy 可以根据 Pod 失败的具体原因(如退出码、条件)自定义 Job 的重试行为,避免无谓重试。
podFailurePolicy:
rules:
– action: FailJob 立即标记 Job 为失败
onExitCodes:
operator: In
values: [42]
– action: Ignore 忽略此次失败(不计入重试计数)
onPodConditions:
– type: DisruptionTarget 因抢占/驱逐导致的失败
3.3 资源管理和限制
Job 和 CronJob 的 Pod 应该设置合理的 resources.requests 和 limits,避免资源争抢导致失败。特别是 CronJob 可能同时运行多个 Job,需保证集群容量。
3.4 监控与日志
- 使用 kubectl logs 查看特定 Job Pod 的日志。
- 通过标签选择器(如 job-name=<job-name>)过滤 Pod。
- 对 CronJob 可设置告警,监控错过调度或失败次数。
3.5 清理历史
合理设置 successfulJobsHistoryLimit 和 failedJobsHistoryLimit,避免大量已完成 Job 占用 etcd 空间。对于一次性 Job,可以使用 ttlSecondsAfterFinished 自动清理。
4. 总结
| 用途 | 一次性或并行批处理任务 | 定时触发 Job |
| 核心 | 确保一定数量的 Pod 成功退出 | 按 Cron 表达式创建 Job |
| 关键字段 | completions, parallelism, backoffLimit | schedule, jobTemplate, concurrencyPolicy |
| 生命周期 | 完成或失败后保留(可设置 TTL 自动清理) | 每次调度创建一个新的 Job,历史保留受限制 |
| 适用场景 | 数据计算、迁移、并行处理 | 定时备份、报表生成、周期性任务 |
通过 Job 和 CronJob,Kubernetes 能够高效、可靠地运行各种非长期运行的工作负载,并与生态系统(如 Prometheus 监控、日志收集)无缝集成。正确理解其行为并配置相关参数,可以帮助你构建健壮的批处理系统。




