概念

Kubernetes v1.16 文档不再得到积极维护。您当前正在查看的版本是静态快照。有关最新文档,请参见 最新版本。

Edit This Page

职位-完成

作业创建一个或多个Pod,并确保指定数量的Pod成功终止。 吊舱成功完成后,工作将跟踪成功完成的情况。指定号码时 达到成功完成的次数,任务(即Job)就完成了。删除作业会清理 the Pods it created.

一种简单的情况是创建一个Job对象,以可靠地运行一个Pod来完成。 如果第一个Pod失败或被删除,则Job对象将启动一个新Pod(例如 由于节点硬件故障或节点重启)。

您还可以使用作业并行运行多个Pod。

运行示例作业

这是一个作业配置示例。它计算π到2000个位置并将其打印出来。 大约需要10秒钟才能完成。

controllers/job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never
  backoffLimit: 4

您可以使用以下命令运行示例:

kubectl apply -f //k8s.io/examples/controllers/job.yaml
job.batch/pi created

Check on the status of the Job with kubectl:

kubectl describe jobs/pi
Name:           pi
Namespace:      default
Selector:       controller-uid=c9948307-e56d-4b5d-8302-ae2d7b7da67c
Labels:         controller-uid=c9948307-e56d-4b5d-8302-ae2d7b7da67c
                job-name=pi
