为什么Delete表数据,磁盘空间却还是被占用
870
2022-10-13
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:
可以看到在 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
发表评论
暂时没有评论,来抢沙发吧~