0%

k8s-Job&CornJob

k8s-Job&CornJob

(翻译自k8sガイドブック)

Job

Job:コンテナを利用して一度限りの処理を実行させるリソースです。

ReplicaSet和Job的不同点

  • Job: Pod の停止が正常終了と期待される用途に向いています
  • ReplicaSet: Pod の停止は予期せぬエラー

创建Job

例子:创建sleep 60s的Job。(虽然和ReplicaSet一样,可以明确的赋予label和selector,由于k8s会自动生成unique的uuid,因此在Job中并不推荐明确赋予。)sample-job.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: batch/v1
kind: Job
metadata:
name: sample-job
spec:
completions: 1
parallelism: 1
backoffLimit: 10
template:
spec:
containers:
- name: tools-container
image: amsy810/tools:v2.0
command: ["sleep"]
args: ["60"]
restartPolicy: Never
1
2
#创建job
kubectl apply -f sample-job.yaml

kubectl get进行Job的确认,不同与ReplicaSet等表示READY的container数量,Job表示正常结束的Pod数(COMPLETIONS)。而且Job和ReplicaSet一样,是创建Pod的资源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Jobの一覧を表示(Jobの作成直後)
$ kubectl get jobs
NAME COMPLETIONS DURATION AGE
sample-job 0/1 3s 3s

# Jobが作成したPodを確認
$ kubectl get pods --watch
NAME READY STATUS RESTARTS AGE
sample-job-bhzs7 1/1 Running 0 31s
sample-job-bhzs7 0/1 Completed 0 69s

# Jobの一覧を表示(Podの実行完了後)
$ kubectl get jobs
NAME COMPLETIONS DURATION AGE
sample-job 1/1 69s 76s

Job的restartPolicy

Job的manifest中,spec.template.spec.restartPolicy字段必须指定为OnFailuere或者Never

  • Never:当Pod故障时,创建新的Pod。
  • OnFailure:再次使用同一个Pod,并重开Job。

restartPolicy—Never

task型和workqueue型的并行Job

Job的spec.completions字段指定成功次数;spec.parallelism字段指定并行个数。这两个字段的默认值都为1。

  • 例子:有2个并列执行,成功10次结束的Job。sample-paralleljob.yaml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    apiVersion: batch/v1
    kind: Job
    metadata:
    name: sample-parallejob
    spec:
    completions: 10
    parallelism: 2
    backoffLimit: 10
    template:
    spec:
    containers:
    - name: tools-container
    image: amsy810/tools:v2.0
    command: ["sleep"]
    args: ["30"]
    restartPolicy: Never

3个重要参数

completions:成功次数,设定后不能变更

parallelism:并列个数,可以中途变更

backoffLimit :允许失败的次数,可以中途变更。

4种典型Job类型

Job类型 使用示例 行为 completions Parallelism
一次性Job 数据库迁移 创建一个Pod直至其成功结束 1 1
固定结束次数的Job(一个一个执行的workQueue) 处理工作队列的Pod 依次创建一个Pod运行直至completions个成功结束 2+ 1
固定结束次数的并行Job 多个Pod同时处理工作队列 依次创建多个Pod运行直至completions个成功结束 2+ 2+
并行Job 多个Pod同时处理工作队列 创建一个或多个Pod直至有一个成功结束 1 2+
One Shot Task:一次性任务

三个参数分别设置为:completions=1 / parallelism=1 / backoffLimit=0

意义:无论是否执行成功,一定会执行一次。

  • 例子:sample-oneshot-task-job.yaml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    apiVersion: batch/v1
    kind: Job
    metadata:
    name: sample-oneshot-task-job
    spec:
    completions: 1
    parallelism: 1
    backoffLimit: 0
    template:
    spec:
    containers:
    - name: tools-container
    image: amsy810/tools:v2.0
    command: ["sleep"]
    args: ["30"]
    restartPolicy: Never
Multi Task: 并行任务

改变completionsparallelism的值,即可创建并行task。

例如:设置completions=5 parallelism=3 。意义:创建3个Pod并行执行,直到Pod成功结束5次。

注意:如果最后只剩下2个Job还没有完成,则只会并行执行2个Pod,而不是3个。

  • 例子:sample-multi-task-job.yaml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    apiVersion: batch/v1
    kind: Job
    metadata:
    name: sample-multi-task-job
    spec:
    completions: 5
    parallelism: 3
    backoffLimit: 5
    template:
    spec:
    containers:
    - name: tools-container
    image: amsy810/tools:v2.0
    command: ["sleep"]
    args: ["30"]
    restartPolicy: Never

如果parallelism>completions时,比如:completions=3,parallelism=5的情况下执行Job,只会创建3个Pod,而不是5个。

Multi WorkQueue: 并行执行的工作队列
  • WorkQueue类型的Job的参数设置:不设置completions,只设置parallelism

  • 意义:parallelism所指定的数量来并行执行Pod,如果其中一个Pod成功结束的话,则不再继续创建Pod。这时,已经处于执行中的Pod不会被强行停止,而是继续执行至处理结束。

使用WorkQueue的场合:

  • 需要message queue(消息队列)来管理所有处理的进度。
