跳到正文
复制成功
请遵守本站许可
报告
章节_文章 // 现场报告

文章编号: RL-JOB批处理任务

2026.08.20

Job:批处理任务、重试与清理

Chavy
Chavy
#Kubernetes#Job#批处理
档案

摘要:使用 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 中用于管理一次性任务的工作负载控制器。

它负责:

  1. 创建执行任务的 Pod。
  2. 监控任务执行状态。
  3. 任务失败时根据策略重试。
  4. 统计成功完成的任务数量。
  5. 达到目标后将 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 必须掌握的知识点。

对比DeploymentJob
主要用途长期运行服务一次性任务
运行目标持续提供服务成功完成任务
容器退出通常重启根据任务结果判断
生命周期长期通常短期
典型应用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#

创建文件:

PRTCL // BASH
Terminal window
vim job.yaml

编写:

PRTCL // YAML
apiVersion: batch/v1
kind: Job
metadata:
name: hello-job
spec:
template:
spec:
containers:
- name: hello
image: busybox:1.36
command:
- sh
- -c
- "echo Hello Kubernetes Job"
restartPolicy: Never

这里注意:

PRTCL // YAML
restartPolicy: Never

Job 的 Pod 模板只允许使用:

  • Never
  • OnFailure

不允许使用 Always。

为什么?

因为 Job 是一次性任务,不能像 Deployment 一样无限期维持容器运行。

2. 创建 Job#

PRTCL // BASH
Terminal window
kubectl apply -f job.yaml

查看:

PRTCL // BASH
Terminal window
kubectl get jobs

输出示例:

PRTCL // TEXT
NAME COMPLETIONS DURATION AGE
hello-job 1/1 3s 10s

其中:

字段含义
COMPLETIONS成功完成的任务数
DURATION任务执行时间
AGEJob 创建时间

查看 Pod:

PRTCL // BASH
Terminal window
kubectl get pods

可能看到:

PRTCL // TEXT
NAME READY STATUS
hello-job-abc12 0/1 Completed

查看日志:

PRTCL // BASH
Terminal window
kubectl logs hello-job-abc12

输出:

PRTCL // TEXT
Hello Kubernetes Job

注意:Job 成功完成后,Pod 默认不会立即删除,以便查看任务日志和排查问题。


三、Job 的核心参数#

Job 有几个非常重要的字段:

参数作用
completions需要成功完成多少个任务
parallelism最多允许多少个任务并行运行
backoffLimit允许的失败重试次数
activeDeadlineSecondsJob 最大运行时间
ttlSecondsAfterFinished完成后多久自动清理 Job

这些是 CKA 的重点。

1. completions:任务完成次数#

假设:

PRTCL // YAML
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:并行执行数量#

假设:

PRTCL // YAML
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 综合示例#

PRTCL // YAML
apiVersion: batch/v1
kind: 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

含义:

PRTCL // TEXT
总任务数量:10
最大并行数量:3
每个任务执行时间:约 10 秒

如果集群资源充足,任务大致分为四批执行:

PRTCL // TEXT
第一批:3 个
第二批:3 个
第三批:3 个
第四批:1 个

四、Job 失败重试机制(backoffLimit)#

实际生产环境中,任务不一定每次都能成功。

例如:

  • 数据库暂时无法连接。
  • 网络请求超时。
  • 外部服务暂时不可用。
  • 执行脚本发生异常。

Job 需要具备失败重试能力。

1. backoffLimit 是什么?#

backoffLimit 表示 Job 允许的失败次数上限。

例如:

PRTCL // YAML
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#

PRTCL // YAML
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#

PRTCL // YAML
restartPolicy: OnFailure

容器失败后,Kubelet 会尝试在当前 Pod 内重启容器。

flowchart TB
    N0["Pod-1"]
    N1["Container 失败"]
    N2["Kubelet 重启 Container"]
    N3["继续执行任务"]
    N0 --> N1
    N1 --> N2
    N2 --> N3

两者对比:

对比NeverOnFailure
容器失败不在原 Pod 内重启在原 Pod 内重启
重新执行任务通常创建新 Pod通常复用原 Pod
Pod 数量可能增加通常不增加
日志排查每次尝试可独立查看需要关注容器重启日志

注意:OnFailure 模式下,容器重启也会受到 Job 失败处理机制的约束;不要把 backoffLimit 简单理解成容器内部重启次数。


五、Job 运行时间控制(activeDeadlineSeconds)#

有些任务不能无限运行。

例如:

一个数据迁移任务,正常情况下 5 分钟就应该完成。

如果运行了 2 个小时还没有结束,可能已经发生死锁或异常。

这时可以使用:

PRTCL // YAML
activeDeadlineSeconds: 300

表示 Job 最长活动时间为 300 秒。

示例:

PRTCL // YAML
apiVersion: batch/v1
kind: 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:

PRTCL // TEXT
job-001
job-002
job-003
...
job-1000

