【 云原生 | kubernetes 】资源对象 – 任务执行之job,cronjob

  • Post author:
  • Post category:其他


在这里插入图片描述

Job 会根据任务创建出一个或多个Pod, 并确保指定数量的 Pod 可以成功执行到进程正常结束。

  • 当数量达到指定的成功个数阈值时,任务(即 Job)结束。
  • 删除 Job 会清除所创建的全部 Pod,运行中的 Job 也会被清除
  • 挂起 Job 的操作会删除 Job 的所有活跃 Pod,直到 Job 被再次恢复执行。



Job



编写Job规范

Job 对象的定义非常简单,如下

所示

apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: busybox
        command: ["sh", "-c", "echo 'scale=1000; 4*a(1)' | bc -l "]
      restartPolicy: Never
  backoffLimit: 4

这个yaml文件中,我们一眼就看到了,Pod模板,即.spec.template字段

  • Pod模板描述的是一个计算Π的容器
  • Job的.spec中只有

    .spec.template

    是必须字段
  • Pod的

    RestartPolicy

    只能设置为Never或OnFailure, 在 Deployment 对象里,restartPolicy 则只允许被设置为 Always
  • 跟其他控制器不同的是,Job 对象并不要求你定义一个

    .spec.selector

    来描述要控制哪些 Pod。
  • 重试次数到达

    .spec.backoffLimit

    所设的上限,Job 会被标记为失败, 其中运行的 Pod 都会被终止。

创建这个Job

[root@sztcyl-177-9-244 ycloud]# kubectl apply -f job-pi.yaml 
job.batch/pi created

查看下Job描述信息

[root@ycloud ~]# kubectl describe job pi
Name:             pi
Namespace:        default
Selector:         controller-uid=76731211-42fe-46b0-9161-33b8283dc390
Labels:           controller-uid=76731211-42fe-46b0-9161-33b8283dc390
                  job-name=pi
Annotations:      <none>
Parallelism:      1
·········
Pod Template:
  Labels:  controller-uid=76731211-42fe-46b0-9161-33b8283dc390
           job-name=pi
  Containers:
   pi:
    Image:      busybox
    Port:       <none>
    Host Port:  <none>
    Command:
      sh
      -c
      echo 'scale=10000; 4*a(1)' | bc -l 
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age   From            Message
  ----    ------            ----  ----            -------
  Normal  SuccessfulCreate  47m   job-controller  Created pod: pi--1-vrsm8
  Normal  Completed         36m   job-controller  Job completed

我们可以看到,这个Job对象在被创建之后,

selector



lable

这两个字段自动添加了controller-uuid相同的值,从而确保其不会与任何其他 Job 重叠

Job内部自动添加的与pod的关联,为了避免不同Job之间无法确认管理的Pod。



运行时间

如果Job运行失败,Job控制器不会去启动新的Pod,但是,它会不停的去重启容器,知道任务完成。在Job对象中有一个字段可以控制运行时间,防止任务运行失败,一直重启任务。

”activeDeadlineSeconds“,设置Job的运行时间,一旦达到,运行中的Pod就会被中止。



示例
apiVersion: batch/v1
kind: Job
metadata:
  name: pi-sec
spec:
  template:
    spec:
      containers:
      - name: pi
        image: busybox
        command: ["sh", "-c", "echo 'scale=10000; 4*a(1)' | bc -l "]
      restartPolicy: Never
  backoffLimit: 4
  activeDeadlineSeconds: 5

注意 Job 的

.spec.activeDeadlineSeconds

优先级高于其

.spec.backoffLimit

设置。

我们把运行时间设置为5秒,然后运行Job,查看运行结果

[root@ycloud ycloud]# kubectl get po 
NAME                               READY   STATUS             RESTARTS        AGE
pi-sec--1-99h2m                    0/1     Error              0               22s
pi-sec--1-gdm2s                    0/1     Error              0               52s
pi-sec--1-mfdvg                    0/1     Error              0               54s
pi-sec--1-tqfxs                    0/1     Error              0               42s

我们发现创建的Pod状态都是 Error,

[root@ycloud ycloud]# kubectl describe jobs pi-sec
Name:                     pi-sec
Namespace:                default
Selector:                 controller-uid=71cf756b-e074-499c-90c9-e4f824e03b1a
Labels:                   controller-uid=71cf756b-e074-499c-90c9-e4f824e03b1a

······

Events:
  Type     Reason            Age    From            Message
  ----     ------            ----   ----            -------
  Normal   SuccessfulCreate  7m32s  job-controller  Created pod: pi-sec--1-mfdvg
  Normal   SuccessfulCreate  7m30s  job-controller  Created pod: pi-sec--1-gdm2s
  Normal   SuccessfulCreate  7m20s  job-controller  Created pod: pi-sec--1-tqfxs
  Normal   SuccessfulCreate  7m     job-controller  Created pod: pi-sec--1-99h2m
  Warning  DeadlineExceeded  6m20s  job-controller  Job was active longer than specified deadline

我们查看Job对象的事件描述,看到Job失败的原因是 DeadlineExceeded



Job并行执行

completions 和 parallelism

  • completions,它定义的是 Job 至少要完成的 Pod 数目,即 Job 的最小完成数。

  • parallelism,它定义的是一个 Job 在任意时间最多可以启动多少个 Pod 同时运行;

