Kubernetes Job
Job 与 CronJob 是 Kubernetes 中的 批处理(Batch)工作负载,用于执行一次性或周期性任务。
| Workload | 适用场景 | 特性 |
|---|---|---|
| Deployment | 持续运行服务 | 横向扩展、滚动升级 |
| StatefulSet | 有状态服务 | 固定身份、稳定存储 |
| DaemonSet | 每节点 Agent | 每节点运行 |
| Job | 执行一次且成功退出 | 保证完成 |
| CronJob | 周期性执行 | 类似 Linux crontab |
总结一句话:
- Job = 一次性任务。
- CronJob = 有计划的 Job。
Job 用于执行必须 成功一次 的任务。
常用于:
- 数据迁移
- 数据备份
- 文件清理
- 启动前初始化(Init 操作)
- 异步脚本(发送通知、执行 ETL)
一个最小的 Job:
apiVersion: batch/v1
kind: Job
metadata:
name: example-job
spec:
template:
spec:
restartPolicy: Never
containers:
- name: task
image: busybox
command: ["echo", "Hello World"]
restartPolicy
只能是:
- Never(推荐)
- OnFailure
不能使用 Always(否则不符合 Job 语义)。
backoffLimit
失败重试次数:
backoffLimit: 6 # 默认 6
超过限制 -> Job 进入 Failed 状态。
activeDeadlineSeconds
设置任务最大执行时长:
activeDeadlineSeconds: 300
避免 Job 卡死。
ttlSecondsAfterFinished
自动清理已完成的 Job:
ttlSecondsAfterFinished: 3600
不至于堆积。
Job 有 3 种执行模式:
spec.parallelism 未设置
一个 Pod 运行一次任务。
适合:
- 单任务执行(最常见)
completions: 5
parallelism: 2
含义:
- 一共需要完成 5 次
- 每次最多并行 2 个 Pod
适合:
- 重复性任务
- 并行计算
parallelism: 10
completions 未指定
通常与外部队列(RabbitMQ/Kafka)配套:
- 每个 Pod 从队列取任务
- 并行执行
- Pod 自行退出
CronJob 只是一个 定时触发的 Job。
示例:
apiVersion: batch/v1
kind: CronJob
metadata:
name: backup
spec:
schedule: "0 */6 * * *" # 每 6 小时执行一次
jobTemplate:
spec:
template:
spec:
restartPolicy: Never
containers:
- name: backup
image: alpine
command: ["sh", "-c", "echo backup run"]
CronJob 采用 Linux crontab 格式:
分 时 日 月 周
示例:
| schedule | 含义 |
|---|---|
"*/5 * * * *" |
每 5 分钟 |
"0 0 * * *" |
每天 0 点 |
"0 3 * * 1" |
每周一 3 点 |
"0 */6 * * *" |
每 6 小时 |
保留成功 Job 数量:
successfulJobsHistoryLimit: 3
失败 Job 数量:
failedJobsHistoryLimit: 1
允许延迟执行的时间(避免错过调度):
startingDeadlineSeconds: 200
处理上次任务没执行完的情况:
| 字段 | 含义 |
|---|---|
| Allow | 默认,允许并发多个 Job |
| Forbid | 禁止并发(上一个未完成 -> 本次跳过) |
| Replace | 杀掉旧 Job,启动新 Job |
例子:
concurrencyPolicy: Forbid
创建 Job
↓
Controller 创建 Pod
↓
Pod 运行完成
↓
成功/失败计数更新
↓
达到限制 (completions/backoffLimit)
↓
Job 标记为 Completed 或 Failed
CronJob 定时触发
↓
创建 Job(一个 Cron 时间点 = 一个 Job)
↓
Job 创建 Pod
↓
Pod 执行完成
- restartPolicy: Never
- backoffLimit
- activeDeadlineSeconds
- ttlSecondsAfterFinished
示例(最推荐):
spec:
backoffLimit: 3
activeDeadlineSeconds: 600
ttlSecondsAfterFinished: 3600
防止任务堆积:
concurrencyPolicy: Forbid
会导致无限重启 -> Job 卡死
使用:
kubectl get jobs -A
kubectl describe cronjob <name>
Kubernetes Job 控制器不是为毫秒级高频调度设计的。
每分钟一次已经是上限,秒级任务应该用:
- 内部定时器
- 流式计算
- 指标驱动(Event-driven)
防止单个任务吃光资源:
resources:
limits:
cpu: 500m
memory: 512Mi
可能原因:
- controller-manager 重启
- schedule 时间点太密集
- startingDeadlineSeconds 设置太小
因为:
successfulJobsHistoryLimit
failedJobsHistoryLimit
未设置。
原因:
- 没有可调度节点
- PVC 无法绑定
- 资源 quota 限制
- 调度器 taint 未容忍
取决于:
parallelism
CronJob 则由:
concurrencyPolicy
控制。
apiVersion: batch/v1
kind: CronJob
metadata:
name: mysql-backup
spec:
schedule: "0 3 * * *"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
jobTemplate:
spec:
backoffLimit: 2
activeDeadlineSeconds: 600
template:
spec:
restartPolicy: Never
containers:
- name: backup
image: alpine
command: ["sh", "-c", "mysqldump ... || exit 1"]
apiVersion: batch/v1
kind: Job
metadata:
name: migrate
spec:
backoffLimit: 3
activeDeadlineSeconds: 300
ttlSecondsAfterFinished: 3600
template:
spec:
restartPolicy: Never
containers:
- name: migrate
image: myapp:migrate
Job = 一次性任务
- 必须成功完成
- 支持重试
- 支持并行
- 可以自动清理
CronJob = 定时执行的 Job
- 和 Linux crontab 类似
- 支持并发策略
- 可控历史数量
- 适合周期任务