diff --git a/content/zh-cn/docs/concepts/workloads/controllers/job.md b/content/zh-cn/docs/concepts/workloads/controllers/job.md index 5bd82c565f..021b5a50dc 100644 --- a/content/zh-cn/docs/concepts/workloads/controllers/job.md +++ b/content/zh-cn/docs/concepts/workloads/controllers/job.md @@ -31,8 +31,8 @@ hide_summary: true # Listed separately in section index ## 运行示例 Job {#running-an-example-job} @@ -215,7 +215,7 @@ pi-5rwd7 ``` Job 标签将为 `job-name` 和 `controller-uid` 加上 `batch.kubernetes.io/` 前缀。 + ### Pod 模板 {#pod-template} @@ -313,13 +317,13 @@ Job 中 Pod 的 [`RestartPolicy`](/zh-cn/docs/concepts/workloads/pods/pod-lifecy ### Pod 选择算符 {#pod-selector} 字段 `.spec.selector` 是可选的。在绝大多数场合,你都不需要为其赋值。 -参阅[设置自己的 Pod 选择算符](#specifying-your-own-pod-selector). +参阅[设置自己的 Pod 选择算符](#specifying-your-own-pod-selector)。 1. 非并行 Job: - 通常只启动一个 Pod,除非该 Pod 失败。 @@ -365,8 +373,8 @@ There are three main types of task suitable to run as a Job: 所有 Pod 都应启动退出过程。 对于**非并行**的 Job,你可以不设置 `spec.completions` 和 `spec.parallelism`。 这两个属性都不设置时,均取默认值 1。 @@ -408,7 +417,7 @@ parallelism, for a variety of reasons: + --> 当每个索引都对应一个成功完成的 Pod 时,Job 被认为是已完成的。 关于如何使用这种模式的更多信息,可参阅 [用带索引的 Job 执行基于静态任务分配的并行处理](/zh-cn/docs/tasks/job/indexed-parallel-processing-static/)。 @@ -493,9 +507,9 @@ or completed for the same index will be deleted by the Job controller once they ## Handling Pod and container failures A container in a Pod may fail for a number of reasons, such as because the process in it exited with -a non-zero exit code, or the container was killed for exceeding a memory limit, etc. If this +a non-zero exit code, or the container was killed for exceeding a memory limit, etc. If this happens, and the `.spec.template.spec.restartPolicy = "OnFailure"`, then the Pod stays -on the node, but the container is re-run. Therefore, your program needs to handle the case when it is +on the node, but the container is re-run. Therefore, your program needs to handle the case when it is restarted locally, or else specify `.spec.template.spec.restartPolicy = "Never"`. See [pod lifecycle](/docs/concepts/workloads/pods/pod-lifecycle/#example-states) for more information on `restartPolicy`. --> @@ -513,9 +527,9 @@ Pod 则继续留在当前节点,但容器会被重新运行。 整个 Pod 也可能会失败,且原因各不相同。 @@ -534,13 +548,22 @@ customize handling of pod failures by setting the Job's [pod failure policy](#po 请参阅 [Pod 回退失效策略](#pod-backoff-failure-policy)。 但你可以通过设置 Job 的 [Pod 失效策略](#pod-failure-policy)自定义对 Pod 失效的处理方式。 + +此外,你可以通过设置 `.spec.backoffLimitPerIndex` 字段, +选择为 [Indexed](#completion-mode) Job 的每个索引独立计算 Pod 失败次数 +(细节参阅[逐索引的回退限制](#backoff-limit-per-index))。 + 注意,即使你将 `.spec.parallelism` 设置为 1,且将 `.spec.completions` 设置为 1,并且 `.spec.template.spec.restartPolicy` 设置为 "Never",同一程序仍然有可能被启动两次。 @@ -583,6 +606,7 @@ Pods associated with the Job are recreated by the Job controller with an exponential back-off delay (10s, 20s, 40s ...) capped at six minutes. The number of retries is calculated in two ways: + - The number of Pods with `.status.phase = "Failed"`. - When using `restartPolicy = "OnFailure"`, the number of retries in all the containers of Pods with `.status.phase` equal to `Pending` or `Running`. @@ -609,7 +633,8 @@ considered failed. {{< note >}} @@ -620,6 +645,117 @@ from failed Jobs is not lost inadvertently. 或者使用日志系统来确保失效 Job 的输出不会意外遗失。 {{< /note >}} + +### 逐索引的回退限制 {#backoff-limit-per-index} + +{{< feature-state for_k8s_version="v1.28" state="alpha" >}} + +{{< note >}} + +只有在集群中启用了 `JobBackoffLimitPerIndex` +[特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/), +才能为 [Indexed](#completion-mode) Job 配置逐索引的回退限制。 +{{< /note >}} + + +运行 [Indexed](#completion-mode) Job 时,你可以选择对每个索引独立处理 Pod 失败的重试。 +为此,可以设置 `.spec.backoffLimitPerIndex` 来指定每个索引的最大 Pod 失败次数。 + + +当某个索引超过逐索引的回退限制后,Kubernetes 将视该索引为已失败,并将其添加到 `.status.failedIndexes` 字段中。 +无论你是否设置了 `backoffLimitPerIndex` 字段,已成功执行的索引(具有成功执行的 Pod)将被记录在 +`.status.completedIndexes` 字段中。 + + +请注意,失败的索引不会中断其他索引的执行。一旦在指定了逐索引回退限制的 Job 中的所有索引完成, +如果其中至少有一个索引失败,Job 控制器会通过在状态中设置 Failed 状况将整个 Job 标记为失败。 +即使其中一些(可能几乎全部)索引已被成功处理,该 Job 也会被标记为失败。 + + +你还可以通过设置 `.spec.maxFailedIndexes` 字段来限制标记为失败的最大索引数。 +当失败的索引数量超过 `maxFailedIndexes` 字段时,Job 控制器会对该 Job +的运行中的所有余下 Pod 触发终止操作。一旦所有 Pod 被终止,Job 控制器将通过设置 Job +状态中的 Failed 状况将整个 Job 标记为失败。 + + +以下是定义 `backoffLimitPerIndex` 的 Job 示例清单: + +{{< codenew file="/controllers/job-backoff-limit-per-index-example.yaml" >}} + + +在上面的示例中,Job 控制器允许每个索引重新启动一次。 +当失败的索引总数超过 5 个时,整个 Job 将被终止。 + +Job 完成后,该 Job 的状态如下所示: + +```sh +kubectl get -o yaml job job-backoff-limit-per-index-example +``` + + +```yaml + status: + completedIndexes: 1,3,5,7,9 + failedIndexes: 0,2,4,6,8 + succeeded: 5 # 每 5 个成功的索引有 1 个成功的 Pod + failed: 10 # 每 5 个失败的索引有 2 个失败的 Pod(1 次重试) + conditions: + - message: Job has failed indexes + reason: FailedIndexes + status: "True" + type: Failed +``` + + +此外,你可能想要结合使用逐索引回退与 [Pod 失败策略](#pod-failure-policy)。 +在使用逐索引回退时,有一个新的 `FailIndex` 操作可用,它让你避免就某个索引进行不必要的重试。 + @@ -634,8 +770,8 @@ You can only configure a Pod failure policy for a Job if you have the enabled in your cluster. Additionally, it is recommended to enable the `PodDisruptionConditions` feature gate in order to be able to detect and handle Pod disruption conditions in the Pod failure policy (see also: -[Pod disruption conditions](/docs/concepts/workloads/pods/disruptions#pod-disruption-conditions)). Both feature gates are -available in Kubernetes {{< skew currentVersion >}}. +[Pod disruption conditions](/docs/concepts/workloads/pods/disruptions#pod-disruption-conditions)). +Both feature gates are available in Kubernetes {{< skew currentVersion >}}. --> 只有你在集群中启用了 `JobPodFailurePolicy` [特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/), @@ -661,12 +797,13 @@ which is based on the Job's `.spec.backoffLimit`. These are some examples of use 在某些情况下,你可能希望更好地控制 Pod 失效的处理方式, 而不是仅限于 [Pod 回退失效策略](#pod-backoff-failure-policy)所提供的控制能力, 后者是基于 Job 的 `.spec.backoffLimit` 实现的。以下是一些使用场景: + 下面是此 API 的一些要求和语义: - 如果你想在 Job 中使用 `.spec.podFailurePolicy` 字段, @@ -779,6 +919,8 @@ These are some requirements and semantics of the API: - `FailJob`:表示 Pod 的任务应标记为 Failed,并且所有正在运行的 Pod 应被终止。 - `Ignore`:表示 `.spec.backoffLimit` 的计数器不应该增加,应该创建一个替换的 Pod。 - `Count`:表示 Pod 应该以默认方式处理。`.spec.backoffLimit` 的计数器应该增加。 + - `FailIndex`:表示使用此操作以及[逐索引回退限制](#backoff-limit-per-index)来避免就失败的 Pod + 的索引进行不必要的重试。 {{< note >}} +自 Kubernetes v1.28 开始,当使用 Pod 失败策略时,Job 控制器仅在这些 Pod 达到终止的 +`Failed` 阶段时才会重新创建终止中的 Pod。这种行为类似于 `podReplacementPolicy: Failed`。 +细节参阅 [Pod 替换策略](#pod-replacement-policy)。 +{{< /note >}} + ## Job 终止与清理 {#job-termination-and-cleanup} @@ -820,13 +973,16 @@ Job 完成时 Job 对象也一样被保留下来,这样你就可以查看它 当使用 `kubectl` 来删除 Job 时,该 Job 所创建的 Pod 也会被删除。 默认情况下,Job 会持续运行,除非某个 Pod 失败(`restartPolicy=Never`) 或者某个容器出错退出(`restartPolicy=OnFailure`)。 @@ -841,7 +997,9 @@ Once a Job reaches `activeDeadlineSeconds`, all of its running Pods are terminat 并且 Job 的状态更新为 `type: Failed` 及 `reason: DeadlineExceeded`。 @@ -865,14 +1023,18 @@ spec: containers: - name: pi image: perl:5.34.0 - command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] + command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] restartPolicy: Never ``` - 注意 Job 规约和 Job 中的 [Pod 模板规约](/zh-cn/docs/concepts/workloads/pods/init-containers/#detailed-behavior) @@ -942,7 +1104,7 @@ spec: containers: - name: pi image: perl:5.34.0 - command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] + command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] restartPolicy: Never ``` @@ -993,9 +1155,9 @@ consume. @@ -1008,7 +1170,7 @@ Job 的确能够支持对一组相互独立而又有所关联的**工作条目** 数据库中要扫描的主键范围等等。 @@ -1050,7 +1212,7 @@ The pattern names are also links to examples and more detailed description. | [Queue with Variable Pod Count] | ✓ | ✓ | | | [Indexed Job with Static Work Assignment] | ✓ | | ✓ | | [Job Template Expansion] | | | ✓ | -| [Job with Pod-to-Pod Communication] | ✓ | sometimes | sometimes | +| [Job with Pod-to-Pod Communication] | ✓ | sometimes | sometimes | --> 下面是对这些权衡的汇总,第 2 到 4 列对应上面的权衡比较。 模式的名称对应了相关示例和更详细描述的链接。 @@ -1065,9 +1227,9 @@ The pattern names are also links to examples and more detailed description. -为了使用此功能,你必须在 [API 服务器](/zh-cn/docs/reference/command-line-tools-reference/kube-apiserver/)上启用 -`JobMutableNodeSchedulingDirectives` [特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/)。 -默认情况下启用。 -{{< /note >}} - - 在大多数情况下,并行作业会希望 Pod 在一定约束条件下运行, 比如所有的 Pod 都在同一个区域,或者所有的 Pod 都在 GPU 型号 x 或 y 上,而不是两者的混合。 @@ -1302,8 +1453,8 @@ suspend 允许自定义队列控制器,以决定工作何时开始;然而, 此特性允许在 Job 开始之前更新调度指令,从而为定制队列提供影响 Pod @@ -1313,7 +1464,7 @@ been unsuspended before. 这仅适用于从未暂停的 Job。 Job 的 Pod 模板中可以更新的字段是节点亲和性、节点选择器、容忍、标签、注解和 @@ -1339,12 +1490,12 @@ To do this, you can specify the `.spec.selector` of the Job. 为了实现这点,你可以手动设置 Job 的 `spec.selector` 字段。 做这个操作时请务必小心。 @@ -1359,7 +1510,7 @@ Kubernetes 不会在你设置 `.spec.selector` 时尝试阻止你犯这类错误 @@ -1478,13 +1629,92 @@ scaling an indexed Job, such as MPI, Horovord, Ray, and PyTorch training jobs. 弹性索引 Job 的使用场景包括需要扩展索引 Job 的批处理工作负载,例如 MPI、Horovord、Ray 和 PyTorch 训练作业。 + +### 延迟创建替换 Pod {#pod-replacement-policy} + +{{< feature-state for_k8s_version="v1.28" state="alpha" >}} + +{{< note >}} + +你只有在启用了 `JobPodReplacementPolicy` +[特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/)后, +才能为 Job 设置 `podReplacementPolicy`。 +{{< /note >}} + + +默认情况下,当 Pod 失败或正在终止(具有删除时间戳)时,Job 控制器会立即重新创建 Pod。 +这意味着,在某个时间点上,当一些 Pod 正在终止时,为 Job 正运行中的 Pod 数量可以大于 `parallelism` +或超出每个索引一个 Pod(如果使用 Indexed Job)。 + + +你可以选择仅在终止过程中的 Pod 完全终止(具有 `status.phase: Failed`)时才创建替换 Pod。 +为此,可以设置 `.spec.podReplacementPolicy: Failed`。 +默认的替换策略取决于 Job 是否设置了 `podFailurePolicy`。对于没有定义 Pod 失败策略的 Job, +省略 `podReplacementPolicy` 字段相当于选择 `TerminatingOrFailed` 替换策略: +控制平面在 Pod 删除时立即创建替换 Pod(只要控制平面发现该 Job 的某个 Pod 被设置了 `deletionTimestamp`)。 +对于设置了 Pod 失败策略的 Job,默认的 `podReplacementPolicy` 是 `Failed`,不允许其他值。 +请参阅 [Pod 失败策略](#pod-failure-policy)以了解更多关于 Job 的 Pod 失败策略的信息。 + +```yaml +kind: Job +metadata: + name: new + ... +spec: + podReplacementPolicy: Failed + ... +``` + + +如果你的集群启用了此特性门控,你可以检查 Job 的 `.status.terminating` 字段。 +该字段值是当前处于终止过程中的、由该 Job 拥有的 Pod 的数量。 + +```shell +kubectl get jobs/myjob -o yaml +``` + + +```yaml +apiVersion: batch/v1 +kind: Job +# .metadata 和 .spec 被省略 +status: + terminating: 3 # 三个 Pod 正在终止且还未达到 Failed 阶段 +``` + @@ -1522,7 +1752,7 @@ Job 管理的是那些希望被终止的 Pod(例如,批处理作业)。 ### Single Job starts controller Pod Another pattern is for a single Job to create a Pod which then creates other Pods, acting as a sort -of custom controller for those Pods. This allows the most flexibility, but may be somewhat +of custom controller for those Pods. This allows the most flexibility, but may be somewhat complicated to get started with and offers less integration with Kubernetes. --> ### 单个 Job 启动控制器 Pod {#single-job-starts-controller-pod} @@ -1534,8 +1764,8 @@ complicated to get started with and offers less integration with Kubernetes.