当成功Pode个数达到completions阈值,Job被视为成功;



示例
apiVersion: batch/v1
kind: Job
metadata:
  name: pi-com
spec:
  template:
    spec:
      containers:
      - name: pi
        image: busybox
        command: ["sh", "-c", "echo 'scale=10000; 4*a(1)' | bc -l "]
      restartPolicy: Never
  backoffLimit: 4
  parallelism: 3 
  completions: 3

我们设置Job的最大并行数和最小完成数都是3,创建这个Job对象

[root@ycloud ycloud]# kubectl apply -f job-com.yaml 
job.batch/pi-com created
[root@ycloud ycloud]# kubectl get po
NAME                               READY   STATUS              RESTARTS        AGE
pi-com--1-2vs6z                    1/1     Running            0               2m8s
pi-com--1-7jm69                    1/1     Running            0               2m8s
pi-com--1-9mkq7                    1/1     Running            0               2m8s

我们可以看到,三个任务同时运行。

综上所述:completions: 最后要成功运行多少个pod, parallelism: 每次只能启动多少个pod



使用拓展



模板拓展

把Job的yaml文件定义为一个模板,通过模板来生成Job

apiVersion: batch/v1
kind: Job
metadata:
  name: process-item-$ITEM
  labels:
    jobgroup: jobexample
spec:
  template:
    metadata:
      name: jobexample
      labels:
        jobgroup: jobexample
    spec:
      containers:
        - name: c
          image: busybox
          command:
            - sh
            - '-c'
            - echo Processing item $ITEM && sleep 5
      restartPolicy: Never

可以看到,我们在这个 Job 的 YAML 里,定义了 $ITEM 这样的“变量”。

如果我们之间去运行这个job,会提示我们名称不符合规范标准。

[root@ycloud ~]# kubectl apply -f job.yaml 
The Job "process-item-$ITEM" is invalid: 
* metadata.name: Invalid value: "process-item-$ITEM": a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')

所以在运行这种Job时,我们需要注意这两个方面:

  • 创建 Job 时,需要对变量 $ITEM 传参
  • 这个模板创建出的 Job ,都会带有 jobgroup: jobexample 的标签。

我们可以编写shell脚本,把 $ITEM 替换掉

#!/bin/bash

mkdir ./jobs
for i in aa bb cc
do
        cat job.yaml | sed "s/\$ITEM/$i/" > ./jobs/job-$i.yaml
done

运行脚本之后,可以看到一组来自同一个模板的不同Job的yaml就生产了,

[root@ycloud ycloud]# ll jobs/
total 12
-rw-r--r-- 1 root root 400 Oct  7 13:54 job-aa.yaml
-rw-r--r-- 1 root root 400 Oct  7 13:54 job-bb.yaml
-rw-r--r-- 1 root root 400 Oct  7 13:54 job-cc.yaml

让我们创建这些Job

[root@ycloud ycloud]# kubectl apply -f jobs/
job.batch/process-item-aa created
job.batch/process-item-bb created
job.batch/process-item-cc created

最后我们查看下Pod的输出,目前kubelet logs只支持一个Pod的输出,我们这里通过一个循环来检查Pod的输出

[root@ycloud ycloud]# cat for.sh 
#!/bin/bash
for p in $(kubectl get pods -l jobgroup=jobexample -o name)
do
  kubectl logs $p
done

[root@ycloud ycloud]# bash for.sh 
Processing item aa
Processing item bb
Processing item cc



CronJob

CronJob是Job对象的一个控制器, 该对象根据 Cron 格式定义的时间计划,周期性地创建 Job 对象。

CronJob 执行周期性的重复任务可以用来定时备份数据、发送邮件等



Cron时间表语法

在这里插入图片描述



并发规则

concurrencyPolicy 声明了 CronJob 创建的任务执行时发生重叠如何处理

  • Allow,这也是默认情况,这意味着这些 Job 可以同时存在;
  • Forbid,这意味着不会创建新的 Pod,该创建周期被跳过;
  • Replace,这意味着新产生的 Job 会替换旧的、没有执行完的 Job。


CronJob示例
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"     #每 1 个时间单位执行一次
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

上面这个CronJob,从当前开始,每分钟会打印出时间和“Hello from the Kubernetes cluster”

[root@ycloud ycloud]# kubectl apply -f cronjob.yaml 
cronjob.batch/hello created

[root@ycloud ycloud]# kubectl get jobs
NAME              COMPLETIONS   DURATION   AGE
hello-27752081    0/1           48s        48s

CronJob 对象会对Job执行进行记录

[root@ycloud ycloud]# kubectl get cronjobs 
NAME    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
hello   */1 * * * *   False     2        21s             4m18s


LAST SCHEDULE

这个时间点成功创建了一个 Job。当前

ACTIVE

Job 数为 2,意味着,该 Job 已经成功结束.

[root@ycloud ycloud]# kubectl logs hello-27752082--1-kdnz2
Fri Oct  7 06:44:04 UTC 2022
Hello from the Kubernetes cluster



结论

我们了解了Job和CronJob的简单使用。从CronJob对像的yaml文件中,我们就可以了解到,Job和CronJob就跟Deployment和ReplicaSet一样,是被管理的关系



版权声明:本文为weixin_45133467原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。