本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。

Kubernetes 1.31: Job 的 Pod 故障策略进入 GA 阶段

这篇博文介绍了 **Pod 故障策略**,该策略在 Kubernetes 1.31 中升级为稳定版,以及如何在你的 Job 中使用它。

关于 Pod 故障策略

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

为了允许这些瞬态故障,Kubernetes Job 包含 `backoffLimit` 字段,该字段允许你指定在 Job 执行期间愿意容忍的 Pod 故障次数。但是,如果你为 `backoffLimit` 字段设置一个大值,并且仅依赖此字段,你可能会注意到操作成本不必要地增加,因为 Pod 会过度重启,直到达到 `backoffLimit` 为止。

当运行具有数千个长时间运行的 Pods 的大规模 Job 跨数千个节点时,这变得尤为棘手。

Pod 故障策略通过以下方式扩展了退避限制机制,帮助你降低成本:

  • 一旦发生不可重试的 Pod 故障,即可控制 Job 失败。
  • 允许你忽略可重试错误,而无需增加 `backoffLimit` 字段。

例如,你可以使用 Pod 故障策略,通过忽略优雅节点关机导致的 Pod 故障,在更经济的 Spot 虚拟机上运行你的工作负载。

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

工作原理

你在 Job 规范中指定 Pod 故障策略,表示为规则列表。

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

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

此外,对于每个规则,你指定以下操作之一,以便在 Pod 匹配规则时执行:

  • Ignore:不将故障计入 `backoffLimit` 或 `backoffLimitPerIndex`。
  • FailJob:使整个 Job 失败并终止所有正在运行的 Pod。
  • FailIndex:使与失败 Pod 对应的索引失败。此操作与每个索引的退避限制功能配合使用。
  • Count:将故障计入 `backoffLimit` 或 `backoffLimitPerIndex`。这是默认行为。

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

请注意,在指定 Pod 故障策略时,你还必须将 Job 的 Pod 模板设置为 `restartPolicy: Never`。这可以防止 kubelet 和 Job 控制器在计算 Pod 故障时出现竞争条件。

Kubernetes 启动的 Pod 中断

为了允许将 Pod 故障策略规则与 Kubernetes 启动的中断导致的故障进行匹配,此功能引入了 `DisruptionTarget` Pod 条件。

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

在所有其他中断场景中,例如因超出 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`,则计入 `backoffLimitPerIndex`)。

了解更多

基于 Pod 故障策略引入的概念,以下额外工作正在进行中:

参与其中

这项工作由批处理工作组赞助,并与 SIG AppsSIG NodeSIG Scheduling 社区密切合作。

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

致谢

我要感谢这些年来参与这个项目的每一个人——这是一个漫长的旅程,也是一项共同的社区努力!下面的列表是我尽力回忆和表彰那些做出贡献的人。谢谢大家!