工作

Job创建一个或多个pod,并将继续重试pod的执行,直到指定数量的pod成功终止。当pod成功完成时,Job跟踪成功完成。当达到指定数量的成功完成时,任务(即Job)就完成了。删除一个Job将清理它创建的Pods。挂起Job将删除其活动pod,直到Job再次恢复。

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

还可以使用Job并行运行多个pod。

如果您希望在调度中运行一个Job(单个任务或多个并行任务),请参见的计划

运行示例Job

下面是一个示例Job配置。它计算π到2000位,然后打印出来。大约需要10分钟才能完成。

apiVersion批次/v1种类工作元数据的名字圆周率规范模板规范容器-的名字圆周率图像perl命令“perl”“-Mbignum=bpi”“wle”“打印bpi(2000)“restartPolicy从不backoffLimit4

你可以用这个命令运行示例:

kubectl应用-f//www.amasoeur.com/examples/controllers/job.yaml

输出类似如下:

的工作。批量创建/π

检查Job的状态kubectl

/πkubectl描述工作

输出类似如下:

名称:pi命名空间:default选择器:controller-uid=c9948307-e56d-4b5d-8302-ae2d7b7da67c标签:controller-uid=c9948307-e56d-4b5d-8302-ae2d7b7da67c job-name=pi注释:kubectl.kubernetes。io / last-applied-configuration:{“apiVersion”:“批/ v1”、“类型”:“工作”,“元数据”:{"注释":{},“名字”:“π”、“名称”:“默认”},“规范”:{“backoffLimit”:4,“模板”:……并行性:1完成:1开始时间:星期一,2019年12月02 15:20:11 + 0200完成:星期一,2019年12月02 15:21:16 + 0200时间:65年代豆荚状态:运行/ 1成功/ 0失败Pod模板:标签:controller-uid = c9948307 e56d - 4 b5d - 8302 ae2d7b7da67c作业名=π容器:π:形象:perl端口:< >没有主机端口:<无>命令:perl -Mbignum=bpi -wle print bpi(2000) Environment:  Mounts:  Volumes:  Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulCreate 14m job-controller Created pod: pi-5rwd7 . log . log . log . log . log . log . log

要查看完成的作业荚,请使用kubectl得到豆荚

要以机器可读的形式列出属于某个Job的所有pod,可以使用如下命令:

豆荚$(Kubectl得到pod,选择器作业名π-输出jsonpath“{. items [*] .metadata.name}”回声美元的豆荚

输出类似如下:

pi-5rwd7

这里,选择器与作业的选择器相同。这个——输出= jsonpath选项指定一个表达式,该表达式的名称来自返回列表中的每个Pod。

查看一个豆荚的标准输出:

kubectl日志美元的豆荚

输出类似如下:

3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275901

写工作说明书

与所有其他Kubernetes配置一样,Job需要apiVersion种类元数据字段。名称必须是有效的DNS域名

一份工作也需要.spec部分

豆荚模板

.spec.template的唯一必填字段是.spec

.spec.template是一个豆荚模板.它和a有完全相同的基模圆荚体,但它是嵌套的且没有apiVersion种类

除了Pod所需的字段外,Job中的Pod模板还必须指定适当的标签(参见豆荚选择器)以及适当的重启策略。

只有一个RestartPolicy等于从不OnFailure是被允许的。

豆荚选择器

.spec.selector字段是可选的。在几乎所有情况下,您都不应该指定它。见第节指定您自己的pod选择器

作业的并行执行

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

  1. 场工作
    • 正常情况下,只有一个Pod启动,除非Pod失败。
    • 一旦Pod成功终止,Job就完成了。
  2. 并行作业固定完成数
    • 指定一个非零的正值.spec.completions
    • Job代表整个任务,并且在有任务时完成.spec.completions成功的豆荚。
    • 使用时.spec.completionMode =“索引”,每个Pod获得一个范围为0到的不同索引.spec.completions-1
  3. 并行作业工作队列
    • 没有指定.spec.completions默认情况下,.spec.parallelism
    • pod必须在它们自己之间或外部服务之间进行协调,以确定每个pod应该处理什么。例如,Pod可能从工作队列中获取最多N个项目的批处理。
    • 每个Pod都能够独立地确定是否完成了所有对等点,从而完成整个工作。
    • 任何Job中的Pod成功终止,没有创建新的Pod。
    • 一旦至少有一个Pod成功终止,并且所有Pod都终止,则作业将成功完成。
    • 一旦任何Pod成功退出,其他Pod就不应继续为此任务执行任何工作或编写任何输出。他们都应该在退出的过程中。

对于一个非平行工作,你可以离开两者.spec.completions.spec.parallelism未设置的。当两者都未设置时,两者都默认为1。

对于一个固定完成数工作,你应该定下来.spec.completions需要完成的数量。你可以设置.spec.parallelism,或者不设置,默认值为1。

对于一个工作队列工作,你必须离开.spec.completions设置,并设置.spec.parallelism变成一个非负整数。

有关如何利用不同类型的工作的更多信息,请参阅工作模式部分。

并行性控制

请求的并行度(.spec.parallelism)可以设置为任何非负值。如果未指定,则默认为1。如果将其指定为0,则作业将有效暂停,直到增加。

由于各种原因,实际并行度(任何时刻运行的POD数)可能大于或小于请求的并行度:

  • 固定完成数作业,并行运行的pod的实际数量不会超过剩余的完成数量。更高的值.spec.parallelism实际上是忽视了。
  • 工作队列Jobs,在任何Pod成功后,都不会启动新的Pod——但是,允许剩余的Pod完成。
  • 如果这份工作控制器没有时间作出反应。
  • 如果作业控制器由于任何原因(缺少ResourceQuota如缺乏许可等),那么豆荚可能比要求的要少。
  • 作业控制器可能会由于同一作业中先前过多的Pod失败而限制新Pod的创建。
  • 当Pod被优雅地关闭时,它需要一段时间才能停止。

完成模式

功能状态: Kubernetes v1.22(β)

工作与固定完成数—即具有非空值的作业.spec.completions-可以具有指定的完成模式.spec.completionMode

  • NonIndexed(默认):Job被认为已经完成.spec.completions成功地完成了吊舱。换句话说,每个Pod完成是彼此同源的。注意有null的Jobs.spec.completions含蓄地NonIndexed
  • 索引: Job的Pods获得一个从0到的关联完成索引.spec.completions-1.该索引可通过以下三个机制获得:
    • 豆荚注释batch.www.amasoeur.com / job-completion-index
    • 作为Pod主机名的一部分,遵循以下模式(作业名)-(美元指数).将索引作业与服务,作业中的吊舱可以使用确定性主机名通过DNS相互寻址。
    • 从包含的任务中,在环境变量中JOB_COMPLETION_INDEX.当每个索引都有一个成功完成的Pod时,就认为Job已经完成。有关如何使用此模式的详细信息,请参见带静态工作分配的并行处理索引作业.注意,尽管很少,但是可以为同一个索引启动多个Pod,但只有一个Pod会计入完成计数。

处理吊舱和集装箱故障

Pod中的容器可能会由于多种原因而失败,例如,因为其中的进程以非零退出代码退出,或者容器因超出内存限制而被终止,等等。如果发生这种情况.spec.template.spec。restartPolicy="OnFailure",则Pod停留在节点上,但容器将重新运行。因此,您的程序需要在本地重新启动时处理这种情况,或者指定.spec.template.spec。restartPolicy="Never".看到豆荚生命周期有关restartPolicy

整个Pod也可能会失败,原因有很多,例如当Pod被踢出节点时(节点被升级、重新启动、删除等),或者如果Pod的容器出现故障并且.spec.template.spec。restartPolicy="Never".当Pod失败时,Job控制器将启动一个新的Pod。这意味着当应用程序在新的pod中重新启动时,需要处理这种情况。特别地,它需要处理临时文件、锁、不完整的输出等先前运行引起的问题。

注意,即使您指定.spec.parallelism=1.spec.completions=1.spec.template.spec。restartPolicy="Never",同一个程序有时可能被启动两次。

如果你指定.spec.parallelism.spec.completions两者都大于1,那么可能有多个pod同时运行。因此,您的pods也必须能够容忍并发。

吊舱后退故障策略

在某些情况下,由于配置中的逻辑错误等原因,您希望在多次重试后失败一个Job。为此,设置.spec.backoffLimit指定在认为作业失败之前的重试次数。回退限制默认设置为6。与Job关联的失败的pod由Job控制器以指数级的回退延迟(10s、20s、40s……)重新创建,延迟上限为6分钟。当Job的Pod被删除或成功,而Job没有任何其他Pod失败时,将重置回退计数。

注意:如果你的工作restartPolicy = " OnFailure ",请记住,一旦达到作业回退限制,运行作业的容器将被终止。这会使调试Job的可执行文件变得更加困难。我们建议设置restartPolicy = "永远"当调试作业或使用日志系统来确保失败的作业的输出不会无意中丢失时。

作业终止和清理

当一个作业完成时,不会再创建POD,但会创建POD通常不是删除。保留它们允许您仍然查看已完成荚的日志,以检查错误、警告或其他诊断输出。作业对象在完成后仍然保留,以便您可以查看它的状态。用户可以在记录旧作业的状态后删除它们。删除作业kubectl(如。/πkubectl删除工作Kubectl删除-f ./job.yaml).当您删除作业使用kubectl,它创建的所有豆荚也被删除了。

默认情况下,Job将不间断运行,除非Pod发生故障(restartPolicy =没有)或者容器错误退出(restartPolicy = OnFailure),此时Job将服从于.spec.backoffLimit上面所描述的。一次.spec.backoffLimit已经到达,作业将被标记为失败,任何正在运行的pod将被终止。

另一种终止Job的方法是设置一个有效的截止日期。通过设置.spec.activeDeadlineSecondsJob字段的秒数。的activeDeadlineSeconds适用于作业的持续时间,无论创建了多少Pods。一旦找到工作activeDeadlineSeconds,所有正在运行的POD都将终止,作业状态将变为类型:失败原因:超出死线

注意,Job's.spec.activeDeadlineSeconds优先于它的.spec.backoffLimit.因此,重新尝试一个或多个失败pod的Job在达到指定的时间限制后将不会部署其他podactiveDeadlineSeconds,即使backoffLimit尚未达成。

例子:

apiVersion批次/v1种类工作元数据的名字pi-with-timeout规范backoffLimit5activeDeadlineSeconds100模板规范容器-的名字圆周率图像perl命令“perl”“-Mbignum=bpi”“wle”“打印bpi(2000)“restartPolicy从不

请注意,Job规范和豆荚模板规范约伯有一个activeDeadlineSeconds字段。确保将该字段设置在适当的级别。

请记住restartPolicy适用于Pod,而不适用于作业本身:一旦作业状态为类型:失败.也就是说,Job终止机制被激活.spec.activeDeadlineSeconds.spec.backoffLimit导致永久性作业失败,需要手动干预才能解决。

自动清理已完成的工作

系统中通常不再需要已完成的作业。将它们保存在系统中会给API服务器带来压力。如果Jobs直接由更高级别的控制器管理,例如的计划时,可由CronJobs根据指定的基于容量的清理策略进行清理。

完成作业的TTL机制

功能状态: Kubernetes v1.21(β)

清理已完成作业的另一种方法(或完整的失败的)自动是使用由TTL控制器对于已完成的资源,通过指定.spec.ttlSecondsAfterFinished工作领域。

当TTL控制器清理Job时,它将级联地删除Job,即将其依赖对象(如Pods)与Job一起删除。请注意,当Job被删除时,它的生命周期保证(例如终结器)将得到遵守。

例如:

apiVersion批次/v1种类工作元数据的名字带ttl的pi规范ttlSecondsAfterFinished100模板规范容器-的名字圆周率图像perl命令“perl”“-Mbignum=bpi”“wle”“打印bpi(2000)“restartPolicy从不

工作带ttl的pi将有资格被自动删除,100完成后几秒钟。

如果该字段设置为0,作业将有资格在完成后立即自动删除。如果该字段未设置,则此作业在完成后不会被TTL控制器清除。

工作模式

Job对象可用于支持pod的可靠并行执行。Job对象不是为支持紧密通信的并行进程而设计的,这在科学计算中很常见。它支持一组独立但相关的并行处理工作项。这些可能是要发送的电子邮件、要呈现的帧、要转码的文件、要扫描的NoSQL数据库中的密钥范围,等等。

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

并行计算有几种不同的模式,每种模式都有优缺点。权衡:

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

这里总结了权衡,列2到4对应于上述权衡。模式名还链接到示例和更详细的描述。

模式 单一的工作对象 豆荚比工作项目更少? 用程序修改的吗?
每个工作项使用Pod排队 有时
具有可变吊舱数的队列
带有静态工作分配的索引工作
工作模板扩张

当您指定用.spec.completions, Job控制器创建的每个Pod都有一个相同的规范.这意味着任务的所有pod将具有相同的命令行、相同的映像、相同的卷和(几乎)相同的环境变量。这些模式是安排豆荚处理不同事情的不同方法。

这个表显示了所需的设置.spec.parallelism.spec.completions对于每个模式。在这里,W是工作项的数量。

模式 .spec.completions .spec.parallelism
每个工作项使用Pod排队 W 任何
具有可变吊舱数的队列 无效的 任何
带有静态工作分配的索引工作 W 任何
工作模板扩张 1 应该是1

高级用法

暂停工作

功能状态: Kubernetes v1.22(β)
注意:在Kubernetes 1.21版本中,这个特性是alpha版本,需要额外的步骤来启用这个特性;一定要读您正在使用的德赢是不是大平台Kubernetes版本的正确文档

当创建Job时,Job控制器将立即开始创建Pods以满足Job的要求,并将继续这样做,直到Job完成。但是,您可能希望临时暂停Job的执行,稍后再恢复它。若要挂起作业,您可以更新.spec.suspend工作领域要真实;稍后,如果要再次恢复,请将其更新为false。利用.spec.suspend设置为true将在挂起状态下创建它。

当一个作业从暂停状态恢复时,它的.status.startTime字段将重置为当前时间。这意味着.spec.activeDeadlineSeconds当作业挂起并恢复时,定时器将停止并重置。

记住,挂起一个Job将删除所有活动的pod。当工作暂停,你的吊舱将被终止使用SIGTERM信号。花苞的优雅终止期将被尊重,你的花苞必须在此期间处理这个信号。这可能包括为以后保存进度或撤消更改。以这种方式终止的豆荚将不计入任务完成计数

挂起状态下的Job定义示例如下:

Kubectl,得到我的工作-哦,我的
apiVersion批次/v1种类工作元数据的名字myjob规范暂停符合事实的并行性1完成5模板规范...

Job的状态可以用来确定Job是否被挂起或过去曾经被挂起:

Kubectl得到工作/我的工作-哦,yaml
apiVersion:批/ v1类型:工作. metadata.spec省略了状态:条件:-lastProbeTime:“2021-02-05T13:14:33Z”lastTransitionTime:“2021-02-05T13:14:33Z”状态:“真正的”类型:暂停开始时间:“2021 - 02年- 05 - t13:13:48z”

类型为“Suspended”状态为“True”的Job状态,表示Job被暂停;的lastTransitionTime字段可用于确定Job已暂停多长时间。如果该条件的状态为“False”,则Job先前被挂起,现在正在运行。如果Job的状态中不存在这样的条件,则Job从未被停止过。

当Job被挂起和恢复时,也会创建事件:

/ myjob kubectl描述工作
名称:myjob……事件:Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulCreate 12m Job -controller Created pod: myjob-hlrpl Normal SuccessfulDelete 11m Job -controller Deleted pod: myjob-hlrpl Normal Suspended 11m Job -controller Job Suspended Normal SuccessfulCreate 3s Job -controller Created pod:myjob-jvb44 Normal Resumed 3s Job -controller作业恢复

最后四个事件,特别是“暂停”和“恢复”事件,是切换的直接结果.spec.suspend领域在这两个事件之间,我们看到没有创建Pod,但Pod创建在作业恢复后立即重新启动。

指定自己的Pod选择器

通常,在创建Job对象时,不指定.spec.selector. 系统默认逻辑在创建作业时添加此字段。它选择一个不会与任何其他作业重叠的选择器值。

然而,在某些情况下,您可能需要覆盖这个自动设置选择器。为此,您可以指定.spec.selector的工作。

做这件事的时候要非常小心。如果您指定一个标签选择器并不是唯一的吊舱的工作,比赛无关的豆荚,豆荚的无关的工作可能会被删除,或者这份工作可能计算其他豆荚完成它,或一个或两个工作可以拒绝创建吊舱或运行完成。如果选择了非唯一的选择器,那么其他控制器(例如ReplicationController)和它们的pod也可能以不可预测的方式运行。Kubernetes不会阻止你在指定的时候犯错误.spec.selector

下面是您可能希望使用此特性的一个示例。

说工作古老的已经运行。您希望现有的pod继续运行,但希望它创建的其余pod使用不同的pod模板,并使Job具有新名称。您无法更新Job,因为这些字段是不可更新的。因此,删除Job古老的让它的豆荚继续运转,使用Kubectl delete jobs/old——cascade=orphan.在删除它之前,你要记下它使用的选择器:

Kubectl得到了一份老工作

输出类似如下:

种类工作元数据的名字古老的...规范选择器matchLabelscontroller-uida8f3d00d c6d2 - 11 - e5 9 f87 af00002——42010...

然后创建一个名为的新作业你明确地指定相同的选择器。因为现有的Pods有标签controller-uid = a8f3d00d c6d2 - 11 - e5 9 f87 af00002——42010,它们由作业控制

你需要指定manualSelector:真,因为您没有使用系统通常自动生成的选择器。

种类工作元数据的名字...规范manualSelector符合事实的选择器matchLabelscontroller-uida8f3d00d c6d2 - 11 - e5 9 f87 af00002——42010...

新的Job本身将有一个不同的uida8f3d00d c6d2 - 11 - e5 9 f87 af00002——42010. 背景manualSelector:真告诉系统您知道自己在做什么,并允许这种不匹配。

使用终结器进行工作跟踪

功能状态: Kubernetes v1.22(α)
注意:

要使用此行为,必须启用JobTrackingWithFinalizers功能门API服务器控制器管理器.默认禁用。

当启用时,控制平面使用下面描述的行为跟踪新job。现有的工作岗位不受影响。作为用户,您可以看到的唯一区别是,Job完成的控制平面跟踪更加准确。

当该特性未启用时,Job控制器依赖于计算集群中存在的Pods来跟踪Job状态,也就是说,为成功失败豆荚。然而,pod可以被删除的原因有很多,包括:

  • 当节点停止运行时删除孤立吊舱的垃圾收集器。
  • 删除已完成pod的垃圾收集器(在成功失败的阶段)。
  • 人为干预删除属于Job的pod。
  • 一个外部控制器(不作为Kubernetes的一部分提供),用于删除或替换Pods。

如果您启用JobTrackingWithFinalizers对于集群功能,控制平面跟踪属于任何作业的Pod,并注意是否从API服务器中删除了任何此类Pod。为此,作业控制器使用终结器创建Podbatch.www.amasoeur.com / job-tracking.只有在Pod已被计入Job状态后,控制器才会删除终结器,从而允许其他控制器或用户删除Pod。

作业控制器仅对新作业使用新算法。启用功能之前创建的作业不受影响。通过检查作业是否具有注释,可以确定作业控制器是否正在使用Pod终结器跟踪作业batch.www.amasoeur.com / job-tracking.你应该手动从Jobs中添加或删除该注释。

选择

裸露的豆荚

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

复制控制器

工作与工作相辅相成复制控制器.复制控制器管理那些预计不会终止的pod(例如web服务器),作业管理那些预计会终止的pod(例如批处理任务)。

讨论了在豆荚生命周期工作只有适用于带有RestartPolicy等于OnFailure从不.(注意:如果RestartPolicy未设置,默认值为总是.)

单作业启动控制器吊舱

另一种模式是让一个Job创建一个Pod,然后再创建其他Pod,充当这些Pod的某种自定义控制器。这提供了最大的灵活性,但开始时可能有些复杂,并且提供了与Kubernetes的较少集成。

这种模式的一个例子是一个Job,它启动一个Pod,这个Pod运行一个脚本,然后启动一个Spark主控制器(参见火花的例子),运行spark驱动程序,然后进行清理。

这种方法的一个优点是,整个流程获得Job对象的完成保证,但对创建什么pod以及如何向它们分配工作保持完全控制。

接下来是什么

最后修改于2021年9月28日上午1:16太平洋标准时间:更新工作负载概念页面的“下一步是什么”部分(#29730)(5b373f5bb)