如何停止掉正在运行的ds job_kubernete编排技术四:Job和CronJob

8ec232df59fa05b8aed57322452a9c84.png

这篇文章我们学习一下kubernete对Job的编排。不同于前面讲的Deployment、StatefulSet的编排,Job是一个执行一次就结束的pod,并不会滚动更新。

Job

定义job非常简单,只要在yaml文件中把kind字段定义成Job就可以了。如下kubejob.yaml:

apiVersion: batch/v1kind: Jobmetadata:  name: kubejobspec:  parallelism: 2  completions: 4  template:    spec:      containers:      - name: myjob        image: zjj2006forever/kubejob:1.0        imagePullPolicy: IfNotPresent      restartPolicy: Never  backoffLimit: 4  activeDeadlineSeconds: 600

这个yaml文件中,我们定义了如下几个重要的参数:

restartPolicy:重启策略,这儿我们定义是Never,就是如果任务失败后不会重启,而是会创建一个新pod出来,直到创建次数超过了backoffLimit。如果设置成OnFailure,则失败后不会重新创建pod而是会重启。

backoffLimit:默认是6,我们定义失败次数是4

activeDeadlineSeconds:控制pod重新创建时间,防止失败后无限制的重新创建,Job运行结束后就会进入Completed状态,如果Job一直没有执行成功,就会反复地重新创建,直到时间超过activeDeadlineSeconds的值,上面我设置了600s如果Job在600s后还没有完成,那就会结束。

parallelism:任务并行度,上面设置是2个,这样就会生成2个pod并行执行

completions:期望有多少个pod执行完成后整个任务结束,上面设置是4

注意:上面的Job中,需要创建pod的数量 = 期望总共完成的pod数量(completions参数) - Completed状态的pod数量(已完成) - running状态的pod数量(运行中)

下面我们写一段java代码,这段代码很简单,每隔12s一次依次输出0到9的数,我把它打成一个镜像,提交到我的dockerhub,名称:zjj2006forever/kubejob:1.0

public class JobTest {    public static void main(String[] args) throws InterruptedException {        for (int i = 0; i < 10; i++){            System.out.println(i);            Thread.sleep(12000);        }    }}

上面的镜像打包好后,执行如下命令创建Job

[root@master kubejob]# kubectl create -f kubejob.yaml job.batch/kubejob created

这时我们看一下Job的描述

[root@master kubejob]# kubectl describe jobs/kubejobName:                     kubejobNamespace:                defaultSelector:                 controller-uid=190e811d-4d89-4d1d-9911-144499413c3aLabels:                   controller-uid=190e811d-4d89-4d1d-9911-144499413c3a                          job-name=kubejobAnnotations:              Parallelism:              2Completions:              4Start Time:               Thu, 30 Jul 2020 07:14:53 -0400Active Deadline Seconds:  600sPods Statuses:            2 Running / 0 Succeeded / 0 FailedPod Template:  Labels:  controller-uid=190e811d-4d89-4d1d-9911-144499413c3a           job-name=kubejob  Containers:   myjob:    Image:        zjj2006forever/kubejob:1.0    Port:             Host Port:        Environment:      Mounts:         Volumes:        Events:  Type    Reason            Age   From            Message  ----    ------            ----  ----            -------  Normal  SuccessfulCreate  105s  job-controller  Created pod: kubejob-vxgzg  Normal  SuccessfulCreate  105s  job-controller  Created pod: kubejob-tbgqj

上面的输出我要说明一下,我们看到有一个Selector,是给了controller一个uid,这个uid的作用是匹配job和它管理的pod的对应关系,也就是通过这个uid,Job才可以管理它创建的pod。

然后查看pod数量,2个pod都已经进入了running状态。

[root@master kubejob]# kubectl get podsNAME            READY   STATUS    RESTARTS   AGEkubejob-tbgqj   1/1     Running   0          5skubejob-vxgzg   1/1     Running   0          5s

上面的输出我们看到当前有2个pod正在并行执行,4分钟以后,我们查看所有的pod,都已经完成