Single WorkQueue: 一个一个执行的工作队列
  • 参数设定:不设置completions,设置parallelism=1
  • 意义:一直一个一个创建Pod,直到Pod正常结束。

例子:sample-single-workqueue-job.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: batch/v1
kind: Job
metadata:
name: sample-single-workqueue-job
spec:
# 不设置completions
parallelism: 1
backoffLimit: 1
template:
spec:
containers:
- name: tools-container
image: amsy810/tools:v2.0
command: ["sleep"]
args: ["30"]
restartPolicy: Never

由于parallelism参数时可以在Job创建之后变更的。因此,可以在创建single WorkQueue之后,通过把parallelism的值改变为N,把Job变成N个并列执行的Multi WorkQueue。

可以通过kubectl patch改变parallelism

1
2
3
4
5
6
7
8
9
10
$ kubectl get jobs
NAME COMPLETIONS DURATION AGE
sample-single-workqueue-job 1/1 4s 29s

$ kubectl patch job sample-single-workqueue-job -p '{"spec": {"parallelism": 2}}'
job.batch/sample-single-workqueue-job patched

$ kubectl get jobs
NAME COMPLETIONS DURATION AGE
sample-single-workqueue-job 1/1 of 2 4s 72s

或者修改manifest声明文件后,用kubectl apply更新。

一段时间后自动删除的Job

在Job的spec字段下面添加ttlSecondsAfterFinished字段进行设置(spec.ttlSecondsAfterFinished)

例子:sample-job-ttl.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: batch/v1
kind: Job
metadata:
name: sample-job-ttl
spec:
ttlSecondAfterFinished: 30
completions: 1
parallelism: 1
backoffLimit: 10
template:
spec:
containers:
- name: tools-container
image: amsy810/tools:v2.0
command: ["sleep"]
args: ["60"]
restartPolicy: Never

在60s后,Job执行完成,再过30s后,Job被删除。

1
2
3
4
5
6
# 监视Job的状態
$ kubectl get job sample-job-ttl --watch --output-watch-events
EVENT NAME COMPLETIONS DURATION AGE
ADDED sample-job-ttl 0/1 1s 1s # Job起動
MODIFIED sample-job-ttl 1/1 64s 64s # Job完成(+60秒後)
DELETED sample-job-ttl 1/1 64s 95s # Job自動削除(+30秒後)

CronJob

CronJob和Job的关系如同Deployment和ReplicaSet的关系。即,CronJob管理Job,Job管理Pod。

CronJob的创建

CronJob的spec.schedule字段的值与Linux的Cron使用相同格式。

例子:创建每隔一分钟就创建有50%成功几率且只执行一次Job的CronJob。即,把completions=1,parallelism=1的Job作为CronJob每分钟来执行。

(本次使用的imageamsy810/random-exit执行了有50%概率执行成功的command。)

sample-cronjob.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: batch/v1
kind: CronJob
metadata:
name: sample-cronjob
spec:
schedule: "*/1 * * * *"
concurrencyPolicy: Allow #不限制同时执行
startingDeadlineSeconds: 30
successfulJobsHistoryLimit: 5 #保存执行成功Job的数量
failedJobsHistoryLimit: 3 #保存执行失败的Job的数量
suspend: false
jobTemplate:
spec:
completions: 1
parallelism: 1
backoffLimit: 0
template:
spec:
container:
- name: tools-container
image: amsy810/random-exit:v2.0
restartPolicy: Never
  • kubectl apply创建

    1
    kubectl apply -f sample-cronjob.yaml
  • 确认CronJob

    1
    2
    3
    4
    5
    6
    7
    $ kubectl get cronjobs
    NAME SCHEDULE SUSPEND ACTIVE LAST-SCHEDULE AGE
    sample-cronjob */1 * * * * False 0 <none> 11s

    # 没有到达Sechedule的时间之前,Job不存在
    $ kubectl get jobs
    No resources found.
  • 到达指定时间之后,再次确认Job

    1
    2
    3
    4
    5
    6
    7
    8
    $ kubectl get cronjobs
    NAME SCHEDULE SUSPEND ACTIVE LAST-SCHEDULE AGE
    sample-cronjob */1 * * * * False 0 1s 2m

    # CronJobが作成したJobが存在
    $ kubectl get jobs
    NAME COMPLETIONS DURATION AGE
    sample-cronjob-1505669160 0/1 1s 1s

暂时停止(suspend)CronJob

把CronJob的spec.suspend字段定义改为true(默认为false),即从Schedule的对象中去除了当前的CronJob。

方法:

  • 修改manifest的spce.suspend后执行kubectl apply更新
  • 或者kubectl path cronjob {cronjob_name} -p '{"spec":{"suspend":true}}'

如果需要reschedule CronJob的话,把spec.suspend改回false即可。

在任意时刻执行CronJob

使用--from选项,以CronJob为基础,创建Job。

1
kubectl create job sample-job-from-cronjob --from cronjob/sample-cronjob

同时执行的控制

通过设置CronJob的spec.concurrencyPolicy字段来控制同时执行。

Policy 概要
Allow(默认) 对同时执行不做限制
Forbid 如果之前的Job没有结束,则不会执行下一个Job(不会同时执行)
Replace 取消之前的Job,开始新的Job