diff --git a/content/zh-cn/docs/concepts/workloads/controllers/job.md b/content/zh-cn/docs/concepts/workloads/controllers/job.md index 38aba40602..1f11af5fc0 100644 --- a/content/zh-cn/docs/concepts/workloads/controllers/job.md +++ b/content/zh-cn/docs/concepts/workloads/controllers/job.md @@ -1081,6 +1081,165 @@ mismatch. 设置 `manualSelector: true` 是在告诉系统你知道自己在干什么并要求系统允许这种不匹配的存在。 + +### Pod 失效策略 {#pod-failure-policy} + +{{< feature-state for_k8s_version="v1.25" state="alpha" >}} + +{{< note >}} + +只有你在集群中启用了 +`JobPodFailurePolicy` [特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/) +你才能为某个 Job 配置 Pod 失效策略。 +此外,建议启用 `PodDisruptionsCondition` 特性门控以便在 Pod 失效策略中检测和处理 Pod 干扰状况 +(参考:[Pod 干扰状况](/zh-cn/docs/concepts/workloads/pods/disruptions#pod-disruption-conditions))。 +这两个特性门控都是在 Kubernetes v1.25 中提供的。 +{{< /note >}} + + +Pod 失效策略使用 `.spec.podFailurePolicy` 字段来定义, +它能让你的集群根据容器的退出码和 Pod 状况来处理 Pod 失效事件。 + + +在某些情况下,你可能希望更好地控制 Pod 失效的处理方式, +而不是仅限于 [Pod 回退失效策略](#pod-backoff-failure-policy)所提供的控制能力, +后者是基于 Job 的 `.spec.backoffLimit` 实现的。以下是一些使用场景: + +* 通过避免不必要的 Pod 重启来优化工作负载的运行成本, + 你可以在某 Job 中一个 Pod 失效且其退出码表明存在软件错误时立即终止该 Job。 +* 为了保证即使有干扰也能完成 Job,你可以忽略由干扰导致的 Pod 失效 + (例如{{< glossary_tooltip text="抢占" term_id="preemption" >}}、 + {{< glossary_tooltip text="通过 API 发起的驱逐" term_id="api-eviction" >}} + 或基于{{< glossary_tooltip text="污点" term_id="taint" >}}的驱逐), + 这样这些失效就不会被计入 `.spec.backoffLimit` 的重试限制中。 + + +你可以在 `.spec.podFailurePolicy` 字段中配置 Pod 失效策略,以满足上述使用场景。 +该策略可以根据容器退出码和 Pod 状况来处理 Pod 失效。 + + +下面是一个定义了 `podFailurePolicy` 的 Job 的清单: + +{{< codenew file="controllers/job-pod-failure-policy-example.yaml" >}} + + +在上面的示例中,Pod 失效策略的第一条规则规定如果 `main` 容器失败并且退出码为 42, +Job 将被标记为失败。以下是 `main` 容器的具体规则: + + +- 退出码 0 代表容器成功 +- 退出码 42 代表 **整个 Job** 失败 +- 所有其他退出码都代表容器失败,同时也代表着整个 Pod 失效。 + 如果重启总次数低于 `backoffLimit` 定义的次数,则会重新启动 Pod, + 如果等于 `backoffLimit` 所设置的次数,则代表 **整个 Job** 失效。 + +{{< note >}} + +因为 Pod 模板中指定了 `restartPolicy: Never`, +所以 kubelet 将不会重启 Pod 中的 `main` 容器。 +{{< /note >}} + + +Pod 失效策略的第二条规则, +指定对于状况为 `DisruptionTarget` 的失效 Pod 采取 `Ignore` 操作, +统计 `.spec.backoffLimit` 重试次数限制时不考虑 Pod 因干扰而发生的异常。 +{{< note >}} + +如果根据 Pod 失效策略或 Pod 回退失效策略判定 Pod 已经失效, +并且 Job 正在运行多个 Pod,Kubernetes 将终止该 Job 中仍处于 Pending 或 Running 的所有 Pod。 +{{< /note >}} + + +下面是此 API 的一些要求和语义: +- 如果你想在 Job 中使用 `.spec.podFailurePolicy` 字段, + 你必须将 Job 的 Pod 模板中的 `.spec.restartPolicy` 设置为 `Never`。 +- 在 `spec.podFailurePolicy.rules` 中设定的 Pod 失效策略规则将按序评估。 + 一旦某个规则与 Pod 失效策略匹配,其余规则将被忽略。 + 当没有规则匹配 Pod 失效策略时,将会采用默认的处理方式。 +- 你可能希望在 `spec.podFailurePolicy.rules[*].containerName` + 中通过指定的名称将规则限制到特定容器。 + 如果不设置,规则将适用于所有容器。 + 如果指定了容器名称,它应该匹配 Pod 模板中的一个普通容器或一个初始容器(Init Container)。 +- 你可以在 `spec.podFailurePolicy.rules[*].action` 指定当 Pod 失效策略发生匹配时要采取的操作。 + 可能的值为: + - `FailJob`:表示 Pod 的任务应标记为 Failed,并且所有正在运行的 Pod 应被终止。 + - `Ignore`:表示 `.spec.backoffLimit` 的计数器不应该增加,应该创建一个替换的 Pod。 + - `Count`:表示 Pod 应该以默认方式处理。`.spec.backoffLimit` 的计数器应该增加。 + diff --git a/content/zh-cn/examples/controllers/job-pod-failure-policy-example.yaml b/content/zh-cn/examples/controllers/job-pod-failure-policy-example.yaml new file mode 100644 index 0000000000..05e2d8c0bf --- /dev/null +++ b/content/zh-cn/examples/controllers/job-pod-failure-policy-example.yaml @@ -0,0 +1,28 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: job-pod-failure-policy-example +spec: + completions: 12 + parallelism: 3 + template: + spec: + restartPolicy: Never + containers: + - name: main + image: docker.io/library/bash:5 + command: ["bash"] # 模拟一个触发 FailJob 动作的错误的示例命令 + args: + - -c + - echo "Hello world!" && sleep 5 && exit 42 + backoffLimit: 6 + podFailurePolicy: + rules: + - action: FailJob + onExitCodes: + containerName: main # 可选 + operator: In # In 和 NotIn 二选一 + values: [42] + - action: Ignore # Ignore、FailJob、Count 其中之一 + onPodConditions: + - type: DisruptionTarget # 表示 Pod 失效