Kubernetes 1.31:Job 的 Pod 失败策略正式发布

本文介绍了 Pod 失败策略,该策略在 Kubernetes 1.31 中升级为稳定版,以及如何在您的 Jobs 中使用它。

关于 Pod 失败策略

当您在 Kubernetes 上运行工作负载时,Pod 可能会因各种原因而失败。理想情况下,像 Jobs 这样的工作负载应该能够忽略瞬态、可重试的故障,并继续运行直到完成。

为了允许这些瞬态故障,Kubernetes Jobs 包括 backoffLimit 字段,该字段允许您指定在 Job 执行期间您愿意容忍的 Pod 失败次数。但是,如果您为 backoffLimit 字段设置一个较大的值,并且仅依赖此字段,您可能会注意到由于 Pod 过度重启直到满足 backoffLimit 而导致运营成本不必要的增加。

当运行跨越数千个节点的数千个长时间运行的 Pod 的大规模 Jobs 时,这会变得特别麻烦。

Pod 失败策略扩展了回退限制机制,以帮助您通过以下方式降低成本

  • 使您能够在发生不可重试的 Pod 失败时立即控制失败 Job。
  • 允许您忽略可重试的错误,而无需增加 backoffLimit 字段。

例如,您可以使用 Pod 失败策略,通过忽略由 优雅节点关闭 导致的 Pod 失败,在更经济实惠的现货机器上运行您的工作负载。

该策略允许您根据容器退出代码或失败 Pod 中的 Pod 条件来区分可重试和不可重试的 Pod 失败。

它是如何工作的

您在 Job 规范中指定 Pod 失败策略,表示为规则列表。

对于每个规则,您根据以下属性之一定义匹配要求

  • 容器退出代码:onExitCodes 属性。
  • Pod 条件:onPodConditions 属性。

此外,对于每个规则,您指定当 Pod 匹配规则时要采取的以下操作之一

  • Ignore:不将失败计入 backoffLimitbackoffLimitPerIndex
  • FailJob:使整个 Job 失败并终止所有正在运行的 Pod。
  • FailIndex:使与失败 Pod 对应的索引失败。此操作与 每个索引的回退限制 功能一起使用。
  • Count:将失败计入 backoffLimitbackoffLimitPerIndex。这是默认行为。

当运行中的 Job 中发生 Pod 失败时,Kubernetes 会按照指定的顺序将失败 Pod 的状态与 Pod 失败策略规则列表进行匹配,并为第一个匹配的规则采取相应的操作。

请注意,在指定 Pod 失败策略时,您还必须将 Job 的 Pod 模板设置为 restartPolicy: Never。这可以防止 kubelet 和 Job 控制器在计算 Pod 失败次数时发生竞争条件。

Kubernetes 发起的 Pod 中断

为了允许将 Pod 失败策略规则与由 Kubernetes 发起的中断引起的失败进行匹配,此功能引入了 DisruptionTarget Pod 条件。

Kubernetes 将此条件添加到任何 Pod,无论它是否由 Job 控制器管理,该 Pod 由于可重试的 中断场景 而失败。DisruptionTarget 条件包含与这些中断场景相对应的以下原因之一

  • PreemptionByKubeScheduler:由 kube-scheduler 进行抢占,以容纳具有更高优先级的新 Pod。
  • DeletionByTaintManager - 由于 Pod 不容忍的 NoExecute 污点,Pod 将被 kube-controller-manager 删除。
  • EvictionByEvictionAPI - Pod 将被 API 发起的中断删除。
  • DeletionByPodGC - Pod 绑定到的节点已不存在,并将被 Pod 垃圾回收删除。
  • TerminationByKubelet - Pod 由于 优雅节点关闭节点压力驱逐或为 系统关键 Pod 进行的抢占而被终止。

在所有其他中断场景中,例如由于超出 Pod 容器限制 而导致的驱逐,Pod 不会接收 DisruptionTarget 条件,因为中断很可能是由 Pod 引起的,并且会在重试时重新发生。

示例

下面的 Pod 失败策略代码片段演示了一个使用示例

podFailurePolicy:
  rules:
  - action: Ignore
    onPodConditions:
    - type: DisruptionTarget
  - action: FailJob
    onPodConditions:
    - type: ConfigIssue
  - action: FailJob
    onExitCodes:
      operator: In
      values: [ 42 ]

在此示例中,Pod 失败策略执行以下操作

  • 忽略任何具有内置 DisruptionTarget 条件的失败 Pod。这些 Pod 不计入 Job 回退限制。
  • 如果任何失败的 Pod 具有自定义用户提供的 ConfigIssue 条件(由自定义控制器或 webhook 添加),则 Job 失败。
  • 如果任何容器以退出代码 42 退出,则 Job 失败。
  • 将所有其他 Pod 失败计入默认的 backoffLimit(如果使用,则计入 backoffLimitPerIndex)。

了解更多

基于 Pod 失败策略引入的概念,以下附加工作正在进行中

参与其中

这项工作由 批量工作组SIG AppsSIG NodeSIG Scheduling 社区的密切合作下赞助完成。

如果您有兴趣研究该领域的新功能,我们建议您订阅我们的 Slack 频道并参加定期社区会议。

致谢

我要感谢多年来参与此项目的所有人 - 这是一段旅程,也是社区共同努力的结果!下面的列表是我尽力尝试记住并认可做出贡献的人。谢谢你们!