kubernetes Job讲解 电脑版发表于:2021/3/3 18:32  >#kubernetes Job讲解 [TOC] 需求来源 ------------ ### Job 背景问题 <p style=" font-weight: 400; line-height: 1.5; color: #212529; -webkit-tap-highlight-color: transparent; box-sizing: border-box; padding: 0px 20px 20px 20px; border: 1px solid #e9ecef; border-left-width: .25rem; border-radius: .25rem; display: block; border-left-color: #5bc0de;"> 我们可以通过Pod来直接运行任务进程吗? 这样做将会产生以下几种问题: 1. 我们如何保证 Pod 内进程正确的结束? 2. 如何保证进程运行失败后重试? 3. 如何管理多个任务,且任务之间有依赖关系? 4. 如何并行地运行任务,并管理任务的队列大小?</div> </p> ### Job 管理任务的控制器 <p style=" font-weight: 400; line-height: 1.5; color: #212529; -webkit-tap-highlight-color: transparent; box-sizing: border-box; padding: 0px 20px 20px 20px; border: 1px solid #e9ecef; border-left-width: .25rem; border-radius: .25rem; border-left-color: #5bc0de;"> Job 能帮我们做什么事情? 1. 创建一个或多个Pod确保指定数量的Pod可以成功地运行终止 2. 跟踪Pod状态,根据配置及时重试失败的pod 3. 确定依赖关系,保证上一个任务运行完毕后再运行下一个任务 4. 控制任务并行度,并根据配置确保Pod队列大小 </p> 用例解读 ------------ ### Job语法 <p style=" font-weight: 400; line-height: 1.5; color: #212529; -webkit-tap-highlight-color: transparent; box-sizing: border-box; padding: 0px 20px 20px 20px; border: 1px solid #e9ecef; border-left-width: .25rem; border-radius: .25rem; border-left-color: #5bc0de;"> 新属性: - **restartPolicy: 重启策略** (值有Always, OnFailure,Never。 默认是 Always。) - **backoffLimit: 重试次数限制** </p> <br/> 举例(job.yaml): ```yaml apiVersion: batch/v1 kind: Job metadata: name: pi spec: template: spec: containers: - name: pi image: perl command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] restartPolicy: Never backoffLimit: 4 ``` >job类型以及元信息: ```yaml kind: Job metadata: name: pi ``` tn>镜像建议提前下载好 ### 查看job状态  <p style=" font-weight: 400; line-height: 1; color: #212529; -webkit-tap-highlight-color: transparent; box-sizing: border-box; padding: 0px 0px 0px 20px; border: 1px solid #e9ecef; border-left-width: .25rem; border-radius: .25rem; border-left-color: #5bc0de;"> - **COMPLETIONS: 完成pod数量** - **DURATION: Job实际业务运行时长** - **AGE: deployment创建的时长** </p> ### 查看Pod ```yaml # kubectl get pod NAME READY STATUS RESTARTS AGE pi-w7gfb 0/1 Completed 0 25m ``` <p style=" font-weight: 400; line-height: 1; color: #212529; -webkit-tap-highlight-color: transparent; box-sizing: border-box; padding: 0px 0px 0px 20px; border: 1px solid #e9ecef; border-left-width: .25rem; border-radius: .25rem; border-left-color: #5bc0de;"> Pod 名称格式: `${job-name}-${random-suffix}` Completed 表示已经执行完了 labels均为自动匹配与添加 - **ownerReferences:声明此pod是归哪个上一层controller来管理** </p> <br/>  ### 并行运行Job <p style=" font-weight: 400; line-height: 1; color: #212529; -webkit-tap-highlight-color: transparent; box-sizing: border-box; padding: 0px 0px 0px 20px; border: 1px solid #e9ecef; border-left-width: .25rem; border-radius: .25rem; border-left-color: #5bc0de;"> 我们有时候希望Job运行的时候可以最大化的并行,并行出n个Pod去快速地执行。同时,由于我们的节点数有限制,可以也不希望同时并行的Pod数过多,有那么一个管道的概念,我们可以希望最大的并行度是多少,Job控制器都可以帮我们做到。请参考下面的示例(parallel-job.yaml) </p> <br/> ```yaml apiVersion: batch/v1 kind: Job metadata: name: paral-1 spec: completions: 8 parallelism: 2 template: spec: containers: - name: param image: alpine:latest command: ["/bin/sh"] args: ["-c", "sleep 30; date"] restartPolicy: OnFailure ``` <p style=" font-weight: 400; line-height: 1; color: #212529; -webkit-tap-highlight-color: transparent; box-sizing: border-box; padding: 0px 0px 0px 20px; border: 1px solid #e9ecef; border-left-width: .25rem; border-radius: .25rem; border-left-color: #5bc0de;"> - **completions: 代表本pod队列执行次数,这里8代表中国任务将会被执行8次** - **parallelism: 代表并行执行个数,这里2代表并行执行的pod数量,也就是说会有2个pod同时运行** 我们通过让它的每个pod都催眠30秒,来进行观察。 </p> ### 查看并行Job运行  ### CronJob与Job的不同 <p style=" font-weight: 400; line-height: 1; color: #212529; -webkit-tap-highlight-color: transparent; box-sizing: border-box; padding: 0px 0px 0px 20px; border: 1px solid #e9ecef; border-left-width: .25rem; border-radius: .25rem; border-left-color: #5bc0de;"> 它们之间最大的不同在于周期性任务作业计划 - <text style="color:green;font-weight:bold">在未来某时间点运行作业一次</text> - <text style="color:green;font-weight:bold">在指定的时间点重复运行作业</text> </p> ### CronJob语法 | 属性 | 描述 | | ------------ | ------------ | | jobTemplate | Job控制器的模板,用于为CronJob控制器生成的Job对象 | | schedule | crontab 时间格式相同 | | startingDeadlineSeconds | Job最长启动时间 | | concurrencyPolicy | 是否允许并行运行 | | successfulJobsHistoryLimit | 运行留存历史job个数 | Demo-CronJob.yaml ```yaml apiVersion: batch/v1beta1 kind: CronJob metadata: name: hello spec: schedule: "*/1 * * * *" jobTemplate: spec: template: spec: containers: - name: hello image: busybox imagePullPolicy: IfNotPresent args: - /bin/sh - -c - date; echo Hello from the Kubernetes cluster restartPolicy: OnFailure startingDeadlineSeconds: 10 concurrencyPolicy: Allow successfulJobsHistoryLimit: 3 ``` tn>在准备运行之前很有必要说一下`schedule`设置时间的格式,上面的yaml是每分钟执行一下,这里我截了官方的一张图,并制作了一个表格提供参考。要生成CronJob调度表达式,您还可以使用诸如<a href="https://crontab.guru/">crontab.guru</a>之类的Web工具。  | 举例 | 定义 | | ------------ | ------------ | | 每年1月1日午夜运行一次 | 0 0 1 1 * | | 每月在每月第一天的午夜运行一次 | 0 0 1 * * | | 每周一在周日上午的午夜运行一次 | 0 0 * * 0 | | 每天半夜运行一次 | 0 0 * * * | | 每小时开始一次,每小时运行一次 | 0 * * * * | | 每个星期五的午夜以及每个月的13日的午夜开始任务 | 0 0 13 * 5 | ### 运行测试   架构设计 ------------ ### 管理模式 <p style=" font-weight: 400; line-height: 1; color: #212529; -webkit-tap-highlight-color: transparent; box-sizing: border-box; padding: 0px 0px 0px 20px; border: 1px solid #e9ecef; border-left-width: .25rem; border-radius: .25rem; border-left-color: #5bc0de;"> 1. Job Controller 负责根据配置创建Pod 2. Job Controller 跟踪Job状态,根据配置及时重试Pod或者继续创建 3. Job Controller 会自动添加label来跟踪对应的pod,并根据配置并行或者串行创建pod </p>  ### Job控制器  <p style=" font-weight: 400; line-height: 1; color: #212529; -webkit-tap-highlight-color: transparent; box-sizing: border-box; padding: 0px 0px 0px 20px; border: 1px solid #e9ecef; border-left-width: .25rem; border-radius: .25rem; border-left-color: #5bc0de;"> 上图是一个 Job 控制器的主要流程。所有的 job 都是一个 controller,它会 watch 这个 API Server,我们每次提交一个 Job 的 yaml 都会经过 api-server 传到 ETCD 里面去,然后 Job Controller 会注册几个 Handler,每当有添加、更新、删除等操作的时候,它会通过一个内存级的消息队列,发到 controller 里面。 通过 Job Controller 检查当前是否有运行的 pod,如果没有的话,通过 Scale up 把这个 pod 创建出来;如果有的话,或者如果大于这个数,对它进行 Scale down,如果这时 pod 发生了变化,需要及时 Update 它的状态。 同时要去检查它是否是并行的 job,或者是串行的 job,根据设置的配置并行度、串行度,及时地把 pod 的数量给创建出来。最后,它会把 job 的整个的状态更新到 API Server 里面去,这样我们就能看到呈现出来的最终效果了。 </p>