3.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 文档

3.2.1. 了解作业和 CronJob

作业会跟踪任务的整体进度,并使用活跃、成功和失败 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 文档中的作业模式

CronJob
通过使用 CronJob,可以调度一个作业运行多次。

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

CronJob 可用于创建周期性和重复执行的任务,如运行备份或发送电子邮件。CronJob 也可以将个别任务调度到指定时间执行,例如,将一个作业调度到低活动时段执行。

警告

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

3.2.2. 了解如何创建作业

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

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

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

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

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

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

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

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

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

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

3.2.2.3. 了解如何配置 CronJob 以移除工件

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

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

    $ oc delete cronjob/<cron_job_name>

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

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

3.2.3. 已知限制

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

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

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

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

3.2.4. 创建作业

您可以通过创建作业对象在 OpenShift Container Platform 中创建作业。

流程

创建作业:

  1. 创建一个类似以下示例的 YAML 文件:

    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 副本;默认与 completions 相同。

      • 对于非并行作业,请保留未设置。当取消设置时,默认为 1
    2. 另外,还可指定标记作业完成时需要成功完成多少个 pod。

      • 对于非并行作业,请保留未设置。当取消设置时,默认为 1
      • 对于具有固定完成计数的并行作业,请指定完成数。
      • 对于带有工作队列的并行作业,请保留 unset。当取消设置默认为 parallelism 值。
    3. 可选值,定义作业可以运行的最长持续时间。
    4. 另外,还可指定作业的重试次数。此字段默认值为 6。
    5. 指定控制器创建的 Pod 模板。
    6. 指定 pod 的重启策略。

      • Never不要重启作业。
      • OnFailure。仅在失败时重启该任务。
      • Always。总是重启该任务。

如需详细了解 OpenShift Container Platform 如何使用与失败容器相关的重启策略,请参阅 Kubernetes 文档中的示例状态

  1. 创建作业:

    $ oc create -f <file-name>.yaml
注意

您还可以使用 oc run,在一个命令中创建并启动作业。以下命令会创建并启动与上一示例中指定的相同的作业:

$ oc run pi --image=perl --replicas=1  --restart=OnFailure \
    --command -- perl -Mbignum=bpi -wle 'print bpi(2000)'

3.2.5. 创建 CronJob

您可以通过创建作业对象在 OpenShift Container Platform 中创建 CronJob。

流程

创建 CronJob:

  1. 创建一个类似以下示例的 YAML 文件:

    apiVersion: batch/v1beta1
    kind: CronJob
    metadata:
      name: pi
    spec:
      schedule: "*/1 * * * *"  1
      concurrencyPolicy: "Replace" 2
      startingDeadlineSeconds: 200 3
      suspend: true            4
      successfulJobsHistoryLimit: 3 5
      failedJobsHistoryLimit: 1     6
      jobTemplate:             7
        spec:
          template:
            metadata:
              labels:          8
                parent: "cronjobpi"
            spec:
              containers:
              - name: pi
                image: perl
                command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
              restartPolicy: OnFailure 9
    1 1 1
    cron 格式指定的作业调度计划。在本例中,作业将每分钟运行一次。
    2 2 2
    可选的并发策略,指定如何对待 CronJob 中的并发作业。只能指定以下并发策略之一。若未指定,默认为允许并发执行。
    • Allow,允许 CronJob 并发运行。
    • Forbid,禁止并发运行。如果上一运行尚未结束,则跳过下一运行。
    • Replace,取消当前运行的作业并替换为新作业。
    3 3 3
    可选期限(秒为单位),如果作业因任何原因而错过预定时间,则在此期限内启动作业。错过的作业执行计为失败的作业。若不指定,则没有期限。
    4 4 4
    可选标志,允许挂起 CronJob。若设为 true,则会挂起所有后续执行。
    5 5 5
    要保留的成功完成作业数(默认为 3)。
    6 6 6
    要保留的失败完成作业数(默认为 1)。
    7
    作业模板。类似于作业示例。
    8
    为此 CronJob 生成的作业设置一个标签。
    9
    pod 的重启策略。这不适用于作业控制器。
    注意

    .spec.successfulJobsHistoryLimit.spec.failedJobsHistoryLimit 字段是可选的,用于指定应保留的已完成作业和已失败作业的数量。默认情况下,分别设置为 31。如果将限制设定为 0,则对应种类的作业完成后不予保留。

  2. 创建 CronJob:

    $ oc create -f <file-name>.yaml
注意

您还可以使用 oc run,在一个命令中创建并启动 CronJob。以下命令会创建并启动与上一示例中指定的相同的 CronJob:

$ oc run pi --image=perl --schedule='*/1 * * * *' \
    --restart=OnFailure --labels parent="cronjobpi" \
    --command -- perl -Mbignum=bpi -wle 'print bpi(2000)'

使用 oc run 时,--schedule 选项接受采用 cron 格式的调度计划。

在创建 CronJob 时,oc run 仅支持 NeverOnFailure 重启策略 (--restart)。