登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  科技周边 >  业界新闻

Kubernetes v1.37 PodFailurePolicy 如何核对失败分类

来源:17golang原创

时间:2026-09-14 11:25:25 249浏览 收藏

在 Kubernetes v1.37 集群里,Job 失败不一定都应该继续重试:应用明确返回的缺陷码、节点扰动和普通执行失败,处理策略可能完全不同。核对 PodFailurePolicy 时,先看规则是否命中,再看 Job 状态,而不是只盯着 backoffLimit。要注意,PodFailurePolicy 不是 v1.37 才新增的能力,它从 v1.31 起已经稳定;v1.37 只是本文选定的运行环境。

官方文档:https://kubernetes.io/docs/tasks/job/pod-failure-policy/

要点速览
  • 策略规则按顺序匹配,首个命中的规则决定 FailJobIgnoreCountFailIndex
  • 使用 podFailurePolicy 时,Job 模板的 restartPolicy 必须为 Never;未命中的失败继续按默认重试逻辑处理。
  • FailureTarget 表示控制器已经触发失败终止,Failed 是所有相关 Pod 处理完后的终态条件。

先把 v1.37 的失败分类边界画清楚

一份可核对的 Job 配置,至少要让输入和结果一一对应。下面的示例把退出码 42 视为不可重试的应用缺陷,把 DisruptionTarget 视为节点或平台扰动;其他失败不匹配这两条规则时,仍然交给默认的 backoffLimit 计数。

apiVersion: batch/v1
kind: Job
metadata:
  name: failure-classification-demo
spec:
  backoffLimit: 3
  template:
    spec:
      restartPolicy: Never # 使用 PodFailurePolicy 时必须固定为 Never
      containers:
        - name: worker
          image: bash:5
          command: ["bash", "-c"]
          args: ["echo simulated failure; exit 42"] # 42 进入 FailJob 规则
  podFailurePolicy:
    rules:
      - action: FailJob # 应用明确返回缺陷码时立即结束 Job
        onExitCodes:
          containerName: worker
          operator: In
          values: [42]
      - action: Ignore # 受扰动的 Pod 不增加 backoffLimit 计数
        onPodConditions:
          - type: DisruptionTarget

规则顺序很重要:控制器只处理第一个匹配项。FailJob 会把 Job 标记为失败并终止仍在运行的 Pod;Ignore 不增加失败计数并创建替代 Pod;Count 使用默认处理方式并增加 backoffLimit 计数;FailIndex 只适用于配置了按索引重试的 Indexed Job。

输入现象匹配条件应核对的结果
容器以 42 退出onExitCodes立即进入 Job 失败终止流程
Pod 带 DisruptionTargetonPodConditions不增加重试计数,重新创建 Pod
其他失败没有规则命中按默认方式计入 backoffLimit
Kubernetes v1.37 Job PodFailurePolicy 从失败 Pod 到 FailJob Ignore Count 和 FailIndex 的规则匹配关系示意图
图1:PodFailurePolicy 规则匹配示意图;同一个失败只沿着首个匹配规则进入对应 action。

用 Job 状态确认控制器到底判成了什么

只看 Pod 的 phase: Failed 还不够。先看 Job 的条件和计数,再回到具体 Pod 的退出码、条件与日志,才能确认是策略命中,还是普通重试耗尽。核对命令可以保持短而固定:

# 先确认 API Server 的版本,再确认目标 Job 的策略字段
kubectl version
kubectl get job failure-classification-demo -o yaml

# 抽取 Job 条件,比较 FailureTarget 与最终 Failed 的 reason/message
kubectl get job failure-classification-demo -o jsonpath='{range .status.conditions[*]}{.type}{"\t"}{.reason}{"\t"}{.message}{"\n"}{end}'

# 对照 Pod 的阶段、退出码和扰动条件,定位究竟是哪条规则可匹配
kubectl get pods -l job-name=failure-classification-demo -o yaml

如果 FailJob 命中,通常先看到 FailureTarget,其 reason 会指向 PodFailurePolicy;控制器开始终止仍处于 Pending 或 Running 的 Pod,待相关 Pod 终止后再写入 Failed。因此,核对过程中短暂看到“已触发失败但终态还没出现”并不矛盾。

如果命中 Ignore,重点看 status.failed 是否没有因为这次扰动增加,并确认是否出现替代 Pod。没有匹配到任何规则时,不能把“没有 FailureTarget”当成策略失效:它可能只是走了默认的 Count 路径,最终在 backoffLimit 达到后才失败。

Kubernetes Job 用 kubectl 核对 FailureTarget Failed status.failed 和 backoffLimit 的状态关系示意图
图2:Job 状态核对示意图;FailureTarget 表示终止已触发,Failed 表示终态条件已写入。

这几个边界最容易把分类看错

  1. 把规则顺序当成并行判断。一条失败不会同时执行多个 action,先把更具体的退出码规则放在前面,再放通用的 Pod 条件规则。
  2. 把终止中的 Pod 当成最终失败。配置策略后,控制器会关注 Pod 是否已经进入终态;删除时间戳出现,不代表策略已经完成分类。
  3. status.failed 推断所有失败。Ignore 不增加该计数,FailJob 也可能先出现 FailureTarget,再出现最终 Failed,必须连同 conditions 一起看。
  4. 把 v1.37 发布说明当成字段定义。版本页用于确认集群所处发布线,字段、action 和条件语义仍应以 Job API 与任务文档为准。

生产排查时,我会把“输入证据—规则索引—Job 条件—重试计数”放在同一条记录里。这样即使 Pod 已被替换,也能从 Job 的 message 和保留的 Pod 日志回溯最初的失败分类。

常见问题

PodFailurePolicy 能和 restartPolicy: OnFailure 一起用吗?

不能。Job 模板使用 PodFailurePolicy 时,restartPolicy 必须为 Never;容器内重启会改变失败计数的观察方式。

为什么规则都没有命中,却还是创建了新 Pod?

未命中时会走默认处理,通常表现为失败计入 backoffLimit 并按 Job 的重试逻辑创建替代 Pod。应检查退出码、Pod 条件和容器名称是否与规则完全一致。

FailureTarget 出现后为什么还看不到 Failed?

FailureTarget 是终止流程的触发信号;Job 控制器还要等待相关 Pod 终止,之后才写入最终的 Failed 条件。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>