Kubernetes系列12 一 Job 与 CronJob

网友投稿 870 2022-10-13

本站部分文章、图片属于网络上可搜索到的公开信息,均用于学习和交流用途,不能代表睿象云的观点、立场或意见。我们接受网民的监督,如发现任何违法内容或侵犯了您的权益,请第一时间联系小编邮箱jiasou666@gmail.com 处理。

Kubernetes系列12 一 Job 与 CronJob

通过前面的文章大家已经对 Kubernetes 的控制对象的能力都有所了解了。

Deployment:控制无状态服务应用,例如大多数的Web服务;StatefulSet:控制有状态服务应用,例如Mysql等有主从节点等拓扑结构的服务;DaemonSet:控制在每个Node上有且仅运行单个实例的应用,例如日志采集、监控等服务。

这些被控制的对象都有个共同点,都是一直处于Running状态的服务。而在生产实践中也存在着大量的离线应用场景,例如执行一次就退出的脚本,或者是周期性执行的脚本,可以称这类应用为离线业务。Kubernetes 通过Job、CronJob 来实现离线业务应用场景。

首先我么看一个 Job 的定义yaml文件:

apiVersion: batch/v1kind: Jobmetadata: name: job-examplespec: template: spec: containers: - name: job-example image: alpine:latest        command: ["sh", "-c", "echo Job is Running && sleep 10"] restartPolicy: Never backoffLimit: 4  activeDeadlineSeconds: 60  parallelism: 2   completions: 4

到现在,大家对 spec.template 部分是非常的熟悉了,是 Kubernetes 的最小调度单位 Pod 的定义。而在示例中我们使用的是一个linux的最小镜像alpine(常作为运行Go应用等无其他依赖的基础镜像),而容器运行起来会输出 Job is Running,同时 sleep 10秒后,容器进程退出。

通过 kubectl get pods 命令可以看到 该 Pod 在Running状态后会变成 Completed 状态:

kubectl get podsNAME READY STATUS RESTARTS AGEjob-example-th9jc 0/1 Completed 0 107s

在容器进程运行的时候是Running状态,当执行完sleep 10命令后容器进程退出。我们可以查看该 Pod 的日志查看容器输出:

kubectl logs job-example-th9jcJob is Running

通过 kubectl describe jobs/job-example 命令可以查看Job的详情:

kubectl describe jobs/job-exampleName: job-exampleNamespace: defaultSelector: controller-uid=f27533fa-3196-492a-af08-2c04c21ba642Labels: controller-uid=f27533fa-3196-492a-af08-2c04c21ba642 job-name=job-exampleAnnotations: Parallelism: 1Completions: 1Start Time: Sat, 19 Jun 2021 14:19:12 +0800Completed At: Sat, 19 Jun 2021 14:19:49 +0800Duration: 37sPods Statuses: 0 Running 1 Succeeded 0 FailedPod Template: Labels: controller-uid=f27533fa-3196-492a-af08-2c04c21ba642 job-name=job-example Containers: job-example: Image: alpine:latest Port: Host Port: Command: sh -c echo Job is Running && sleep 10 Environment: Mounts: Volumes: Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulCreate 40s job-controller Created pod: job-example-th9jc

可以看到在 Job 对象被创建后,Pod会被自动加上一个带有uid的label controller-uid=xxxxxx,而当前Job会带有一个Selector来保证当前Job与Pod的关系,避免了不同的Job管理了相同的Pod。

我们再回过头来看看 Job 的定义文件中的字段。

其中 restartPolicy=Never,表示Pod 正常退出后不再重启,实际上Job也不应该在正常退出后被重启,所以 Job 的restartPolicy只能设置为Never或者Onfailure。

而 Never 和 Onfailure 表示在Pod的容器如果是异常退出后的处理不同。Never 表示会不断地重新创建 Pod,Onfailure 则不会创建新的 Pod,只会不停的重启 Pod 里的容器。

但是Never 状态下也不会是无限的重启Pod,默认重试6次,可以通过backoffLimit 来指定重试次数,示例中定义的 backoffLimit 为4。Job重启Pod的时间间隔是指数增长的,10s、20s、40s ......

spec.activeDeadlineSeconds 则是用来设置容器的最长运行时间的。当Job管理的Pod容器运行的脚本逻辑出现异常,一直卡着导致Pod一直无法为Completed状态时,一旦超过了 activeDeadlineSeconds定义的时间,当前Job管理的Pod会被终止,且 Events 中可以看到 Reason 为 DeadlineExceeded。

spec.parallelism控制Job 当前并行运行的Pod数量,spec.completions 控制Job需要完成的Pod数量。在示例中需要执行4次Pod且有2个Pod并行执行。Job管理并行运行Pod数和总数的过程与Pod的滚动升级策略是一样的,详情可以见Kubernetes系列9 一 终于聊到编排了。

但是在我们的生产实践中CronJob是最为常见的,通过名字就能猜想到其与Linux的Cron Job类似,提供周期性执行任务的能力。

我们将上述yaml案例改造为一个每分钟执行一次的Cron Job:

apiVersion: batch/v1beta1kind: CronJobmetadata:  name: cronjob-examplespec: schedule: "*/1 * * * *"  concurrencyPolicy: Allow  startingDeadlineSeconds: 7200 jobTemplate: spec:      template: containers: - name: cronjob-example image: alpine:latest command: ["sh", "-c", "echo Job is Running && sleep 10"] restartPolicy: Never backoffLimit: 4

其中JobTemplate.spec.template 正是一个Pod 的定义与Job的 spec.template 对应。说明CronJob同Deployment、StatefulSet、DaemonSet是一类,都是控制器对象。而CronJob直接管理的对象是Job,即Job 的 ownerReference 为CronJob。这与 RelicaSet 同 Deployment 的关系是一样的。

CronJob的 spec.schedule 与linux cron命令语法是一致的,不了解的同学可以自行查阅资料。

我们还需要注意 spec.concurrencyPolicy 定义,定时任务难免会出现上一次任务还未结束,而到达当前任务执行时间的场景。concurrencyPolicy有如下三种类型:

Allow:表示不同周期的任务可以同时存在,这也是concurrency的默认值;Forbid:表示上一周期的任务未退出则不会创建新的Pod,当前周期会被跳过;Replacy:表示用新的周期任务代换上一周期任务。

spec.startingDeadlineSeconds 表示在多长滑动窗口时间内,如果Job创建失败的次数达到100(这个100是kubernetes源码里写死的)则不再创建Pod,案例中为2小时内错误数达到100次则不再执行 Job任务。

本系列回顾:

Kubernetes系列1 一 容器是什么?

Kubernetes系列2 一 小鲸鱼与船长的历险记

Kubernetes系列3 一 docker隔离与限制的原理

Kubernetes系列4 一 docker镜像

Kubernetes系列5 一 实践课

Kubernetes系列6 一 Kubernetes登场

Kubernetes系列7 一 最小编排单位Pod

Kubernetes系列8 一 Pod的生命周期

Kubernetes系列9 一 终于聊到编排了

Kubernetes系列10 一 容器编排之StatefulSet

Kubernetes系列11 一 容器编排之DaemonSet

上一篇:MySQL Binlog 技术原理和业务应用案例分析
下一篇:Nginx下关于缓存控制字段cache-control的配置说明 - 运维小结
相关文章

 发表评论

暂时没有评论,来抢沙发吧~