Annotations:    kubectl.kubernetes.io/last-applied-configuration:
                  {"apiVersion":"batch/v1","kind":"Job","metadata":{"annotations":{},"name":"pi","namespace":"default"},"spec":{"backoffLimit":4,"template":...
Parallelism:    1
Completions:    1
Start Time:     Mon, 02 Dec 2019 15:20:11 +0200
Completed At:   Mon, 02 Dec 2019 15:21:16 +0200
Duration:       65s
Pods Statuses:  0 Running / 1 Succeeded / 0 Failed
Pod Template:
  Labels:  controller-uid=c9948307-e56d-4b5d-8302-ae2d7b7da67c
           job-name=pi
  Containers:
   pi:
    Image:      perl
    Port:       <none>
    Host Port:  <none>
    Command:
      perl
      -Mbignum=bpi
      -wle
      print bpi(2000)
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age   From            Message
  ----    ------            ----  ----            -------
  Normal  SuccessfulCreate  14m   job-controller  Created pod: pi-5rwd7

To view completed Pods of a Job, use kubectl get pods.

要以机器可读形式列出属于作业的所有Pod,可以使用以下命令:

荚s=$(kubectl get pods --selector=job-name=pi --output=jsonpath='{.items[*].metadata.name}')
echo $pods
pi-5rwd7

Here, the selector is the same as the selector for the Job. The --output=jsonpath option specifies an expression 只是从返回列表中的每个Pod中获取名称。

查看其中一个Pod的标准输出:

kubectl logs $pods

输出类似于以下内容:

3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275901

编写工作规范

As with all other Kubernetes config, a Job needs apiVersion, kind, and metadata fields.

一个工作还需要一个 .spec section.

吊舱模板

The .spec.template is the only required field of the .spec.

The .spec.template is a 吊舱模板。它的架构与 , except it is nested and does not have an apiVersion 或者 kind.

除Pod的必填字段外,作业中的Pod模板还必须指定适当的字段 labels (see 吊舱选择器)和适当的重启策略。

只有一个 RestartPolicy equal to Never 或者 OnFailure is allowed.

吊舱选择器

The .spec.selector field is optional. In almost all cases you should not specify it. See section 指定自己的Pod选择器.

并行作业

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

  1. 非并行作业
    • 通常,除非Pod发生故障,否则仅启动一个Pod。
    • 一旦Pod成功终止,作业即完成。
  2. 并行作业 固定完成计数:
    • specify a non-zero positive value for .spec.completions.
    • the Job represents the overall task, and is complete when there is one successful Pod for each value in the range 1 to .spec.completions.
    • 尚未实施: Each Pod is passed a different index in the range 1 to .spec.completions.
  3. 并行作业 工作队列:
    • do not specify .spec.completions, default to .spec.parallelism.
    • Pod必须在彼此之间或外部服务之间进行协调,以确定每个Pod应该如何处理。例如,一个Pod可以从工作队列中获取最多N批的批处理。
    • 每个Pod都可以独立确定其所有对等方是否都已完成,从而确定了整个Job。
    • 什么时候 任何 作业中的Pod成功终止,不会创建新的Pod。
    • 一旦至少一个Pod成功终止并且所有Pod都终止,则作业成功完成。
    • 一旦Pod成功退出,则其他Pod仍不应为此任务做任何工作或编写任何输出。他们都应该退出。

为一个 非平行 Job, you can leave both .spec.completions and .spec.parallelism unset. When both are 未设置,两者均默认为1。

为一个 固定完成计数 Job, you should set .spec.completions to the number of completions needed. You can set .spec.parallelism, or leave it unset and it will default to 1.

为一个 工作队列 Job, you must leave .spec.completions unset, and set .spec.parallelism to 一个非负整数。

有关如何利用不同类型的工作的更多信息,请参见 工作模式 section.

控制并行

The requested parallelism (.spec.parallelism) can be set to any non-negative value. 如果未指定,则默认为1。 如果将其指定为0,则作业将被有效地暂停直到被增加。

实际并行度(随时运行的Pod数量)可能大于或小于请求 并行性,由于多种原因:

  • 为了 固定完成计数 作业中,并行运行的Pod的实际数量不会超过 remaining completions. Higher values of .spec.parallelism are effectively ignored.
  • 为了 工作队列 Jobs,任何Pod成功后都不会启动新的Pod–但是,剩余的Pod可以完成。
  • 如果工作 控制器一个控制环,它通过apiserver监视群集的共享状态,并进行更改以尝试将当前状态移向所需状态。 还没来得及反应。
  • 如果工作 controller failed to create Pods for any reason (lack of ResourceQuota, lack of permission, etc.), 那么豆荚的数量可能会少于请求的数量。
  • 作业控制器可能会由于同一作业中先前的过多Pod故障而限制新Pod的创建。
  • 如果Pod正常关闭,则需要花费一些时间才能停止。

处理Pod和容器故障

Pod中的容器可能由于多种原因而失败,例如由于其中的进程退出 非零的退出代码,或者容器因超出内存限制而被杀死,等等。如果这 happens, and the .spec.template.spec.restartPolicy = "OnFailure", then the Pod stays 在节点上,但是容器重新运行。因此,您的程序需要处理这种情况 restarted locally, or else specify .spec.template.spec.restartPolicy = "Never". See 吊舱生命周期 为了 more information on restartPolicy.

整个Pod也可能因多种原因而失败,例如,当Pod被踢离节点时 (节点已升级,重新引导,删除等),或者Pod的容器发生故障并且 .spec.template.spec.restartPolicy = "Never"。当Pod发生故障时,作业控制器 启动一个新的Pod。这意味着您的应用程序需要在新的环境下重新启动时处理该情况。 荚。特别是,它需要处理临时文件,锁,不完整的输出等。 由先前的运行引起。

不 te that even if you specify .spec.parallelism = 1 and .spec.completions = 1 and .spec.template.spec.restartPolicy = "Never",同一程序可能 有时会启动两次。

If you do specify .spec.parallelism and .spec.completions both greater than 1, then there may be 多个Pod同时运行。因此,您的Pod也必须容忍并发。

Pod后退失败策略

在某些情况下,您需要经过一定的重试次数才能使作业失败 由于配置等方面的逻辑错误 To do so, set .spec.backoffLimit to specify the number of retries before 认为工作失败。退避限制默认设置为6。失败 与作业相关联的Pod由作业控制器重新创建,并带有 指数退避延迟(10s,20s,40s…)的上限为六分钟。这 如果作业之前没有新的失败Pod出现,则会重置退避计数’s next status check.

笔记: 问题 #54870 版本1.12之前的Kubernetes版本仍然存在
笔记: If your job has restartPolicy = "OnFailure", keep in mind that your container running the Job 一旦达到作业退避限制,将终止。这可以调试作业’s的可执行文件更加困难。我们建议设置 restartPolicy = "Never" 在调试作业或使用日志记录系统以确保输出时 失败的乔布斯不会因疏忽而丢失。

作业终止和清理

作业完成后,不会再创建其他Pod,但是Pod也不会被删除。保持他们周围 使您仍然可以查看已完成的容器的日志,以检查错误,警告或其他诊断输出。 作业对象在完成后也会保留下来,以便您查看其状态。由用户决定删除 old jobs after noting their status. Delete the job with kubectl (e.g. kubectl delete jobs/pi 或者 kubectl delete -f ./job.yaml). When you delete the job using kubectl, all the pods it created are deleted too.

By default, a Job will run uninterrupted unless a Pod fails (restartPolicy=Never) or a Container exits in error (restartPolicy=OnFailure), at which point the Job defers to the .spec.backoffLimit described above. Once .spec.backoffLimit has been reached the Job will be marked as failed and any running Pods will be terminated.

终止工作的另一种方法是设置有效期限。 Do this by setting the .spec.activeDeadlineSeconds field of the Job to a number of seconds. The activeDeadlineSeconds applies to the duration of the job, no matter how many Pods are created. Once a Job reaches activeDeadlineSeconds, all of its running Pods are terminated and the Job status will become type: Failed with reason: DeadlineExceeded.

注意工作’s .spec.activeDeadlineSeconds takes precedence over its .spec.backoffLimit. Therefore, a Job that is retrying one or more failed Pods will not deploy additional Pods once it reaches the time limit specified by activeDeadlineSeconds, even if the backoffLimit is not yet reached.

例子:

apiVersion: batch/v1
kind: Job
metadata:
  name: pi-with-timeout
spec:
  backoffLimit: 5
  activeDeadlineSeconds: 100
  template:
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never

请注意,作业规范和 Pod模板规格 within the Job have an activeDeadlineSeconds field. Ensure that you set this field at the proper level.

自动清理完成的作业

系统中通常不再需要完成作业。保持它们在附近 系统将对API服务器施加压力。如果直接管理工作 由更高级别的控制器(例如 CronJobs,乔布斯可以 由CronJobs根据指定的基于容量的清理策略进行清理。

完成作业的TTL机制

功能状态: Kubernetes v1.12 α
该功能当前位于 α state, meaning:

  • 版本名称包含Alpha(例如v1alpha1)。
  • 可能是越野车。启用该功能可能会暴露错误。默认禁用。
  • 随时可能删除对功能的支持,恕不另行通知。
  • 在以后的软件版本中,API可能会以不兼容的方式更改,恕不另行通知。
  • 由于存在更高的错误风险和缺乏长期支持,建议仅用于短期测试集群。

Another way to clean up finished Jobs (either Complete 或者 Failed) 自动是使用由 TTL控制器 for finished resources, by specifying the .spec.ttlSecondsAfterFinished field of the Job.

TTL控制器清理作业时,会级联删除作业, 即删除其相关对象,例如Pod,以及Job。笔记 当作业被删除时,其生命周期保证(例如终结器)将 be honored.

例如:

apiVersion: batch/v1
kind: Job
metadata:
  name: pi-with-ttl
spec:
  ttlSecondsAfterFinished: 100
  template:
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never

The Job pi-with-ttl will be eligible to be automatically deleted, 100 完成后几秒钟。

If the field is set to 0, the Job will be eligible to be automatically deleted 完成后立即执行。如果未设置该字段,则此作业胜出’t be cleaned 完成后由TTL控制器启动。

不 te that this TTL mechanism is alpha, with feature gate TTLAfterFinished. For 有关更多信息,请参见文档。 TTL控制器 for finished resources.

工作模式

Job对象可用于支持Pods的可靠并行执行。 Job对象不是 设计用于支持紧密通信的并行过程,这在科学中很常见 计算。它确实支持一组独立但相关的并行处理 工作项目. 这些可能是要发送的电子邮件,要渲染的帧,要转码的文件, 要扫描的NoSQL数据库,等等。

在复杂的系统中,可能会有多个不同的工作项集。我们在这里 考虑用户想要一起管理的一组工作项— a 批处理作业.

并行计算有几种不同的模式,每种都有优点和缺点。 The tradeoffs are:

  • 每个工作项只有一个Job对象,而所有工作项只有一个Job对象。后者是 对大量工作项目更好。前者为用户和 系统来管理大量的Job对象。
  • 与每个Pod可以处理多个工作项相比,创建的pod数等于工作项数。 前者通常需要对现有代码和容器进行较少的修改。后者 出于与上一个项目符号类似的原因,对于大量工作项来说更好。
  • 几种方法使用工作队列。这需要运行队列服务, 并对现有程序或容器进行修改,以使其使用工作队列。 其他方法更容易适应现有的容器化应用程序。

此处总结了权衡,第2至4列对应于上述权衡。 模式名称也是示例和更详细说明的链接。

图案 单个作业对象 豆荚比工作项目少? 使用未修改的应用程序? 在Kube 1.1中工作?
作业模板扩展
每个工作项带有Pod的队列 有时
具有可变Pod计数的队列
具有静态工作分配的单个作业

When you specify completions with .spec.completions, each Pod created by the Job controller has an identical spec。这意味着 任务的所有Pod将具有相同的命令行和相同的 映像,相同的体积和(几乎)相同的环境变量。这些模式 安排广告连播在不同事物上工作的方式不同。

This table shows the required settings for .spec.parallelism and .spec.completions 为了 each of the patterns. Here, W is the number of work items.

图案 .spec.completions .spec.parallelism
作业模板扩展 1 应该是1
每个工作项带有Pod的队列 W 任何
具有可变Pod计数的队列 1 任何
具有静态工作分配的单个作业 W 任何

高级用法

指定自己的Pod选择器

不 rmally, when you create a Job object, you do not specify .spec.selector. 创建作业时,系统默认逻辑会添加此字段。 它选择一个不会与任何其他作业重叠的选择器值。

但是,在某些情况下,您可能需要覆盖此自动设置的选择器。 To do this, you can specify the .spec.selector of the Job.

这样做时要非常小心。如果指定的标签选择器不是 该职位的豆荚所独有,并且与无关的豆荚匹配,然后与无关的豆荚匹配 作业可能被删除,或者该作业可能将其他Pod视为完成该作业,或者其中之一或两者都 乔布斯可能拒绝创建Pod或将其完成。如果非唯一选择器是 选择,则其他控制器(例如复制控制器)及其Pod可能会表现 也以不可预测的方式Kubernetes不会阻止您在以下情况下犯错 specifying .spec.selector.

这是您可能要使用此功能时的示例。

Say Job old is already running. You want existing Pods 保持运行,但是您想要它创建的其余Pod 使用不同的pod模板,并使Job具有新名称。 您无法更新作业,因为这些字段不可更新。 Therefore, you delete Job old but 离开豆荚 running, using kubectl delete jobs/old --cascade=false. 删除它之前,请记下它使用的选择器:

kubectl get job old -o yaml
kind: Job
metadata:
  name: old
  ...
spec:
  selector:
    matchLabels:
      controller-uid: a8f3d00d-c6d2-11e5-9f87-42010af00002
  ...

Then you create a new Job with name new and you explicitly specify the same selector. Since the existing Pods have label controller-uid=a8f3d00d-c6d2-11e5-9f87-42010af00002, they are controlled by Job new as well.

You need to specify manualSelector: true in the new Job since you are not using 系统通常会自动为您生成的选择器。

kind: Job
metadata:
  name: new
  ...
spec:
  manualSelector: true
  selector:
    matchLabels:
      controller-uid: a8f3d00d-c6d2-11e5-9f87-42010af00002
  ...

The new Job itself will have a different uid from a8f3d00d-c6d2-11e5-9f87-42010af00002. Setting manualSelector: true 告诉系统您知道自己在做什么,并允许这样做 mismatch.

备择方案

裸荚

当Pod在其上运行的节点重新启动或发生故障时,该Pod终止 并且不会重新启动。但是,作业将创建新的Pod来替换终止的Pod。 因此,即使您的应用程序是我们,也建议您使用Job而不是裸Pod 只需要一个Pod。

复制控制器

工作是对工作的补充 复制控制器. 复制控制器管理不应终止的Pod(例如Web服务器)和作业 管理可能会终止的Pod(例如批处理任务)。

正如在 Pod生命周期, Job is 只要 appropriate for pods with RestartPolicy equal to OnFailure 或者 Never. (Note: If RestartPolicy is not set, the default value is Always.)

单个作业启动Controller Pod

另一种模式是由单个Job创建一个Pod,然后再创建其他Pod,作为一种排序 这些Pod的自定义控制器。这样可以提供最大的灵活性,但可能有些 入门很复杂,并且与Kubernetes的集成较少。

这种模式的一个示例是Job,它启动一个Pod,该Pod运行一个脚本,该脚本依次 启动Spark主控制器(请参阅 火花的例子),发出火花 驱动程序,然后清理。

这种方法的一个优点是整个过程都可以确保完成工作 对象,但可以完全控制创建什么Pod以及如何分配工作。

克伦·乔布斯

您可以使用 CronJob to create a Job that will run at specified times/dates, similar to the Unix tool cron.

回馈