Job 控制器会持续监控任务状态,如果 Pod 执行失败,它会自动重试或重新创建 Pod,直到达到你设定的“成功 Pod 数量”目标为止。
1. 什么是“批处理任务”?
与 Web 服务(如 Deployment)需要 24 小时持续运行不同,批处理任务(如数据库迁移、数据备份、视频渲染等)是“一次性”的,它们有明确的开始和结束。Job 就是专门用来管理这类任务的资源对象。
2. 什么是“一个或多个成功”?
Job 的成功标准是由 YAML 配置文件中的 .spec.completions 参数决定的:
- 默认情况(1个成功):如果你不设置该参数,Job 只需要创建 1 个 Pod,只要这 1 个 Pod 成功执行完毕(退出码为 0),整个 Job 就宣告成功。
- 多个成功:如果你需要处理一批数据,可以设置
completions: 5。这意味着 Job 必须确保有 5 个 Pod 成功完成任务,整个 Job 才会结束。
3. “保障...为止”是如何实现的?
这就是 Job 控制器的核心容错机制。在任务执行过程中,如果 Pod 因为节点故障或代码报错而意外终止,Job 控制器不会放任不管,而是会根据你配置的重启策略(restartPolicy)和重试上限(backoffLimit)来自动创建新的 Pod 继续执行任务,直到满足上述的“成功数量”目标。
这句话描述的是 Job 的“死磕”精神:它负责创建 Pod 并跟踪进度,无论中间遇到多少次失败,它都会不断重试,直到凑齐你要求的那几个“成功名额”才算真正完成使命
. 设置重试上限(backoffLimit)
backoffLimit 决定了 Job 在彻底放弃之前,最多允许失败多少次(默认值为 6 次)。
- 一旦失败的 Pod 数量达到了这个上限,Job 控制器就会停止创建新的 Pod,并将整个 Job 标记为
Failed 状态。
- 这就相当于告诉系统:“如果重试了这么多次还不行,说明大概率是代码或配置有严重问题,别再白费力气了,赶紧报错让人类来介入排查吧。”
2. 指数退避延迟(Exponential Backoff)
为了避免代码一报错就瞬间疯狂重建 Pod 导致集群“雪崩”,Job 在重试时会采用“等越来越久”的策略。
- 例如:第 1 次失败后等 10 秒,第 2 次等 20 秒,第 3 次等 40 秒,以此类推(最大等待时间通常为 6 分钟)。
- 这种机制给了系统喘息的时间,也避免了在持续故障时产生海量的无用日志
根据你在 YAML 中配置的 restartPolicy,Job 处理失败的方式也有所不同:
- 如果配置为
Never:容器一旦失败,Pod 直接变为 Error 状态,Job 控制器会创建一个全新的 Pod 来重试,每一次重试都会消耗 backoffLimit 的额度。
- 如果配置为
OnFailure:容器失败后,kubelet 会在同一个 Pod 内重启容器。只有当这个 Pod 彻底崩溃变成 Error 状态时,才会触发 Job 级别的重试并计入 backoffLimit。
Deployment 追求的是“数量达标”,而 Job 追求的是“任务完成”。
1. 终极目标不同:持久运行 vs 一次性完成
- Deployment(持久性控制器):它的目标是维持你期望的 Pod 数量。比如你设置
replicas: 3,它就希望这 3 个 Pod 24小时不间断地运行下去(比如 Web 服务)。只要数量不够,它就会不断拉起新 Pod。
- Job(一次性控制器):它的目标是“凑齐成功名额”。比如你设置
completions: 5,当 5 个 Pod 都成功执行完任务并退出后,Job 就彻底结束了,它绝对不会为了维持数量再去创建新的 Pod。
2. 对“代码报错”的处理逻辑不同(核心区别)
- Deployment 遇到代码报错:如果代码有 Bug 导致容器崩溃,Deployment 会陷入“无限重启的死循环”。它会不断地拉起新 Pod,新 Pod 启动后继续崩溃,然后再拉起……因为它必须保证 3 个 Pod 存活。
- Job 遇到代码报错:Job 不会无限重启。它只认
backoffLimit(重试上限)。如果因为代码 Bug 导致失败次数达到了上限(比如默认的 6 次),Job 会果断“认输”,将整个 Job 标记为 Failed 状态并停止所有动作,把问题抛给人类去修代码。
3. 重启策略(restartPolicy)的限制不同
- Deployment:通常使用
restartPolicy: Always。因为服务需要一直活着,容器一挂就必须立刻重启。
- Job:严格禁止使用
Always。它只支持 Never 或 OnFailure。因为批处理任务执行完就应该退出,不需要像 Web 服务那样永远保持运行状态。
1. Deployment 看重“过程”(维持状态)
Deployment 就像是一个“保安队长”或者“餐厅服务员”。
- 核心诉求:只要你在岗(Pod 存活),我就满意了。
- 过程导向:它根本不在乎你在这个岗位上具体干了什么,也不在乎你一天内重启(换人)了多少次。它唯一在乎的就是“当前时刻,活着的人是不是够数”。只要状态维持住了,它的任务就一直在继续。
2. Job 看重“结果”(达成目标)
Job 就像是一个“包工头”或者“外卖骑手”。
- 核心诉求:我不关心你中间经历了什么,我只看最后有没有把砖搬完、有没有把外卖送到(Pod 成功退出)。
- 结果导向:它不在乎你中间是不是因为下雨摔了一跤(临时故障),只要最后能爬起来继续干就行。但如果你彻底干不了(触发
backoffLimit),它就不管你了,直接宣布任务失败。一旦目标达成(completions 满足),哪怕你只干了 1 秒钟,它也立刻宣布收工,绝不多留你一秒钟。