本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。
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` 条件包含以下与这些中断场景对应的原因之一:
PreemptionByKubeScheduler
:`kube-scheduler` 为了容纳更高优先级的 Pod 而抢占。DeletionByTaintManager
- Pod 将因 `kube-controller-manager` 删除,因为 Pod 不容忍 `NoExecute` 污点。EvictionByEvictionAPI
- Pod 将因API 启动的驱逐而被删除。DeletionByPodGC
- Pod 绑定到一个不再存在的节点,并将因Pod 垃圾回收而被删除。TerminationByKubelet
- Pod 因优雅节点关机、节点压力驱逐或系统关键 Pods 的抢占而终止。
在所有其他中断场景中,例如因超出 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 故障策略的实践指南,请参阅使用 Pod 故障策略处理可重试和不可重试的 Pod 故障
- 阅读有关Pod 故障策略和每个索引的退避限制的文档
- 阅读有关Pod 中断条件的文档
- 阅读Pod 故障策略的 KEP
相关工作
基于 Pod 故障策略引入的概念,以下额外工作正在进行中:
- JobSet 集成:可配置的故障策略 API
- Pod 故障策略扩展,以添加更精细的故障原因
- 通过 JobSet 在Kubeflow Training v2 中支持 Pod 故障策略
- 提案:应从端点中移除中断的 Pod
参与其中
这项工作由批处理工作组赞助,并与 SIG Apps、SIG Node 和 SIG Scheduling 社区密切合作。
如果你有兴趣在该领域开发新功能,我们建议你订阅我们的 Slack 频道并参加定期的社区会议。
致谢
我要感谢这些年来参与这个项目的每一个人——这是一个漫长的旅程,也是一项共同的社区努力!下面的列表是我尽力回忆和表彰那些做出贡献的人。谢谢大家!
- Aldo Culquicondor 在整个过程中给予指导和评论
- Jordan Liggitt 进行 KEP 和 API 审查
- David Eads 进行 API 审查
- Maciej Szulik 从 SIG Apps 角度进行 KEP 审查
- Clayton Coleman 提供指导和 SIG Node 审查
- Sergey Kanzhelev 从 SIG Node 角度进行 KEP 审查
- Dawn Chen 从 SIG Node 角度进行 KEP 审查
- Daniel Smith 从 SIG API 机制角度进行审查
- Antoine Pelisse 从 SIG API 机制角度进行审查
- John Belamaric 进行 PRR 审查
- Filip Křepinský 从 SIG Apps 角度进行全面审查和错误修复
- David Porter 从 SIG Node 角度进行全面审查
- Jensen Lo 参与早期需求讨论、测试和问题报告
- Daniel Vega-Myhre 推动 JobSet 集成和问题报告
- Abdullah Gharaibeh 参与早期设计讨论和指导
- Antonio Ojea 进行测试审查
- Yuki Iwai 进行审查并协调相关 Job 功能的实现
- Kevin Hannon 进行审查并协调相关 Job 功能的实现
- Tim Bannister 进行文档审查
- Shannon Kularathna 进行文档审查
- Paola Cortés 进行文档审查