摘要:使用 Job 管理一次性批处理任务,掌握完成次数、并行度、失败重试、超时、自动清理、索引任务与 Pod 失败策略。
本节学习 Kubernetes 中用于管理一次性任务的工作负载控制器——Job。
现在考虑一个新的场景:
假设你有一个应用,需要每天执行一次数据统计任务。
执行过程:
flowchart TB
N0["启动容器"]
N1["读取数据库"]
N2["统计数据"]
N3["生成报表"]
N4["任务完成"]
N5["容器退出"]
N0 --> N1
N1 --> N2
N2 --> N3
N3 --> N4
N4 --> N5
这类任务不需要容器一直运行。
如果使用 Deployment,容器退出后可能被重新启动,反而无法符合一次性任务的需求。
因此 Kubernetes 提供了 Job。
Job 的核心作用:确保指定数量的任务成功完成。
一、Job 基本概念
1. 什么是 Job?
Job 是 Kubernetes 中用于管理一次性任务的工作负载控制器。
它负责:
- 创建执行任务的 Pod。
- 监控任务执行状态。
- 任务失败时根据策略重试。
- 统计成功完成的任务数量。
- 达到目标后将 Job 标记为完成。
例如:
flowchart TB
N0["Job"]
N1["Pod"]
N2["Container"]
N3["执行任务"]
N4["Completed"]
N5["重试"]
N0 --> N1
N1 --> N2
N2 --> N3
N3 -->|"成功"| N4
N3 -->|"失败"| N5
典型应用:
| 场景 | 示例 |
|---|---|
| 数据库操作 | 数据迁移、初始化 |
| 批量处理 | 批量导入数据 |
| 数据计算 | 统计分析 |
| 文件处理 | 图片压缩、文件转换 |
| 运维任务 | 定期备份、数据清理 |
| 自动化任务 | 批量执行脚本 |
2. Job 与 Deployment 的区别
这是 CKA 必须掌握的知识点。
| 对比 | Deployment | Job |
|---|---|---|
| 主要用途 | 长期运行服务 | 一次性任务 |
| 运行目标 | 持续提供服务 | 成功完成任务 |
| 容器退出 | 通常重启 | 根据任务结果判断 |
| 生命周期 | 长期 | 通常短期 |
| 典型应用 | Nginx、API | 数据迁移、批处理 |
例如:
Deployment:
flowchart TB
N0["Nginx"]
N1["持续运行"]
N2["提供 Web 服务"]
N0 --> N1
N1 --> N2
Job:
flowchart TB
N0["数据迁移任务"]
N1["执行脚本"]
N2["成功退出"]
N3["Job Completed"]
N0 --> N1
N1 --> N2
N2 --> N3
二、Job 的 YAML 结构
1. 创建一个简单 Job
创建文件:
vim job.yaml编写:
apiVersion: batch/v1kind: Job
metadata: name: hello-job
spec: template: spec: containers: - name: hello image: busybox:1.36 command: - sh - -c - "echo Hello Kubernetes Job"
restartPolicy: Never这里注意:
restartPolicy: NeverJob 的 Pod 模板只允许使用:
- Never
- OnFailure
不允许使用 Always。
为什么?
因为 Job 是一次性任务,不能像 Deployment 一样无限期维持容器运行。
2. 创建 Job
kubectl apply -f job.yaml查看:
kubectl get jobs输出示例:
NAME COMPLETIONS DURATION AGEhello-job 1/1 3s 10s其中:
| 字段 | 含义 |
|---|---|
| COMPLETIONS | 成功完成的任务数 |
| DURATION | 任务执行时间 |
| AGE | Job 创建时间 |
查看 Pod:
kubectl get pods可能看到:
NAME READY STATUShello-job-abc12 0/1 Completed查看日志:
kubectl logs hello-job-abc12输出:
Hello Kubernetes Job注意:Job 成功完成后,Pod 默认不会立即删除,以便查看任务日志和排查问题。
三、Job 的核心参数
Job 有几个非常重要的字段:
| 参数 | 作用 |
|---|---|
| completions | 需要成功完成多少个任务 |
| parallelism | 最多允许多少个任务并行运行 |
| backoffLimit | 允许的失败重试次数 |
| activeDeadlineSeconds | Job 最大运行时间 |
| ttlSecondsAfterFinished | 完成后多久自动清理 Job |
这些是 CKA 的重点。
1. completions:任务完成次数
假设:
spec: completions: 5表示需要成功完成 5 个任务。
例如:
flowchart TB
N0["Job"]
N1["Pod-1 成功"]
N2["Pod-2 成功"]
N3["Pod-3 成功"]
N4["Pod-4 成功"]
N5["Pod-5 成功"]
N0 --> N1
N0 --> N2
N0 --> N3
N0 --> N4
N0 --> N5
当成功完成数量达到 5,Job 就会进入 Complete 状态。
注意:
completions 表示成功完成次数,不代表最多创建 5 个 Pod。失败的任务可能会导致额外创建 Pod。
2. parallelism:并行执行数量
假设:
spec: completions: 5 parallelism: 2表示:
- 总共需要成功完成 5 个任务。
- 最多同时运行 2 个任务 Pod。
执行过程可能是:
Job 并行执行示意
flowchart TB
subgraph G0["第一批"]
direction TB
N0["Pod-1<br/>成功"]
N1["Pod-2<br/>成功"]
end
subgraph G1["第二批"]
direction TB
N2["Pod-3<br/>成功"]
N3["Pod-4<br/>成功"]
end
subgraph G2["第三批"]
direction TB
N4["Pod-5<br/>成功"]
end
N5["5 个任务全部完成"]
G0 --> G1
G1 --> G2
G2 --> N5
这里最多同时运行两个 Pod。
注意:parallelism 是并发上限,不保证每个时刻都能有这么多 Pod 运行,还会受到调度、资源和任务完成速度影响。
3. completions 和 parallelism 综合示例
apiVersion: batch/v1kind: Job
metadata: name: batch-job
spec: completions: 10 parallelism: 3
template: spec: containers: - name: worker image: busybox:1.36 command: - sh - -c - "echo processing; sleep 10"
restartPolicy: Never含义:
总任务数量:10最大并行数量:3每个任务执行时间:约 10 秒如果集群资源充足,任务大致分为四批执行:
第一批:3 个第二批:3 个第三批:3 个第四批:1 个四、Job 失败重试机制(backoffLimit)
实际生产环境中,任务不一定每次都能成功。
例如:
- 数据库暂时无法连接。
- 网络请求超时。
- 外部服务暂时不可用。
- 执行脚本发生异常。
Job 需要具备失败重试能力。
1. backoffLimit 是什么?
backoffLimit 表示 Job 允许的失败次数上限。
例如:
spec: backoffLimit: 3表示 Job 在失败次数达到限制后,会被判定为失败。
默认情况下,backoffLimit 为 6。
注意:这里统计的是 Job 的失败尝试,不应简单理解为最多创建几个 Pod。具体重试行为还取决于 Pod 重启策略和失败类型。
2. Job 失败重试过程
flowchart TB
N0["创建 Job"]
N1["创建 Pod"]
N2["执行任务"]
N3["Completed"]
N4["检查失败次数"]
N5["重试"]
N6["Failed"]
N0 --> N1
N1 --> N2
N2 -->|"成功"| N3
N2 -->|"失败"| N4
N4 -->|"未超限"| N5
N4 -->|"已超限"| N6
3. 重试退避机制
Job 并不会在失败后立即无限快速重试。
它采用指数退避机制(Exponential Backoff)。
大致表现为:
flowchart TB
N0["第一次失败"]
N1["等待约 10 秒"]
N2["第二次失败"]
N3["等待约 20 秒"]
N4["第三次失败"]
N5["等待约 40 秒"]
N0 --> N1
N1 --> N2
N2 --> N3
N3 --> N4
N4 --> N5
实际等待时间还会受到退避上限等机制影响。
为什么需要指数退避?
假设数据库已经宕机,如果 Kubernetes 不断高速创建任务 Pod,就可能进一步增加数据库和集群的压力。
通过逐步延长重试间隔,可以减少无效重试。
4. OnFailure 与 Never 的区别
Job 的 Pod 支持两种重启策略。
Never
restartPolicy: Never容器失败后,当前 Pod 不会重新启动。
Job Controller 可以创建新的 Pod 重新执行任务。
flowchart TB
N0["Pod-1:Failed"]
N1["Job Controller"]
N2["创建 Pod-2"]
N3["重新执行任务"]
N0 --> N1
N1 --> N2
N2 --> N3
OnFailure
restartPolicy: OnFailure容器失败后,Kubelet 会尝试在当前 Pod 内重启容器。
flowchart TB
N0["Pod-1"]
N1["Container 失败"]
N2["Kubelet 重启 Container"]
N3["继续执行任务"]
N0 --> N1
N1 --> N2
N2 --> N3
两者对比:
| 对比 | Never | OnFailure |
|---|---|---|
| 容器失败 | 不在原 Pod 内重启 | 在原 Pod 内重启 |
| 重新执行任务 | 通常创建新 Pod | 通常复用原 Pod |
| Pod 数量 | 可能增加 | 通常不增加 |
| 日志排查 | 每次尝试可独立查看 | 需要关注容器重启日志 |
注意:OnFailure 模式下,容器重启也会受到 Job 失败处理机制的约束;不要把 backoffLimit 简单理解成容器内部重启次数。
五、Job 运行时间控制(activeDeadlineSeconds)
有些任务不能无限运行。
例如:
一个数据迁移任务,正常情况下 5 分钟就应该完成。
如果运行了 2 个小时还没有结束,可能已经发生死锁或异常。
这时可以使用:
activeDeadlineSeconds: 300表示 Job 最长活动时间为 300 秒。
示例:
apiVersion: batch/v1kind: Job
metadata: name: timeout-job
spec: activeDeadlineSeconds: 300
template: spec: containers: - name: task image: busybox:1.36 command: - sh - -c - "sleep 600"
restartPolicy: Never这个任务需要运行 600 秒,但 Job 最多允许运行 300 秒。
因此,达到时间限制后,Job 会被标记为失败,并终止其活动 Pod。
注意:
activeDeadlineSeconds 优先于 backoffLimit。即使还没有达到失败次数限制,超过 Job 的活动时间限制也会终止任务。
六、Job 自动清理(ttlSecondsAfterFinished)
Job 完成后,默认不会立即删除。
这有什么问题?
假设每天执行 1000 个 Job:
job-001job-002job-003...job-1000如果一直不清理,集群中就会积累大量历史 Job 和 Pod。
可以使用 TTL 自动清理。
1. ttlSecondsAfterFinished
示例:
spec: ttlSecondsAfterFinished: 60表示:
Job 完成或失败后,等待约 60 秒,然后由 TTL 控制器尝试清理 Job 及其依赖的 Pod。
完整示例:
apiVersion: batch/v1kind: Job
metadata: name: cleanup-job
spec: ttlSecondsAfterFinished: 60
template: spec: containers: - name: task image: busybox:1.36 command: - sh - -c - "echo task completed"
restartPolicy: Never常用配置:
| 配置 | 含义 |
|---|---|
| 不配置 | 不设置 TTL 自动清理 |
0 | 完成后尽快清理 |
60 | 完成 60 秒后清理 |
3600 | 完成 1 小时后清理 |
注意:TTL 控制器会异步执行清理,不保证精确到秒。
生产环境建议:不要为了节省资源就将所有 Job 设置为立即删除。 应保留必要的任务状态和日志,以便排查问题。
七、Job 高级任务模式
前面学习的是普通 Job。
实际上 Kubernetes Job 还支持不同的任务执行模式。
1. Non-parallel Job(非并行任务)
最简单的模式。
spec: completions: 1 parallelism: 1表示只需要成功完成一次任务。
例如:
flowchart TB
N0["备份数据库"]
N1["生成备份文件"]
N2["任务结束"]
N0 --> N1
N1 --> N2
这是 Job 最常见的使用方式之一。
2. Parallel Job(并行任务)
多个 Pod 同时执行任务。
spec: completions: 10 parallelism: 3表示:
- 需要成功完成 10 个任务。
- 最多允许 3 个任务同时执行。
适用于:
- 批量数据计算。
- 文件处理。
- 图片转换。
- 分布式数据处理。
3. Work Queue Job(工作队列任务)
这种模式与普通固定完成次数的 Job 不同。
它通常使用共享任务队列,由多个 Worker Pod 不断获取任务并执行。
例如:
flowchart TB
N0["Job"]
N1["Worker1"]
N2["Worker2"]
N3["Worker3"]
N4["Redis Queue"]
N5["待处理任务"]
N0 --> N1
N0 --> N2
N0 --> N3
N1 --> N4
N2 --> N4
N3 --> N4
N4 --> N5
这时通常:
spec: parallelism: 3而不设置固定的 completions。
Worker 通过外部任务队列判断是否还有工作。
任务队列为空后,Worker 需要根据应用自身的退出逻辑正常结束。
这种模式适合持续有任务进入、由多个 Worker 协作处理的场景。
4. Indexed Job(索引任务)
这是 Job 比较重要的高级功能。
假设需要并行处理 5 份数据:
数据集 0数据集 1数据集 2数据集 3数据集 4如果每个 Pod 都需要知道自己负责处理哪一份数据,可以使用 Indexed Job。
配置:
apiVersion: batch/v1kind: Job
metadata: name: indexed-job
spec: completions: 5 parallelism: 2
completionMode: Indexed
template: spec: containers: - name: worker image: busybox:1.36 command: - sh - -c - "echo Processing index: $JOB_COMPLETION_INDEX"
restartPolicy: NeverKubernetes 会为每个任务分配一个索引:
Pod-1:JOB_COMPLETION_INDEX=0Pod-2:JOB_COMPLETION_INDEX=1Pod-3:JOB_COMPLETION_INDEX=2Pod-4:JOB_COMPLETION_INDEX=3Pod-5:JOB_COMPLETION_INDEX=4这样每个 Pod 就可以根据自己的索引处理不同的数据。
例如:
case "$JOB_COMPLETION_INDEX" in 0) process data-0 ;; 1) process data-1 ;; 2) process data-2 ;; 3) process data-3 ;; 4) process data-4 ;;esac实际业务中可以把索引传递给 Python、Go 或 Java 程序。
八、Job 暂停与恢复
Kubernetes Job 还支持暂停执行。
例如:
某个批处理任务需要等待外部数据准备完成,暂时不希望继续创建任务 Pod。
可以使用:
spec: suspend: true表示暂停 Job。
恢复:
spec: suspend: false也可以通过命令:
kubectl patch job batch-job \ -p '{"spec":{"suspend":true}}'恢复:
kubectl patch job batch-job \ -p '{"spec":{"suspend":false}}'暂停和恢复的过程:
flowchart TB
N0["Job 正在执行"]
N1["suspend: true"]
N2["暂停任务"]
N3["suspend: false"]
N4["继续执行"]
N0 --> N1
N1 --> N2
N2 --> N3
N3 --> N4
注意:暂停一个正在运行的 Job 时,其活动 Pod 会被终止;恢复后 Job Controller 会根据任务完成状态继续协调。因此不要把暂停理解为简单冻结容器进程。
九、Job 的 Pod 失败策略
除了普通的失败重试,Kubernetes 还支持更精细的 Pod 失败处理机制。
例如:
一个 Job 有 10 个任务 Pod。
其中:
- 部分 Pod 因节点故障失败。
- 部分 Pod 因应用参数错误失败。
- 部分 Pod 因资源不足失败。
我们可能希望:
- 节点故障时允许重试。
- 应用参数错误时直接终止整个 Job。
在支持该功能的 Kubernetes 版本中,可以使用 podFailurePolicy。
示例:
apiVersion: batch/v1kind: Job
metadata: name: failure-policy-job
spec: backoffLimit: 3
podFailurePolicy: rules: - action: FailJob onExitCodes: containerName: worker operator: In values: - 42
- action: Ignore onPodConditions: - type: DisruptionTarget
template: spec: containers: - name: worker image: busybox:1.36 command: - sh - -c - "exit 42"
restartPolicy: Never这里:
| 配置 | 作用 |
|---|---|
| FailJob | 直接将 Job 判定为失败 |
| Ignore | 不将匹配的 Pod 失败计入普通重试次数 |
| Count | 按照普通失败进行计数 |
注意:
podFailurePolicy需要restartPolicy: Never。FailJob适合处理明确不可恢复的错误。Ignore适合处理某些可忽略的中断。podFailurePolicy是进阶功能,CKA 初期重点掌握 backoffLimit 即可。
十、Job 故障排查
生产环境中,Job 最常见的问题就是任务无法完成。
1. Job 一直没有完成
例如:
NAME COMPLETIONSbatch-job 0/5排查:
kubectl get pods -l job-name=batch-job查看 Pod:
kubectl describe pod <pod-name>查看日志:
kubectl logs <pod-name>可能原因:
- 容器一直运行。
- 脚本没有正常退出。
- 数据库连接失败。
- 程序出现死循环。
- 外部依赖服务异常。
2. Job 一直重试失败
例如:
NAME COMPLETIONS FAILEDbatch-job 0/1 3检查:
kubectl describe job batch-job查看日志:
kubectl logs <pod-name>重点关注:
- Exit Code。
- Reason。
- Restart Count。
- Events。
- backoffLimit。
3. Job 无法创建 Pod
检查:
kubectl describe job batch-job可能原因:
- ResourceQuota 限制。
- 节点资源不足。
- Pod 模板配置错误。
- ServiceAccount 不存在。
- 镜像拉取失败。
4. 常用排查流程
flowchart TB
N0["kubectl get jobs"]
N1["查看任务完成状态"]
N2["kubectl get pods"]
N3["查看 Pod 状态"]
N4["kubectl describe pod"]
N5["kubectl logs"]
N6["定位具体错误"]
N0 --> N1
N1 --> N2
N2 --> N3
N3 --> N4
N4 --> N5
N5 --> N6
十一、Job 必须掌握的命令
| 操作 | 命令 |
|---|---|
| 查看 Job | kubectl get jobs |
| 查看所有命名空间 Job | kubectl get jobs -A |
| 查看详细信息 | kubectl describe job batch-job |
| 创建 Job | kubectl apply -f job.yaml |
| 查看 Job Pod | kubectl get pods -l job-name=batch-job |
| 查看任务日志 | kubectl logs job/batch-job |
| 删除 Job | kubectl delete job batch-job |
| 查看 YAML | kubectl get job batch-job -o yaml |
| 暂停 Job | kubectl patch job batch-job -p '{"spec":{"suspend":true}}' |
| 恢复 Job | kubectl patch job batch-job -p '{"spec":{"suspend":false}}' |
十二、Job 核心知识总结
Job 知识体系
Job Controller 确保任务成功完成
任务数量
completions
并行数量
parallelism
失败重试
backoffLimit
超时控制
activeDeadlineSeconds
自动清理
ttlSecondsAfterFinished
任务索引
completionMode: Indexed