
kubernetes Job讲解
需求来源
Job 背景问题
我们可以通过Pod来直接运行任务进程吗?
这样做将会产生以下几种问题:
1. 我们如何保证 Pod 内进程正确的结束?
2. 如何保证进程运行失败后重试?
3. 如何管理多个任务,且任务之间有依赖关系?
4. 如何并行地运行任务,并管理任务的队列大小?
Job 管理任务的控制器
Job 能帮我们做什么事情?
1. 创建一个或多个Pod确保指定数量的Pod可以成功地运行终止
2. 跟踪Pod状态,根据配置及时重试失败的pod
3. 确定依赖关系,保证上一个任务运行完毕后再运行下一个任务
4. 控制任务并行度,并根据配置确保Pod队列大小
用例解读
Job语法
新属性:
- restartPolicy: 重启策略
(值有Always, OnFailure,Never。 默认是 Always。)
- backoffLimit: 重试次数限制
举例(job.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类型以及元信息:
kind: Job
metadata:
name: pi
镜像建议提前下载好
查看job状态
- COMPLETIONS: 完成pod数量
- DURATION: Job实际业务运行时长
- AGE: deployment创建的时长
查看Pod
# kubectl get pod
NAME READY STATUS RESTARTS AGE
pi-w7gfb 0/1 Completed 0 25m
Pod 名称格式: ${job-name}-${random-suffix}
Completed 表示已经执行完了
labels均为自动匹配与添加
- ownerReferences:声明此pod是归哪个上一层controller来管理
并行运行Job
我们有时候希望Job运行的时候可以最大化的并行,并行出n个Pod去快速地执行。同时,由于我们的节点数有限制,可以也不希望同时并行的Pod数过多,有那么一个管道的概念,我们可以希望最大的并行度是多少,Job控制器都可以帮我们做到。请参考下面的示例(parallel-job.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
- completions: 代表本pod队列执行次数,这里8代表中国任务将会被执行8次
- parallelism: 代表并行执行个数,这里2代表并行执行的pod数量,也就是说会有2个pod同时运行
我们通过让它的每个pod都催眠30秒,来进行观察。
查看并行Job运行
CronJob与Job的不同
它们之间最大的不同在于周期性任务作业计划
-
-
CronJob语法
属性 | 描述 |
---|---|
jobTemplate | Job控制器的模板,用于为CronJob控制器生成的Job对象 |
schedule | crontab 时间格式相同 |
startingDeadlineSeconds | Job最长启动时间 |
concurrencyPolicy | 是否允许并行运行 |
successfulJobsHistoryLimit | 运行留存历史job个数 |
Demo-CronJob.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
在准备运行之前很有必要说一下schedule
设置时间的格式,上面的yaml是每分钟执行一下,这里我截了官方的一张图,并制作了一个表格提供参考。要生成CronJob调度表达式,您还可以使用诸如crontab.guru之类的Web工具。
举例 | 定义 |
---|---|
每年1月1日午夜运行一次 | 0 0 1 1 * |
每月在每月第一天的午夜运行一次 | 0 0 1 |
每周一在周日上午的午夜运行一次 | 0 0 0 |
每天半夜运行一次 | 0 0 * |
每小时开始一次,每小时运行一次 | 0 |
每个星期五的午夜以及每个月的13日的午夜开始任务 | 0 0 13 * 5 |
运行测试
架构设计
管理模式
1. Job Controller 负责根据配置创建Pod
2. Job Controller 跟踪Job状态,根据配置及时重试Pod或者继续创建
3. Job Controller 会自动添加label来跟踪对应的pod,并根据配置并行或者串行创建pod
Job控制器
上图是一个 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 里面去,这样我们就能看到呈现出来的最终效果了。
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