[root@master kubejob]# kubectl get podsNAME            READY   STATUS      RESTARTS   AGEkubejob-fnx6b   0/1     Completed   0          3m9skubejob-tbgqj   0/1     Completed   0          5m13skubejob-vxgzg   0/1     Completed   0          5m13skubejob-w7zlb   0/1     Completed   0          3m9s

而我们这时再查看pod的状态,COMPLETIONS说明期望4个任务都已经完成

[root@master kubejob]# kubectl get JobNAME      COMPLETIONS   DURATION   AGEkubejob   4/4           4m8s       19m

我们查看其中一个pod的日志,输出正确,如下图:

[root@master kubejob]# kubectl logs kubejob-fnx6b0123456789

CronJob

从名字中我们也可以看出,这是一个定时任务控制器,事实上,它也是用标准的Unix cron表达式来控制任务的执行。它的定义也非常简单,把kind定义成CronJob。我们先定义一个yaml文件cronjob.yaml如下:

apiVersion: batch/v1beta1kind: CronJobmetadata:  name: mycronjobspec:  schedule: "*/1 * * * *"  jobTemplate:    spec:      template:        spec:          containers:          - name: mycronjob            image: zjj2006forever/kubejob:1.0            imagePullPolicy: IfNotPresent          restartPolicy: OnFailure  concurrencyPolicy: Replace

从上面的yaml定义中我们看到有一个jobTemplate属性,他是一个job的模板,用来控制Job对象。所以,CronJob其实是一个Job对象的控制器。还记得之前文章《kubernete编排技术二:deployment》中用deployment来控制ReplicaSet对象吗,其实是一个道理。

CronJob对Job的控制,是通过参数schedule来进行的,这个参数的表达式就跟我们在linux下创建定时任务配置的cron时间格式一样。

这儿要注意,我上面定义的cron表达式是每分钟执行一次,但是上面我写的java应用是每2分钟才能执行,那是不是会有时间段内同时存在2个任务呢?

我们可以用这个字段来控制spec.concurrencyPolicy,它有3个属性值:默认是Allow,允许job同时存在;Forbid表示上一个任务没有执行完成这个任务不允许创建;Replace表示新产生的任务pod会替换掉旧的。

接下来我们创建这个CronJob,执行下面命令:

kubectl create -f cronjob.yaml

查看创建的任务:

[root@master kubejob]# kubectl get CronJobNAME        SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGEmycronjob   */1 * * * *   False     1        21s             4m14s

再看一下pod和日志打印:

[root@master kubejob]# kubectl get podsNAME                         READY   STATUS    RESTARTS   AGEmycronjob-1596280800-9xnpm   1/1     Running   0          52s[root@master kubejob]# kubectl logs mycronjob-1596280800-9xnpm01234

这时我们看到其中一个pod打印出5个数之后(用了一分钟),就消失了,出现了新的Pod,这也印证了我们yaml文件中的spec.concurrencyPolicy=Replace

[root@master kubejob]# kubectl logs mycronjob-1596280800-9xnpmError from server (NotFound): pods "mycronjob-1596280800-9xnpm" not found

下面的输出我们还看到了pod被Replace的过程

[root@master kubejob]# kubectl get podsNAME                         READY   STATUS              RESTARTS   AGEmycronjob-1596280920-2vlhr   1/1     Terminating         0          60smycronjob-1596280980-gvqqd   0/1     ContainerCreating   0          0s[root@master kubejob]# kubectl get podsNAME                         READY   STATUS    RESTARTS   AGEmycronjob-1596280980-gvqqd   1/1     Running   0          14s

最后说明一下,如果一个Job创建失败,这个Job就标记为miss,一旦指定时间内miss次数达到100,CronJob会停止再创建这个Job。这个时间可以由spec.startingDeadlineSeconds参数指定,单位是s。这里我就不再实验了。

总结

相对于之前讲的编排技术,Job和CronJob是相对比较简单一种的编排技术,但是也非常重要,包括怎么控制并发任务(parallelism),怎么控制完成数量(completions),还有定时任务配置(schedule)。这些对kubernete中的应用起了很好的支持。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值