4.2. 使用任务在 Pod 中运行任务

作业(job)在 OpenShift Container Platform 集群中执行某项任务。

作业会跟踪任务的整体进度,并使用活跃、成功和失败 pod 的相关信息来更新其状态。删除作业会清理它创建的所有 pod 副本。作业是 Kubernetes API 的一部分,可以像其他对象类型一样通过 oc 命令进行管理。

作业规格示例

apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  parallelism: 1    1
  completions: 1    2
  activeDeadlineSeconds: 1800 3
  backoffLimit: 6   4
  template:         5
    metadata:
      name: pi
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: OnFailure    6

1
作业应并行运行的 pod 副本 。
2
pod 成功完成后需要标记为作业也完成。
3
作业可以运行的最长时间。
4
作业的重试次数。
5
控制器创建的 pod 模板。
6
pod 的重启策略。

如需有关作业的更多信息,请参阅 Kubernetes 文档

4.2.1. 了解作业和 cron 作业

作业会跟踪任务的整体进度,并使用活跃、成功和失败 pod 的相关信息来更新其状态。删除作业会清理它创建的所有 pod。作业是 Kubernetes API 的一部分,可以像其他对象类型一样通过 oc 命令进行管理。

OpenShift Container Platform 中有两种资源类型可以创建只运行一次的对象:

作业
常规作业是一种只运行一次的对象,它会创建一个任务并确保作业完成。

有三种适合作为作业运行的任务类型:

  • 非并行作业:

    • 仅启动一个 pod 的作业,除非 pod 失败。
    • 一旦 pod 成功终止,作业就会马上完成。
  • 带有固定完成计数的并行作业:

    • 启动多个 pod 的作业。
    • Job 代表整个任务,并在 1completions 范围内的每个值都有一个成功 pod 时完成 。
  • 带有工作队列的并行作业:

    • 在一个给定 pod 中具有多个并行 worker 进程的作业。
    • OpenShift Container Platform 协调 pod,以确定每个 pod 都应该使用什么作业,或使用一个外部队列服务。
    • 每个 pod 都可以独立决定是否所有对等 pod 都已完成(整个作业完成)。
    • 当所有来自作业的 pod 都成功终止时,不会创建新的 pod。
    • 当至少有一个 pod 成功终止并且所有 pod 都终止时,作业成功完成。
    • 当任何 pod 成功退出时,其他 pod 都不应该为这个任务做任何工作或写任何输出。Pod 都应该处于退出过程中。

如需有关如何使用不同类型的作业的更多信息,请参阅 Kubernetes 文档中的作业模式

Cron job
通过使用 Cron Job,一个作业可以被调度为运行多次。

Cron Job 基于常规作业构建,允许您指定作业的运行方式。Cron job 是 Kubernetes API 的一部分,可以像其他对象类型一样通过 oc 命令进行管理。

Cron Job 可用于创建周期性和重复执行的任务,如运行备份或发送电子邮件。Cron Job 也可以将个别任务调度到指定时间执行,例如,将一个作业调度到低活动时段执行。一个 cron 作业会创建一个 Job 对象,它基于在运行 cronjob 的 control plane 节点上配置的时区。

警告

Cron Job 大致会在调度的每个执行时间创建一个 Job 对象,但在有些情况下,它可能无法创建作业,或者可能会创建两个作业。因此,作业必须具有幂等性,而且您必须配置历史限制。

4.2.1.1. 了解如何创建作业

两种资源类型都需要一个由以下关键部分组成的作业配置:

  • pod 模板,用于描述 OpenShift Container Platform 创建的 pod。
  • parallelism 参数,用于指定在任意时间点上应并行运行多少个 pod 来执行某个作业。

    • 对于非并行作业,请保留未设置。当取消设置时,默认为 1
  • completions 参数,用于指定需要成功完成多少个 pod 才能完成某个作业。

    • 对于非并行作业,请保留未设置。当取消设置时,默认为 1
    • 对于带有固定完成计数的并行作业,请指定一个值。
    • 对于带有工作队列的并行作业,请保留 unset。当取消设置默认为 parallelism 值。

4.2.1.2. 了解如何为作业设置最长持续时间

在定义作业时,您可以通过设置 activeDeadlineSeconds 字段来定义其最长持续时间。以秒为单位指定,默认情况下不设置。若未设置,则不强制执行最长持续时间。

最长持续时间从系统中调度第一个 pod 的时间开始计算,并且定义作业在多久时间内处于活跃状态。它将跟踪整个执行时间。达到指定的超时后,OpenShift Container Platform 将终止作业。

4.2.1.3. 了解如何为 pod 失败设置作业避退策略

在因为配置中的逻辑错误或其他类似原因而重试了一定次数后,作业会被视为已经失败。控制器以六分钟为上限,按指数避退延时(10s20s40s …)重新创建与作业关联的失败 pod。如果控制器检查之间没有出现新的失败 pod,则重置这个限制。

使用 spec.backoffLimit 参数为作业设置重试次数。

4.2.1.4. 了解如何配置 Cron Job 以移除工件

Cron Job 可能会遗留工件资源,如作业或 pod 等。作为用户,务必要配置一个历史限制,以便能妥善清理旧作业及其 pod。Cron Job 规格内有两个字段负责这一事务:

  • .spec.successfulJobsHistoryLimit。要保留的成功完成作业数(默认为 3)。
  • .spec.failedJobsHistoryLimit。要保留的失败完成作业数(默认为 1)。
提示
  • 删除您不再需要的 Cron Job:

    $ oc delete cronjob/<cron_job_name>

    这样可防止生成不必要的工件。

  • 您可以通过将 spec.suspend 设置为 true 来挂起后续执行。所有后续执行都会挂起,直到重置为 false

4.2.1.5. 已知限制

作业规格重启策略只适用于 pod,不适用于作业控制器。不过,作业控制器被硬编码为可以一直重试直到作业完成为止。

因此,restartPolicy: Never--restart=Never 会产生与 restartPolicy: OnFailure--restart=OnFailure 相同的行为。也就是说,作业失败后会自动重启,直到成功(或被手动放弃)为止。策略仅设定由哪一子系统执行重启。

使用 Never 策略时,作业控制器负责执行重启。在每次尝试时,作业控制器会在作业状态中递增失败次数并创建新的 pod。这意味着,每次尝试失败都会增加 pod 的数量。

使用 OnFailure 策略时,kubelet 负责执行重启。每次尝试都不会在作业状态中递增失败次数。另外,kubelet 将通过在相同节点上启动 pod 来重试失败的作业。