如果一直不清理,集群中就会积累大量历史 Job 和 Pod。

可以使用 TTL 自动清理。

1. ttlSecondsAfterFinished#

示例:

PRTCL // YAML
spec:
ttlSecondsAfterFinished: 60

表示:

Job 完成或失败后,等待约 60 秒,然后由 TTL 控制器尝试清理 Job 及其依赖的 Pod。

完整示例:

PRTCL // YAML
apiVersion: batch/v1
kind: 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(非并行任务)#

最简单的模式。

PRTCL // YAML
spec:
completions: 1
parallelism: 1

表示只需要成功完成一次任务。

例如:

flowchart TB
    N0["备份数据库"]
    N1["生成备份文件"]
    N2["任务结束"]
    N0 --> N1
    N1 --> N2

这是 Job 最常见的使用方式之一。

2. Parallel Job(并行任务)#

多个 Pod 同时执行任务。

PRTCL // YAML
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

这时通常:

PRTCL // YAML
spec:
parallelism: 3

而不设置固定的 completions。

Worker 通过外部任务队列判断是否还有工作。

任务队列为空后,Worker 需要根据应用自身的退出逻辑正常结束。

这种模式适合持续有任务进入、由多个 Worker 协作处理的场景。

4. Indexed Job(索引任务)#

这是 Job 比较重要的高级功能。

假设需要并行处理 5 份数据:

PRTCL // TEXT
数据集 0
数据集 1
数据集 2
数据集 3
数据集 4

如果每个 Pod 都需要知道自己负责处理哪一份数据,可以使用 Indexed Job。

配置:

PRTCL // YAML
apiVersion: batch/v1
kind: 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: Never

Kubernetes 会为每个任务分配一个索引:

PRTCL // TEXT
Pod-1:JOB_COMPLETION_INDEX=0
Pod-2:JOB_COMPLETION_INDEX=1
Pod-3:JOB_COMPLETION_INDEX=2
Pod-4:JOB_COMPLETION_INDEX=3
Pod-5:JOB_COMPLETION_INDEX=4

这样每个 Pod 就可以根据自己的索引处理不同的数据。

例如:

PRTCL // BASH
Terminal window
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。

可以使用:

PRTCL // YAML
spec:
suspend: true

表示暂停 Job。

恢复:

PRTCL // YAML
spec:
suspend: false

也可以通过命令:

PRTCL // BASH
Terminal window
kubectl patch job batch-job \
-p '{"spec":{"suspend":true}}'

恢复:

PRTCL // BASH
Terminal window
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。

示例:

PRTCL // YAML
apiVersion: batch/v1
kind: 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 一直没有完成#

例如:

PRTCL // TEXT
NAME COMPLETIONS
batch-job 0/5

排查:

PRTCL // BASH
Terminal window
kubectl get pods -l job-name=batch-job

查看 Pod:

PRTCL // BASH
Terminal window
kubectl describe pod <pod-name>

查看日志:

PRTCL // BASH
Terminal window
kubectl logs <pod-name>

可能原因:

  • 容器一直运行。
  • 脚本没有正常退出。
  • 数据库连接失败。
  • 程序出现死循环。
  • 外部依赖服务异常。

2. Job 一直重试失败#

例如:

PRTCL // TEXT
NAME COMPLETIONS FAILED
batch-job 0/1 3

检查:

PRTCL // BASH
Terminal window
kubectl describe job batch-job

查看日志:

PRTCL // BASH
Terminal window
kubectl logs <pod-name>

重点关注:

  • Exit Code。
  • Reason。
  • Restart Count。
  • Events。
  • backoffLimit。

3. Job 无法创建 Pod#

检查:

PRTCL // BASH
Terminal window
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 必须掌握的命令#

操作命令
查看 Jobkubectl get jobs
查看所有命名空间 Jobkubectl get jobs -A
查看详细信息kubectl describe job batch-job
创建 Jobkubectl apply -f job.yaml
查看 Job Podkubectl get pods -l job-name=batch-job
查看任务日志kubectl logs job/batch-job
删除 Jobkubectl delete job batch-job
查看 YAMLkubectl get job batch-job -o yaml
暂停 Jobkubectl patch job batch-job -p '{"spec":{"suspend":true}}'
恢复 Jobkubectl patch job batch-job -p '{"spec":{"suspend":false}}'

十二、Job 核心知识总结#

Job 知识体系

Job Controller 确保任务成功完成

任务数量

completions

并行数量

parallelism

失败重试

backoffLimit

超时控制

activeDeadlineSeconds

自动清理

ttlSecondsAfterFinished

任务索引

completionMode: Indexed

归档于 2026.08.20
// 档案结束
Classified
章节_06
协议编号: CC-BY-NC-SA-4.0

Job:批处理任务、重试与清理

作者:Chavy发布日期:2026.08.20

基于 CC BY-NC-SA 4.0

© 2026 Chavy
Powered by Astro