• 打赏 jQuery火箭图标返回顶部代码</h1> <hr> <span class="pre-scrollable"><div id="cnblogs_post_body" class="blogpost-body"> <div> <div data-df="lake"> <p data-wording="true" data-lake-id="82d9659d3f9c8c3350f6f4e1b056ac07_p_0"><span style="font-family: "Microsoft YaHei"; font-size: 14px">Kubernetes的主要任务是保证Pod中的应用长久稳定的运行,但是我们有时候也需要一些只需要运行一次,执行完就退出了的"短时"任务,这时候使用Deployment等这类控制器就无法满足我们的需求,Kubernetes就诞生了Job Controller,专门用来处理这类需求。</span></p> <h2 id="3g7f9" data-wording="true" data-lake-id="a74ae1dca73357e001fe622c90aca097_h1_0"><span style="font-family: "Microsoft YaHei"; font-size: 14px">1、Job</span></h2> <h3 id="J4NmS" data-wording="true" data-lake-id="07a24ecb29e7ae8f826918ddf8145645_h2_0"><span style="font-family: "Microsoft YaHei"; font-size: 14px">1.1、基本操作</span></h3> <p data-wording="true" data-lake-id="cf3b90ca520ca51e34f54baf08b0efe7_p_1"><span style="font-family: "Microsoft YaHei"; font-size: 14px">Job负责处理仅执行一次的任务,它保证批处理的任务的一个或多个成功结束,我们可以通过kubectl explain job来查看具体语法,如下:</span></p> <div id="szxA3" data-card-type="block" data-lake-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22yaml%22%2C%22code%22%3A%22%5Broot%40master%20~%5D%23%20kubectl%20explain%20job%5CnKIND%3A%20%20%20%20%20Job%5CnVERSION%3A%20%20batch%2Fv1%5Cn%5CnDESCRIPTION%3A%5Cn%20%20%20%20%20Job%20represents%20the%20configuration%20of%20a%20single%20job.%5Cn%5CnFIELDS%3A%5Cn%20%20%20apiVersion%20%20%20%3Cstring%3E%5Cn%20%20%20%20%20APIVersion%20defines%20the%20versioned%20schema%20of%20this%20representation%20of%20an%5Cn%20%20%20%20%20object.%20Servers%20should%20convert%20recognized%20schemas%20to%20the%20latest%20internal%5Cn%20%20%20%20%20value%2C%20and%20may%20reject%20unrecognized%20values.%20More%20info%3A%5Cn%20%20%20%20%20https%3A%2F%2Fgit.k8s.io%2Fcommunity%2Fcontributors%2Fdevel%2Fapi-conventions.md%23resources%5Cn%5Cn%20%20%20kind%20%3Cstring%3E%5Cn%20%20%20%20%20Kind%20is%20a%20string%20value%20representing%20the%20REST%20resource%20this%20object%5Cn%20%20%20%20%20represents.%20Servers%20may%20infer%20this%20from%20the%20endpoint%20the%20client%20submits%5Cn%20%20%20%20%20requests%20to.%20Cannot%20be%20updated.%20In%20CamelCase.%20More%20info%3A%5Cn%20%20%20%20%20https%3A%2F%2Fgit.k8s.io%2Fcommunity%2Fcontributors%2Fdevel%2Fapi-conventions.md%23types-kinds%5Cn%5Cn%20%20%20metadata%20%20%20%20%20%3CObject%3E%5Cn%20%20%20%20%20Standard%20object's%20metadata.%20More%20info%3A%5Cn%20%20%20%20%20https%3A%2F%2Fgit.k8s.io%2Fcommunity%2Fcontributors%2Fdevel%2Fapi-conventions.md%23metadata%5Cn%5Cn%20%20%20spec%20%3CObject%3E%5Cn%20%20%20%20%20Specification%20of%20the%20desired%20behavior%20of%20a%20job.%20More%20info%3A%5Cn%20%20%20%20%20https%3A%2F%2Fgit.k8s.io%2Fcommunity%2Fcontributors%2Fdevel%2Fapi-conventions.md%23spec-and-status%5Cn%5Cn%20%20%20status%20%20%20%20%20%20%20%3CObject%3E%5Cn%20%20%20%20%20Current%20status%20of%20a%20job.%20More%20info%3A%5Cn%20%20%20%20%20https%3A%2F%2Fgit.k8s.io%2Fcommunity%2Fcontributors%2Fdevel%2Fapi-conventions.md%23spec-and-status%5Cn%22%2C%22id%22%3A%22szxA3%22%7D" data-language="yaml"> <div> <div> <div class="cnblogs_code"> <pre>[root@master ~<span style="color: rgba(0, 0, 0, 1)">]# kubectl explain job KIND: Job VERSION: batch</span>/<span style="color: rgba(0, 0, 0, 1)">v1 DESCRIPTION: Job represents the configuration of a single job. FIELDS: apiVersion </span><<span style="color: rgba(0, 0, 255, 1)">string</span>><span style="color: rgba(0, 0, 0, 1)"> APIVersion defines the versioned schema of </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)"> representation of an </span><span style="color: rgba(0, 0, 255, 1)">object</span>. Servers should convert recognized schemas to the latest <span style="color: rgba(0, 0, 255, 1)">internal</span><span style="color: rgba(0, 0, 0, 1)"> value, and may reject unrecognized values. More info: https:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">git.k8s.io/community/contributors/devel/api-conventions.md#resources</span> <span style="color: rgba(0, 0, 0, 1)"> kind </span><<span style="color: rgba(0, 0, 255, 1)">string</span>><span style="color: rgba(0, 0, 0, 1)"> Kind </span><span style="color: rgba(0, 0, 255, 1)">is</span> a <span style="color: rgba(0, 0, 255, 1)">string</span> value representing the REST resource <span style="color: rgba(0, 0, 255, 1)">this</span> <span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)"> represents. Servers may infer </span><span style="color: rgba(0, 0, 255, 1)">this</span> <span style="color: rgba(0, 0, 255, 1)">from</span><span style="color: rgba(0, 0, 0, 1)"> the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds</span> <span style="color: rgba(0, 0, 0, 1)"> metadata </span><Object><span style="color: rgba(0, 0, 0, 1)"> Standard </span><span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">s metadata. More info:</span> https:<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">git.k8s.io/community/contributors/devel/api-conventions.md#metadata</span> <span style="color: rgba(0, 0, 0, 1)"> spec </span><Object><span style="color: rgba(0, 0, 0, 1)"> Specification of the desired behavior of a job. More info: https:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status</span> <span style="color: rgba(0, 0, 0, 1)"> status </span><Object><span style="color: rgba(0, 0, 0, 1)"> Current status of a job. More info: https:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status</span></pre> </div> <p><span style="font-family: "Microsoft YaHei"">从上面可以看到跟我们定义Deployment,Pod的语法是差不多的,下面我们定义一个Job的YAML文件:</span></p> </div> </div> </div> <div class="cnblogs_code"> <pre>job-<span style="color: rgba(0, 0, 0, 1)">demo.yaml apiVersion: batch</span>/<span style="color: rgba(0, 0, 0, 1)">v1 kind: Job metadata: name: job</span>-<span style="color: rgba(0, 0, 0, 1)">demo </span><span style="color: rgba(0, 0, 255, 1)">namespace</span>: <span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> spec: template: metadata: name: job</span>-<span style="color: rgba(0, 0, 0, 1)">demo spec: containers: </span>- name: test-<span style="color: rgba(0, 0, 0, 1)">job image: busybox imagePullPolicy: IfNotPresent command: </span>- <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/bin/sh</span><span style="color: rgba(128, 0, 0, 1)">"</span> - <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">-c</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)"> args: </span>- <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">for i in $(seq 10); do echo $i; done</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)"> restartPolicy: Never backoffLimit: </span><span style="color: rgba(128, 0, 128, 1)">4</span></pre> </div> <p><span style="font-family: "Microsoft YaHei"">从上面的YAML文件我们可以看到Job的spec里就是我们熟悉的Pod模板。我们执行kubectl apply -f job-demo.yaml,查看运行信息:</span></p> <div id="Kl5B1" data-card-type="block" data-lake-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22yaml%22%2C%22code%22%3A%22%5Broot%40master%20job%5D%23%20kubectl%20get%20job%5CnNAME%20%20%20%20%20%20%20COMPLETIONS%20%20%20DURATION%20%20%20AGE%5Cnjob-demo%20%20%201%2F1%20%20%20%20%20%20%20%20%20%20%205s%20%20%20%20%20%20%20%20%207s%5Cn%5Broot%40master%20job%5D%23%20kubectl%20describe%20job%20job-demo%5CnName%3A%20%20%20%20%20%20%20%20%20%20%20job-demo%5CnNamespace%3A%20%20%20%20%20%20default%5CnSelector%3A%20%20%20%20%20%20%20controller-uid%3D5000fea1-8af7-4199-b482-082b7e94f6fd%5CnLabels%3A%20%20%20%20%20%20%20%20%20controller-uid%3D5000fea1-8af7-4199-b482-082b7e94f6fd%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20job-name%3Djob-demo%5CnAnnotations%3A%20%20%20%20kubectl.kubernetes.io%2Flast-applied-configuration%3A%5Cn%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%5C%22apiVersion%5C%22%3A%5C%22batch%2Fv1%5C%22%2C%5C%22kind%5C%22%3A%5C%22Job%5C%22%2C%5C%22metadata%5C%22%3A%7B%5C%22annotations%5C%22%3A%7B%7D%2C%5C%22name%5C%22%3A%5C%22job-demo%5C%22%2C%5C%22namespace%5C%22%3A%5C%22default%5C%22%7D%2C%5C%22spec%5C%22%3A%7B%5C%22backoffLimit%5C%22%3A4%2C%5C%22temp...%5CnParallelism%3A%20%20%20%201%5CnCompletions%3A%20%20%20%201%5CnStart%20Time%3A%20%20%20%20%20Wed%2C%2023%20Oct%202019%2015%3A55%3A19%20%2B0800%5CnCompleted%20At%3A%20%20%20Wed%2C%2023%20Oct%202019%2015%3A55%3A24%20%2B0800%5CnDuration%3A%20%20%20%20%20%20%205s%5CnPods%20Statuses%3A%20%200%20Running%20%2F%201%20Succeeded%20%2F%200%20Failed%5CnPod%20Template%3A%5Cn%20%20Labels%3A%20%20controller-uid%3D5000fea1-8af7-4199-b482-082b7e94f6fd%5Cn%20%20%20%20%20%20%20%20%20%20%20job-name%3Djob-demo%5Cn%20%20Containers%3A%5Cn%20%20%20test-job%3A%5Cn%20%20%20%20Image%3A%20%20%20%20%20%20busybox%5Cn%20%20%20%20Port%3A%20%20%20%20%20%20%20%3Cnone%3E%5Cn%20%20%20%20Host%20Port%3A%20%20%3Cnone%3E%5Cn%20%20%20%20Command%3A%5Cn%20%20%20%20%20%20%2Fbin%2Fsh%5Cn%20%20%20%20%20%20-c%5Cn%20%20%20%20Args%3A%5Cn%20%20%20%20%20%20for%20i%20in%20%24(seq%2010)%3B%20do%20echo%20%24i%3B%20done%5Cn%20%20%20%20Environment%3A%20%20%3Cnone%3E%5Cn%20%20%20%20Mounts%3A%20%20%20%20%20%20%20%3Cnone%3E%5Cn%20%20Volumes%3A%20%20%20%20%20%20%20%20%3Cnone%3E%5CnEvents%3A%5Cn%20%20Type%20%20%20%20Reason%20%20%20%20%20%20%20%20%20%20%20%20Age%20%20%20From%20%20%20%20%20%20%20%20%20%20%20%20Message%5Cn%20%20----%20%20%20%20------%20%20%20%20%20%20%20%20%20%20%20%20----%20%20----%20%20%20%20%20%20%20%20%20%20%20%20-------%5Cn%20%20Normal%20%20SuccessfulCreate%20%2015s%20%20%20job-controller%20%20Created%20pod%3A%20job-demo-f9hmn%22%2C%22id%22%3A%22Kl5B1%22%7D" data-language="yaml"> <pre></pre> <div class="cnblogs_code"> <pre>[root@master job]# kubectl <span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)"> job NAME COMPLETIONS DURATION AGE job</span>-demo <span style="color: rgba(128, 0, 128, 1)">1</span>/<span style="color: rgba(128, 0, 128, 1)">1</span> 5s 7s</pre> </div> <p><span style="font-family: "Microsoft YaHei"; font-size: 14px">从上面可以看到在Pod里自动生成了一个controller-uid的label,然后在Job的selector也会自动加上这个label,这就建立Job和它管理的Pod之间的对应关系。</span></p> </div> <p data-wording="true" data-lake-id="6a830804e924634ef0b76494da8bc366_p_9"><span style="font-family: "Microsoft YaHei"; font-size: 14px">接下来我们查看这个Pod的状态,如下:</span></p> <div data-card-type="block" data-lake-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22yaml%22%2C%22code%22%3A%22%5Broot%40master%20job%5D%23%20kubectl%20get%20pod%5CnNAME%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20READY%20%20%20STATUS%20%20%20%20%20%20RESTARTS%20%20%20AGE%5Cnjob-demo-f9hmn%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200%2F1%20%20%20%20%20Completed%20%20%200%20%20%20%20%20%20%20%20%20%202m35s%22%2C%22id%22%3A%22DAGZy%22%7D" data-language="yaml"> <div class="cnblogs_code"> <pre>[root@master job]# kubectl <span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)"> pod NAME READY STATUS RESTARTS AGE job</span>-demo-f9hmn <span style="color: rgba(128, 0, 128, 1)">0</span>/<span style="color: rgba(128, 0, 128, 1)">1</span> Completed <span style="color: rgba(128, 0, 128, 1)">0</span> 2m35s</pre> </div> </div> <p data-wording="true" data-lake-id="6d4e463ff3da78d46fbc6ffaca7fbeb3_p_10"><span style="font-family: "Microsoft YaHei"; font-size: 14px">我们可以看到执行结束后,STATUS变成了Completed状态,而且RESTARTS为0(表示为重启)。我们也可以看一下这个Pod的日志。</span></p> <p><span style="font-family: "Microsoft YaHei"; font-size: 14px"> </span><span style="font-family: "Microsoft YaHei"; font-size: 14px">我们可以看到这个Pod只运行了一次。</span></p> <p data-wording="true" data-lake-id="7650a63d2ef0dda8ddcbe739bcac94cb_p_13"><span style="font-family: "Microsoft YaHei"; font-size: 14px">那么如果这个任务执行失败了呢?比如我们将上面的YAML文件中的args参数随便改一个非Linux命令,如下:</span></p> <div data-card-type="block" data-lake-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22yaml%22%2C%22code%22%3A%22%20%20%20%20%20%20......%5Cn%20%20%20%20%20%20args%3A%5Cn%20%20%20%20%20%20%20%20-%20%5C%22xxxxxx%5C%22%5Cn%20%20%20%20%20%20......%22%2C%22id%22%3A%22crAQj%22%7D" data-language="yaml"> <div> <div> <pre><span style="font-family: "Microsoft YaHei"; font-size: 14px"> ...... args: - "xxxxxx" ......</span></pre> </div> </div> </div> <p data-wording="true" data-lake-id="403f90f6aac6eddd73ae40213d38a8ae_p_15"><span style="font-family: "Microsoft YaHei"; font-size: 14px">然后我们查看Pod的状态:</span></p> <div data-card-type="block" data-lake-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22yaml%22%2C%22code%22%3A%22%5Broot%40master%20job%5D%23%20kubectl%20get%20pod%5CnNAME%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20READY%20%20%20STATUS%20%20%20%20%20%20%20%20%20%20%20%20%20%20RESTARTS%20%20%20AGE%5Cnjob-demo-2ccjq%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200%2F1%20%20%20%20%20Error%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200%20%20%20%20%20%20%20%20%20%2011s%5Cnjob-demo-hwss6%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200%2F1%20%20%20%20%20ContainerCreating%20%20%200%20%20%20%20%20%20%20%20%20%203s%5Cn%22%2C%22id%22%3A%22gp0b6%22%7D" data-language="yaml"> <pre></pre> <div class="cnblogs_code"> <pre>[root@master job]# kubectl <span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)"> pod NAME READY STATUS RESTARTS AGE job</span>-demo-2ccjq <span style="color: rgba(128, 0, 128, 1)">0</span>/<span style="color: rgba(128, 0, 128, 1)">1</span> Error <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)"> 11s job</span>-demo-hwss6 <span style="color: rgba(128, 0, 128, 1)">0</span>/<span style="color: rgba(128, 0, 128, 1)">1</span> ContainerCreating <span style="color: rgba(128, 0, 128, 1)">0</span> 3s</pre> </div> <p><span style="font-family: "Microsoft YaHei"; font-size: 14px">我们看到这个Job任务没有执行成功,我们定义了restartPolicy=Never,这时候Job Controller就会创建一个新的Pod。我们在Job的YAML文件里定义了backoffLimit=4,这表明重试次数只有4次,默认是6次,4次重试都还未成功,则这个Job则失败:</span></p> </div> <div data-card-type="block" data-lake-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22yaml%22%2C%22code%22%3A%22%5Broot%40master%20job%5D%23%20kubectl%20get%20pod%5CnNAME%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20READY%20%20%20STATUS%20%20%20%20RESTARTS%20%20%20AGE%5Cnjob-demo-2ccjq%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200%2F1%20%20%20%20%20Error%20%20%20%20%200%20%20%20%20%20%20%20%20%20%203m21s%5Cnjob-demo-2kdpc%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200%2F1%20%20%20%20%20Error%20%20%20%20%200%20%20%20%20%20%20%20%20%20%202m43s%5Cnjob-demo-7q62j%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200%2F1%20%20%20%20%20Error%20%20%20%20%200%20%20%20%20%20%20%20%20%20%203m3s%5Cnjob-demo-hwss6%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200%2F1%20%20%20%20%20Error%20%20%20%20%200%20%20%20%20%20%20%20%20%20%203m13s%5CnYou%20have%20new%20mail%20in%20%2Fvar%2Fspool%2Fmail%2Froot%5Cn%5Broot%40master%20job%5D%23%20kubectl%20get%20job%5CnNAME%20%20%20%20%20%20%20COMPLETIONS%20%20%20DURATION%20%20%20AGE%5Cnjob-demo%20%20%200%2F1%20%20%20%20%20%20%20%20%20%20%205m49s%20%20%20%20%20%205m49s%5CnYou%20have%20new%20mail%20in%20%2Fvar%2Fspool%2Fmail%2Froot%22%2C%22id%22%3A%22KPy6i%22%7D" data-language="yaml"> <div class="cnblogs_code"> <pre>[root@master job]# kubectl <span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)"> pod NAME READY STATUS RESTARTS AGE job</span>-demo-2ccjq <span style="color: rgba(128, 0, 128, 1)">0</span>/<span style="color: rgba(128, 0, 128, 1)">1</span> Error <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)"> 3m21s job</span>-demo-2kdpc <span style="color: rgba(128, 0, 128, 1)">0</span>/<span style="color: rgba(128, 0, 128, 1)">1</span> Error <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)"> 2m43s job</span>-demo-7q62j <span style="color: rgba(128, 0, 128, 1)">0</span>/<span style="color: rgba(128, 0, 128, 1)">1</span> Error <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)"> 3m3s job</span>-demo-hwss6 <span style="color: rgba(128, 0, 128, 1)">0</span>/<span style="color: rgba(128, 0, 128, 1)">1</span> Error <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)"> 3m13s You have </span><span style="color: rgba(0, 0, 255, 1)">new</span> mail <span style="color: rgba(0, 0, 255, 1)">in</span> /<span style="color: rgba(0, 0, 255, 1)">var</span>/spool/mail/<span style="color: rgba(0, 0, 0, 1)">root [root@master job]# kubectl </span><span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)"> job NAME COMPLETIONS DURATION AGE job</span>-demo <span style="color: rgba(128, 0, 128, 1)">0</span>/<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)"> 5m49s 5m49s You have </span><span style="color: rgba(0, 0, 255, 1)">new</span> mail <span style="color: rgba(0, 0, 255, 1)">in</span> /<span style="color: rgba(0, 0, 255, 1)">var</span>/spool/mail/root</pre> </div> <p><span style="font-family: "Microsoft YaHei"">如果我们定义restartPolicy=OnFailure,如果作业失败,Job Controller就不会在创建新的Pod,但是会不断重启这个Pod。如下,我们把Job的YAML文件中的restartPolicy改成restartPolicy=OnFailure,测试如下:</span></p> </div> <div data-card-type="block" data-lake-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22yaml%22%2C%22code%22%3A%22%5Broot%40master%20job%5D%23%20kubectl%20get%20pod%5CnNAME%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20READY%20%20%20STATUS%20%20%20%20RESTARTS%20%20%20AGE%5Cnjob-demo-cbmft%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200%2F1%20%20%20%20%20Error%20%20%20%20%203%20%20%20%20%20%20%20%20%20%2069s%5Cn%22%2C%22id%22%3A%22OaQ2n%22%7D" data-language="yaml"> <pre></pre> <div class="cnblogs_code"> <pre>[root@master job]# kubectl <span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)"> pod NAME READY STATUS RESTARTS AGE job</span>-demo-cbmft <span style="color: rgba(128, 0, 128, 1)">0</span>/<span style="color: rgba(128, 0, 128, 1)">1</span> Error <span style="color: rgba(128, 0, 128, 1)">3</span> 69s</pre> </div> 我们可以看到RESTARTS变为了1,表示重启了3次。</div> <p><span style="font-family: "Microsoft YaHei"; font-size: 14px">还有一种情况,如果这个Job一直不肯结束怎么办呢?比如我们将上面的YAML文件做如下修改:</span></p> <div data-card-type="block" data-lake-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22yaml%22%2C%22code%22%3A%22apiVersion%3A%20batch%2Fv1%5Cnkind%3A%20Job%5Cnmetadata%3A%5Cn%20%20name%3A%20job-demo%5Cn%20%20namespace%3A%20default%5Cnspec%3A%5Cn%20%20template%3A%5Cn%20%20%20%20metadata%3A%5Cn%20%20%20%20%20%20name%3A%20job-demo%5Cn%20%20%20%20spec%3A%5Cn%20%20%20%20%20%20containers%3A%5Cn%20%20%20%20%20%20-%20name%3A%20test-job%5Cn%20%20%20%20%20%20%20%20image%3A%20busybox%5Cn%20%20%20%20%20%20%20%20imagePullPolicy%3A%20IfNotPresent%5Cn%20%20%20%20%20%20%20%20command%3A%5Cn%20%20%20%20%20%20%20%20-%20%5C%22%2Fbin%2Fsh%5C%22%5Cn%20%20%20%20%20%20%20%20-%20%5C%22-c%5C%22%5Cn%20%20%20%20%20%20%20%20args%3A%5Cn%20%20%20%20%20%20%20%20-%20%5C%22sleep%203600%5C%22%5Cn%20%20%20%20%20%20restartPolicy%3A%20OnFailure%5Cn%20%20backoffLimit%3A%204%5Cn%22%2C%22id%22%3A%22NZriL%22%7D" data-language="yaml"> <div class="cnblogs_code"> <pre>apiVersion: batch/<span style="color: rgba(0, 0, 0, 1)">v1 kind: Job metadata: name: job</span>-<span style="color: rgba(0, 0, 0, 1)">demo </span><span style="color: rgba(0, 0, 255, 1)">namespace</span>: <span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> spec: template: metadata: name: job</span>-<span style="color: rgba(0, 0, 0, 1)">demo spec: containers: </span>- name: test-<span style="color: rgba(0, 0, 0, 1)">job image: busybox imagePullPolicy: IfNotPresent command: </span>- <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/bin/sh</span><span style="color: rgba(128, 0, 0, 1)">"</span> - <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">-c</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)"> args: </span>- <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">sleep 3600</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)"> restartPolicy: OnFailure backoffLimit: </span><span style="color: rgba(128, 0, 128, 1)">4</span></pre> </div> </div> <p data-wording="true" data-lake-id="c55ba16022e043ef03af50cbe4c9958b_p_24"><span style="font-family: "Microsoft YaHei"; font-size: 14px">然后执行kubectl apply -f job-demo.yaml。我们可以发现这个Pod不会结束直到3600秒后,这时候如果我们加一个参数activeDeadlineSeconds,如下:</span></p> <div data-card-type="block" data-lake-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22yaml%22%2C%22code%22%3A%22spec%3A%5Cn......%5Cn%20%20%20%20%20%20restartPolicy%3A%20OnFailure%5Cn%20%20backoffLimit%3A%204%5Cn%20%20activeDeadlineSeconds%3A%20100%5Cn%22%2C%22id%22%3A%22xxSiH%22%7D" data-language="yaml"> <pre></pre> <div class="cnblogs_code"> <pre><span style="color: rgba(0, 0, 0, 1)">spec: ...... restartPolicy: OnFailure backoffLimit: </span><span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)"> activeDeadlineSeconds: </span><span style="color: rgba(128, 0, 128, 1)">100</span></pre> </div> <p><span style="font-family: "Microsoft YaHei"; font-size: 14px">这个参数的作用是如果这个Pod运行时间超过100s,这个Pod将被终止。</span></p> </div> <h3>1.2、并行控制</h3> <p data-wording="true" data-lake-id="eefc64c642eed7537628d76a489858a1_p_27"><span style="font-family: "Microsoft YaHei"; font-size: 14px">在Job对象中,负责控制并行的参数为:</span></p> <ul> <li data-wording="true" data-lake-id="a947555341989965f1ca4adb3685507b_li_0"><span style="font-family: "Microsoft YaHei"; font-size: 14px">completions:定义Job至少要完成的Pod数目,既Job的最小完成数;</span></li> <li data-wording="true" data-lake-id="e163844011ff615d06e72b213874e923_li_1"><span style="font-family: "Microsoft YaHei"; font-size: 14px">parallelism:定义一个Job在任意时间最多可以启动多少个Pod;</span></li> </ul> <p data-wording="true" data-lake-id="52c60c15e016f894c691b2d0dde12970_p_29"><span style="font-family: "Microsoft YaHei"; font-size: 14px">我们定义下面一个Job的YAML文件:</span></p> <div data-card-type="block" data-lake-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22yaml%22%2C%22code%22%3A%22apiVersion%3A%20batch%2Fv1%5Cnkind%3A%20Job%5Cnmetadata%3A%5Cn%20%20name%3A%20job-demo%5Cn%20%20namespace%3A%20default%5Cnspec%3A%5Cn%20%20parallelism%3A%202%5Cn%20%20completions%3A%204%5Cn%20%20template%3A%5Cn%20%20%20%20metadata%3A%5Cn%20%20%20%20%20%20name%3A%20job-demo%5Cn%20%20%20%20spec%3A%5Cn%20%20%20%20%20%20containers%3A%5Cn%20%20%20%20%20%20-%20name%3A%20test-job%5Cn%20%20%20%20%20%20%20%20image%3A%20busybox%5Cn%20%20%20%20%20%20%20%20imagePullPolicy%3A%20IfNotPresent%5Cn%20%20%20%20%20%20%20%20command%3A%5Cn%20%20%20%20%20%20%20%20-%20%5C%22%2Fbin%2Fsh%5C%22%5Cn%20%20%20%20%20%20%20%20-%20%5C%22-c%5C%22%5Cn%20%20%20%20%20%20%20%20args%3A%5Cn%20%20%20%20%20%20%20%20-%20%5C%22for%20i%20in%20%24(seq%2010)%3B%20do%20echo%20%24i%3B%20done%5C%22%5Cn%20%20%20%20%20%20restartPolicy%3A%20OnFailure%5Cn%20%20backoffLimit%3A%204%5Cn%20%20activeDeadlineSeconds%3A%20100%22%2C%22id%22%3A%22mcbHO%22%7D" data-language="yaml"> <div class="cnblogs_code"> <pre>apiVersion: batch/<span style="color: rgba(0, 0, 0, 1)">v1 kind: Job metadata: name: job</span>-<span style="color: rgba(0, 0, 0, 1)">demo </span><span style="color: rgba(0, 0, 255, 1)">namespace</span>: <span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> spec: parallelism: </span><span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)"> completions: </span><span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)"> template: metadata: name: job</span>-<span style="color: rgba(0, 0, 0, 1)">demo spec: containers: </span>- name: test-<span style="color: rgba(0, 0, 0, 1)">job image: busybox imagePullPolicy: IfNotPresent command: </span>- <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/bin/sh</span><span style="color: rgba(128, 0, 0, 1)">"</span> - <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">-c</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)"> args: </span>- <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">for i in $(seq 10); do echo $i; done</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)"> restartPolicy: OnFailure backoffLimit: </span><span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)"> activeDeadlineSeconds: </span><span style="color: rgba(128, 0, 128, 1)">100</span></pre> </div> </div> <p data-wording="true" data-lake-id="c98a44f1b20a9a848f726ceead2ef307_p_30"><span style="font-family: "Microsoft YaHei"; font-size: 14px">parallelism: 2 和 completions: 4表示要完成4个pod,每次可以同时运行两个Pod,我们创建这个Job。</span></p> <div data-card-type="block" data-lake-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22yaml%22%2C%22code%22%3A%22%5Broot%40master%20job%5D%23%20kubectl%20apply%20-f%20job-demo.yaml%20%5Cnjob.batch%2Fjob-demo%20created%5Cn%5Broot%40master%20job%5D%23%20kubectl%20get%20pod%5CnNAME%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20READY%20%20%20STATUS%20%20%20%20%20%20%20%20%20%20%20%20%20%20RESTARTS%20%20%20AGE%5Cnjob-demo-kcm4c%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200%2F1%20%20%20%20%20ContainerCreating%20%20%200%20%20%20%20%20%20%20%20%20%201s%5Cnjob-demo-kdrxl%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200%2F1%20%20%20%20%20Completed%20%20%20%20%20%20%20%20%20%20%200%20%20%20%20%20%20%20%20%20%204s%5Cnjob-demo-r4k49%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200%2F1%20%20%20%20%20ContainerCreating%20%20%200%20%20%20%20%20%20%20%20%20%202s%5Cnjob-demo-w9c49%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%200%2F1%20%20%20%20%20Completed%20%20%20%20%20%20%20%20%20%20%200%20%20%20%20%20%20%20%20%20%204s%22%2C%22id%22%3A%22ydDcv%22%7D" data-language="yaml"> <div class="cnblogs_code"> <pre>[root@master job]# kubectl apply -f job-<span style="color: rgba(0, 0, 0, 1)">demo.yaml job.batch</span>/job-<span style="color: rgba(0, 0, 0, 1)">demo created [root@master job]# kubectl </span><span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)"> pod NAME READY STATUS RESTARTS AGE job</span>-demo-kcm4c <span style="color: rgba(128, 0, 128, 1)">0</span>/<span style="color: rgba(128, 0, 128, 1)">1</span> ContainerCreating <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)"> 1s job</span>-demo-kdrxl <span style="color: rgba(128, 0, 128, 1)">0</span>/<span style="color: rgba(128, 0, 128, 1)">1</span> Completed <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)"> 4s job</span>-demo-r4k49 <span style="color: rgba(128, 0, 128, 1)">0</span>/<span style="color: rgba(128, 0, 128, 1)">1</span> ContainerCreating <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)"> 2s job</span>-demo-w9c49 <span style="color: rgba(128, 0, 128, 1)">0</span>/<span style="color: rgba(128, 0, 128, 1)">1</span> Completed <span style="color: rgba(128, 0, 128, 1)">0</span> 4s</pre> </div> </div> <p data-wording="true" data-lake-id="689c4bea925c81018ffd124a16df6f92_p_32"><span style="font-family: "Microsoft YaHei"; font-size: 14px">可以看到两个运行结束,另外两个才开始。</span></p> <h4 id="JDdN1" data-wording="true" data-lake-id="7f8357a13eb53b15ea542f688751a772_h2_2"><span style="font-family: "Microsoft YaHei"; font-size: 14px">1.3、原理总结</span></h4> <p data-wording="true" data-lake-id="474eeaa6eb531bdcdd8c9689fd9a1f2f_p_34"><span style="font-family: "Microsoft YaHei"; font-size: 14px">从上面可以知道,Job Controller实际控制的就是Pod,它在创建的时候会在Job和Pod里自动生成随机字符串的label,然后将它们进行绑定。</span></p> <p data-wording="true" data-lake-id="4cc4c970153a8bf70d7886b76f1db6aa_p_35"><span style="font-family: "Microsoft YaHei"; font-size: 14px">Job Controller在实际的调谐操作是根据实际在running状态的Pod数,还有已经退出的Pod数以及parallelism和completions的参数值共同计算出在Job周期内应该创建或者删除多少Pod,然后调用kube-api来执行这类操作。</span></p> <p data-wording="true" data-lake-id="4730ff9e37cf9adb65e854e13cdfef33_p_36"><span style="font-family: "Microsoft YaHei"; font-size: 14px">所以Job Controller实际上是控制的Pod的并行度以及总共要完成的任务数这两个重要的参数。</span></p> <h3 id="8t9oj" data-wording="true" data-lake-id="93d5f546f0a29f55e2a35f9b49d598c6_h2_3"><span style="font-family: "Microsoft YaHei"; font-size: 14px">1.4、使用场景</span></h3> <h4 id="8A2su" data-wording="true" data-lake-id="d08a53c948a709cf93e4b942ca4ea2ed_h3_0"><span style="font-family: "Microsoft YaHei"; font-size: 14px">1.4.1、外部管理器+Job模板</span></h4> <p data-wording="true" data-lake-id="99f4cbc350a443f29cf5161d57bb09dd_p_38"><span style="font-family: "Microsoft YaHei"; font-size: 14px">用法:把Job的YAML文件定义为一个模板,然后用外部工具来控制这个模板生成Job。</span></p> <p data-wording="true" data-lake-id="5c9e7085c8ba43098a096cd99ea691f4_p_39"><span style="font-family: "Microsoft YaHei"; font-size: 14px">比如我们定义如下YAML:</span></p> <div data-card-type="block" data-lake-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22yaml%22%2C%22code%22%3A%22%5CnapiVersion%3A%20batch%2Fv1%5Cnkind%3A%20Job%5Cnmetadata%3A%5Cn%20%20name%3A%20process-item-%24ITEM%5Cn%20%20labels%3A%5Cn%20%20%20%20jobgroup%3A%20jobexample%5Cnspec%3A%5Cn%20%20template%3A%5Cn%20%20%20%20metadata%3A%5Cn%20%20%20%20%20%20name%3A%20jobexample%5Cn%20%20%20%20%20%20labels%3A%5Cn%20%20%20%20%20%20%20%20jobgroup%3A%20jobexample%5Cn%20%20%20%20spec%3A%5Cn%20%20%20%20%20%20containers%3A%5Cn%20%20%20%20%20%20-%20name%3A%20c%5Cn%20%20%20%20%20%20%20%20image%3A%20busybox%5Cn%20%20%20%20%20%20%20%20command%3A%20%5B%5C%22sh%5C%22%2C%20%5C%22-c%5C%22%2C%20%5C%22echo%20Processing%20item%20%24ITEM%20%26%26%20sleep%205%5C%22%5D%5Cn%20%20%20%20%20%20restartPolicy%3A%20Never%22%2C%22id%22%3A%2249fxs%22%7D" data-language="yaml"> <pre></pre> <div class="cnblogs_code"> <pre>apiVersion: batch/<span style="color: rgba(0, 0, 0, 1)">v1 kind: Job metadata: name: process</span>-item-<span style="color: rgba(0, 0, 0, 1)">$ITEM labels: jobgroup: jobexample spec: template: metadata: name: jobexample labels: jobgroup: jobexample spec: containers: </span>-<span style="color: rgba(0, 0, 0, 1)"> name: c image: busybox command: [</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">sh</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">-c</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">echo Processing item $ITEM && sleep 5</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">] restartPolicy: Never</span></pre> </div> <p>我们在这个YAML文件里设定了一个$ITEM的变量,然后我们使用外部脚本来通过这个YAML文件生成Job,如下:</p> <div class="cnblogs_code"> <pre>$ mkdir ./<span style="color: rgba(0, 0, 0, 1)">jobs $ </span><span style="color: rgba(0, 0, 255, 1)">for</span> i <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> apple banana cherry </span><span style="color: rgba(0, 0, 255, 1)">do</span><span style="color: rgba(0, 0, 0, 1)"> cat job</span>-tmpl.yaml | sed <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">s/$ITEM/$i/</span><span style="color: rgba(128, 0, 0, 1)">"</span> > ./jobs/job-<span style="color: rgba(0, 0, 0, 1)">$i.yaml done</span></pre> </div> </div> <p data-wording="true" data-lake-id="b53cbd7065c6a9474ea179d91556d489_p_41"><span style="font-family: "Microsoft YaHei"; font-size: 14px">然后就会生成三个Job文件,这时候就可以通过kubectl apply -f .来执行这些Job。</span></p> <span style="font-family: "Microsoft YaHei"; font-size: 14px">1.4.2、固定任务数的并行Job</span> <p data-wording="true" data-lake-id="de3480bf97a273b391c7f383f043d2c0_p_43"><span style="font-family: "Microsoft YaHei"; font-size: 14px">在这种场景下,我们只关注是否有我们定义的指定数目的任务成功退出,并不会去关心并行度是多少。</span></p> <p data-wording="true" data-lake-id="bcb7ef2fdfdf1b68c51835ce0021cd61_p_44"><span style="font-family: "Microsoft YaHei"; font-size: 14px">比如:</span></p> <div data-card-type="block" data-lake-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22yaml%22%2C%22code%22%3A%22%5CnapiVersion%3A%20batch%2Fv1%5Cnkind%3A%20Job%5Cnmetadata%3A%5Cn%20%20name%3A%20job-wq-1%5Cnspec%3A%5Cn%20%20completions%3A%208%5Cn%20%20parallelism%3A%202%5Cn%20%20template%3A%5Cn%20%20%20%20metadata%3A%5Cn%20%20%20%20%20%20name%3A%20job-wq-1%5Cn%20%20%20%20spec%3A%5Cn%20%20%20%20%20%20containers%3A%5Cn%20%20%20%20%20%20-%20name%3A%20c%5Cn%20%20%20%20%20%20%20%20image%3A%20myrepo%2Fjob-wq-1%5Cn%20%20%20%20%20%20%20%20env%3A%5Cn%20%20%20%20%20%20%20%20-%20name%3A%20BROKER_URL%5Cn%20%20%20%20%20%20%20%20%20%20value%3A%20amqp%3A%2F%2Fguest%3Aguest%40rabbitmq-service%3A5672%5Cn%20%20%20%20%20%20%20%20-%20name%3A%20QUEUE%5Cn%20%20%20%20%20%20%20%20%20%20value%3A%20job1%5Cn%20%20%20%20%20%20restartPolicy%3A%20OnFailure%22%2C%22id%22%3A%221sTmM%22%7D" data-language="yaml"> <div class="cnblogs_code"> <pre>apiVersion: batch/<span style="color: rgba(0, 0, 0, 1)">v1 kind: Job metadata: name: job</span>-wq-<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)"> spec: completions: </span><span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)"> parallelism: </span><span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)"> template: metadata: name: job</span>-wq-<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)"> spec: containers: </span>-<span style="color: rgba(0, 0, 0, 1)"> name: c image: myrepo</span>/job-wq-<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)"> env: </span>-<span style="color: rgba(0, 0, 0, 1)"> name: BROKER_URL value: amqp:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">guest:guest@rabbitmq-service:5672</span> -<span style="color: rgba(0, 0, 0, 1)"> name: QUEUE value: job1 restartPolicy: OnFailure</span></pre> </div> </div> <p data-wording="true" data-lake-id="0f06421be4bc77f984f9101e4e2b59d5_p_45"><span style="font-family: "Microsoft YaHei"; font-size: 14px">上面的文件会以并发度为2的方式创建8个Pod,然后每个Pod各自去处理任务,我们最终只关心是否有8个Pod启动并且退出,只要这个目标达成,我们就认为这个Job成功执行。</span></p> <h3 id="HsdI8" data-wording="true" data-lake-id="60cb0760b83bcedf2404e31ab885e6af_h3_2"><span style="font-family: "Microsoft YaHei"; font-size: 14px">1.4.3、设置并行度,不设置固定值</span></h3> <p data-wording="true" data-lake-id="7374e53adeaa03ac468e797ec47e50b9_p_47"><span style="font-family: "Microsoft YaHei"; font-size: 14px">这种情况就必须自己决定什么时候启动Pod,什么时候执行完成,由于没有限制任务的总数,所以不仅需要一个工作队列来决定任务的分发,还需要能够判定工作队列是否为空,也就是任务是否完成。</span></p> <p data-wording="true" data-lake-id="6ffb34892d4e1a29737c64dcf5d32f05_p_48"><span style="font-family: "Microsoft YaHei"; font-size: 14px">如下:</span></p> <div data-card-type="block" data-lake-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22yaml%22%2C%22code%22%3A%22%5CnapiVersion%3A%20batch%2Fv1%5Cnkind%3A%20Job%5Cnmetadata%3A%5Cn%20%20name%3A%20job-wq-2%5Cnspec%3A%5Cn%20%20parallelism%3A%202%5Cn%20%20template%3A%5Cn%20%20%20%20metadata%3A%5Cn%20%20%20%20%20%20name%3A%20job-wq-2%5Cn%20%20%20%20spec%3A%5Cn%20%20%20%20%20%20containers%3A%5Cn%20%20%20%20%20%20-%20name%3A%20c%5Cn%20%20%20%20%20%20%20%20image%3A%20gcr.io%2Fmyproject%2Fjob-wq-2%5Cn%20%20%20%20%20%20%20%20env%3A%5Cn%20%20%20%20%20%20%20%20-%20name%3A%20BROKER_URL%5Cn%20%20%20%20%20%20%20%20%20%20value%3A%20amqp%3A%2F%2Fguest%3Aguest%40rabbitmq-service%3A5672%5Cn%20%20%20%20%20%20%20%20-%20name%3A%20QUEUE%5Cn%20%20%20%20%20%20%20%20%20%20value%3A%20job2%5Cn%20%20%20%20%20%20restartPolicy%3A%20OnFailure%22%2C%22id%22%3A%22dM7hi%22%7D" data-language="yaml"> <div class="cnblogs_code"> <pre>apiVersion: batch/<span style="color: rgba(0, 0, 0, 1)">v1 kind: Job metadata: name: job</span>-wq-<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)"> spec: parallelism: </span><span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)"> template: metadata: name: job</span>-wq-<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)"> spec: containers: </span>-<span style="color: rgba(0, 0, 0, 1)"> name: c image: gcr.io</span>/myproject/job-wq-<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)"> env: </span>-<span style="color: rgba(0, 0, 0, 1)"> name: BROKER_URL value: amqp:</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">guest:guest@rabbitmq-service:5672</span> -<span style="color: rgba(0, 0, 0, 1)"> name: QUEUE value: job2 restartPolicy: OnFailure</span></pre> </div> </div> <p data-wording="true" data-lake-id="2ef348a87ff832b114b7c39fd14dbac0_p_49"><span style="font-family: "Microsoft YaHei"; font-size: 14px">由于任务数不确定,所以每个Pod必须能够知道,自己什么时候可以退出。</span></p> <h2 id="MHXsO" data-wording="true" data-lake-id="b3953cb4520be2469064ec0754dfe65f_h1_1"><span style="font-family: "Microsoft YaHei"; font-size: 14px">2、CronJob</span></h2> <p data-wording="true" data-lake-id="cc4483d92d3cb8cf07391f52c68c6252_p_51"><span style="font-family: "Microsoft YaHei"; font-size: 14px">CronJob其实就在Job的基础上加了时间调度,类似于用Deployment管理Pod一样。它和我们Linux上的Crontab差不多。</span></p> <p data-wording="true" data-lake-id="057312afa179419c999ba8a064b47cbf_p_52"><span style="font-family: "Microsoft YaHei"; font-size: 14px">比如:</span></p> <div data-card-type="block" data-lake-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22yaml%22%2C%22code%22%3A%22%5CnapiVersion%3A%20batch%2Fv1beta1%5Cnkind%3A%20CronJob%5Cnmetadata%3A%5Cn%20%20name%3A%20hello%5Cnspec%3A%5Cn%20%20schedule%3A%20%5C%22*%2F1%20*%20*%20*%20*%5C%22%5Cn%20%20jobTemplate%3A%5Cn%20%20%20%20spec%3A%5Cn%20%20%20%20%20%20template%3A%5Cn%20%20%20%20%20%20%20%20spec%3A%5Cn%20%20%20%20%20%20%20%20%20%20containers%3A%5Cn%20%20%20%20%20%20%20%20%20%20-%20name%3A%20hello%5Cn%20%20%20%20%20%20%20%20%20%20%20%20image%3A%20busybox%5Cn%20%20%20%20%20%20%20%20%20%20%20%20command%3A%5Cn%20%20%20%20%20%20%20%20%20%20%20%20-%20%5C%22%2Fbin%2Fsh%5C%22%5Cn%20%20%20%20%20%20%20%20%20%20%20%20-%20%5C%22-c%5C%22%5Cn%20%20%20%20%20%20%20%20%20%20%20%20args%3A%5Cn%20%20%20%20%20%20%20%20%20%20%20%20-%20%5C%22for%20i%20in%20%24(seq%2010)%3B%20do%20echo%20%24i%3B%20done%5C%22%5Cn%20%20%20%20%20%20%20%20%20%20restartPolicy%3A%20OnFailure%22%2C%22id%22%3A%22MhrXR%22%7D" data-language="yaml"> <div class="cnblogs_code"> <pre>apiVersion: batch/<span style="color: rgba(0, 0, 0, 1)">v1beta1 kind: CronJob metadata: name: hello spec: schedule: </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">*/1 * * * *</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)"> jobTemplate: spec: template: spec: containers: </span>-<span style="color: rgba(0, 0, 0, 1)"> name: hello image: busybox command: </span>- <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/bin/sh</span><span style="color: rgba(128, 0, 0, 1)">"</span> - <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">-c</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)"> args: </span>- <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">for i in $(seq 10); do echo $i; done</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)"> restartPolicy: OnFailure</span></pre> </div> <p><span style="font-family: "Microsoft YaHei"">我们可以看到spec里其实就是一个Job Template。另外其schedule就是一个便准的Cron格式,</span></p> </div> <div data-card-type="block" data-lake-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22yaml%22%2C%22code%22%3A%22%E5%88%86%E9%92%9F%20%20%20%E5%B0%8F%E6%97%B6%20%20%20%20%E6%97%A5%20%20%20%20%E6%9C%88%20%20%20%20%E6%98%9F%E6%9C%9F%5Cn*%20%20%20%20%20%20*%20%20%20%20%20%20*%20%20%20%20%20*%20%20%20%20%20%20*%22%2C%22id%22%3A%22pqD1L%22%7D" data-language="yaml"> <div> <div> <pre><span style="font-family: "Microsoft YaHei"; font-size: 14px">分钟 小时 日 月 星期 * * * * *</span></pre> </div> </div> </div> <p data-wording="true" data-lake-id="bc63564d6a448e6a61712ab0355e06df_p_56"><span style="font-family: "Microsoft YaHei"; font-size: 14px">我们创建上面的YAML文件。查看器结果:</span></p> <div data-card-type="block" data-lake-card="codeblock" data-card-value="data:%7B%22mode%22%3A%22yaml%22%2C%22code%22%3A%22%5Broot%40master%20job%5D%23%20kubectl%20apply%20-f%20cronjob-demo.yaml%20%5Cncronjob.batch%2Fhello%20created%5Cn%5Broot%40master%20job%5D%23%20kubectl%20get%20cronjobs.batch%20%5CnNAME%20%20%20%20SCHEDULE%20%20%20%20%20%20SUSPEND%20%20%20ACTIVE%20%20%20LAST%20SCHEDULE%20%20%20AGE%5Cnhello%20%20%20*%2F1%20*%20*%20*%20*%20%20%20False%20%20%20%20%200%20%20%20%20%20%20%20%20%3Cnone%3E%20%20%20%20%20%20%20%20%20%205s%22%2C%22id%22%3A%22Lwe03%22%7D" data-language="yaml"> <div class="cnblogs_code"> <pre>[root@master job]# kubectl apply -f cronjob-<span style="color: rgba(0, 0, 0, 1)">demo.yaml cronjob.batch</span>/<span style="color: rgba(0, 0, 0, 1)">hello created [root@master job]# kubectl </span><span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)"> cronjobs.batch NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE hello </span>*/<span style="color: rgba(128, 0, 128, 1)">1</span> * * * * False <span style="color: rgba(128, 0, 128, 1)">0</span> <none> 5s</pre> </div> <p><span style="font-family: "Microsoft YaHei"">需要注意的是,由于cron的特殊性,有时候会存在由于上一个定时任务还没有执行完成,新的定时任务又开始了的情况,我们可以通过定义spec.concurrencyPolicy字段来定义规则,比如:</span></p> </div> <ul> <li data-wording="true" data-lake-id="50c8621d40bc2b72a1d184b1bfa8410d_li_2"><span style="font-family: "Microsoft YaHei"; font-size: 14px">concurrencyPolicy=Allow:表示这些Job可以同时存在</span></li> <li data-wording="true" data-lake-id="822d6e0e7860c39275eb21e7a43dbbe9_li_3"><span style="font-family: "Microsoft YaHei"; font-size: 14px">concurrencyPolicy=Firbid:表示不会创建新的Job,也就是这个定时任务被跳过</span></li> <li data-wording="true" data-lake-id="98cf0c1fefb9ce86e9b5423cfee5e90a_li_4"><span style="font-family: "Microsoft YaHei"; font-size: 14px">concurrencyPolicy=Replace:表示产生的新Job会替代旧的Job</span></li> </ul> <p data-wording="true" data-lake-id="29c697498e59f033a3cb1c865d3486f1_p_59"><span style="font-family: "Microsoft YaHei"; font-size: 14px">如果某一个Job创建失败,那么这次创建就会被标记为miss,当在指定的时间窗口内,Miss的数达到100,那么CronJob就会停止再创建这个Job。这个时间窗口可以通过spec.startingDeadlineSeconds来指定。</span></p> </div> </div> </div> </span> </li> <li class="list-group-item ul-li"> <b>相关阅读:</b><br> <nobr> <a href="aimei-p-12192692.html" target="_blank">linux常用命令</a> <br/><a href="MrHSR-p-9300075.html" target="_blank">mysql 开发基础系列20 事务控制和锁定语句(上)</a> <br/><a href="MrHSR-p-9285983.html" target="_blank">sql server 性能调优之 资源等待 CXPACKET</a> <br/><a href="MrHSR-p-9297960.html" target="_blank">mysql 开发基础系列19 触发器</a> <br/><a href="MrHSR-p-9293744.html" target="_blank">mysql 开发基础系列18 存储过程和函数(下)</a> <br/><a href="MrHSR-p-9289853.html" target="_blank">mysql 开发基础系列17 存储过程和函数(上)</a> <br/><a href="MrHSR-p-9287226.html" target="_blank">sql server 性能调优之 资源等待PAGEIOLATCH</a> <br/><a href="MrHSR-p-9284756.html" target="_blank">mysql 开发基础系列16 视图</a> <br/><a href="MrHSR-p-9283647.html" target="_blank">mysql 开发基础系列15 索引的设计和使用</a> <br/><a href="MrHSR-p-9156452.html" target="_blank">sql server 性能调优之 当前用户请求分析 (1)</a> <br/> </nobr> </li> <li class="list-group-item from-a mb-2"> 原文地址:https://www.cnblogs.com/liang-io/p/14096428.html </li> </ul> </div> <!-- 右侧开始 --> <div class="col-lg-4 col-sm-12"> <ul class="list-group" style="word-break:break-all;"> <li class="list-group-item ul-li-bg" aria-current="true"> 最新文章 </li> <li class="list-group-item ul-li"> <nobr> <a href="eternityz-p-12238904.html" target="_blank">Java遍历Map对象的四种方式</a> <br/><a href="chenyingying0-p-12527950.html" target="_blank">Swiper快速切换插件</a> <br/><a href="chenyingying0-p-12523953.html" target="_blank">video动态设置宽高</a> <br/><a href="chenyingying0-p-12523665.html" target="_blank">kindeditor编辑器,视频不显示,视频格式embed改成video</a> <br/><a href="chenyingying0-p-12520784.html" target="_blank">zepto中的动画+Ajax+touch模块+zepto插件</a> <br/><a href="chenyingying0-p-12517547.html" target="_blank">phpAdmin数据导出成excel,解决乱码,分列问题</a> <br/><a href="chenyingying0-p-12517224.html" target="_blank">zepto中的事件</a> <br/><a href="chenyingying0-p-12516186.html" target="_blank">zepto中的DOM操作</a> <br/><a href="chenyingying0-p-12513955.html" target="_blank">zepto选择器</a> <br/><a href="chenyingying0-p-12511552.html" target="_blank">移动端性能优化(JavaScript性能优化)</a> <br/> </nobr> </li> </ul> <ul class="list-group pt-2" style="word-break:break-all;"> <li class="list-group-item ul-li-bg" aria-current="true"> 热门文章 </li> <li class="list-group-item ul-li"> <nobr> <a href="chenyingying0-p-12510986.html" target="_blank">移动端性能优化(CSS性能优化)</a> <br/><a href="aimei-p-12192810.html" target="_blank">Docker的安装和操作(虚拟机+linux系统)</a> <br/><a href="aimei-p-12192804.html" target="_blank">linux命令安装docker</a> <br/><a href="aimei-p-12192792.html" target="_blank">centos7 防火墙的操作</a> <br/><a href="aimei-p-12192773.html" target="_blank">四、CentOS 7安装Oracle JDK</a> <br/><a href="aimei-p-12192738.html" target="_blank">三、linux环境的搭建1(oracle、ssh、jdk、mysql、samba、tomcat)</a> <br/><a href="aimei-p-12192732.html" target="_blank">二、vim的保存文件和退出命令</a> <br/><a href="aimei-p-12192720.html" target="_blank">Centos7更改网卡名称Eth0</a> <br/><a href="aimei-p-12192711.html" target="_blank">Linux文件编辑命令详细整理</a> <br/><a href="aimei-p-12192702.html" target="_blank">Centos7开放及查看端口</a> <br/> </nobr> </li> </ul> </div> </div> </div> <!-- 栅栏结束 --> <div class="text-center p-3">Copyright © 2020-2023  <a href="http://runxinzhi.com" target="_blank">润新知</a> <!-- 引入底部 --> <!-- 底部开始 --> <!-- 百度自动推送js --> <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> <!-- 百度自动推送js --> <!-- 底部结束 --> </div> <script src="https://common.cnblogs.com/scripts/jquery-2.2.0.min.js"></script> <script src="https://www.cnblogs.com/js/blog-common.min.js"></script> <script src="http://common.cnblogs.com/script/encoder.js"></script> <!-- <script src="/public/js/blog-common.min.js"></script> --> <!-- <script src="/public/js/details.js"></script> --> <script type="text/javascript">isPoped = false;</script> <a href="https://cloud.tencent.com/act/cps/redirect?redirect=2446&cps_key=87a18266a36636885bbb685e9a6481aa&from=console" id="redirect_url"></a> <a href="/liang-io-p-14096428.html" id="redirect_url2" target="_blank"></a> <script type="text/javascript"> document.onclick = function() { if (!isPoped) { document.getElementById("redirect_url").click(); document.getElementById("redirect_url2").click(); isPoped = true; } } </script> </body> </html>