目录

Job

用于处理离线业务的,运行完成后就终止执行。

运行一个 Pod 对象

编写 Job 的 YAML 文件(job-pi.yaml)

bc 命令是 Linux 里的“计算器”;-l 表示使用标准数学库;a(1) 是调用数学库中的 arctangent 函数,计算 atan(1)。

tan(π/4) = 1。所以,4*atan(1)正好就是π,也就是 3.1415926…。

apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: pi
        image: alpine
        command: ["sh", "-c", "echo 'scale=6000; 4*a(1)' | bc -l"]
  • restartPolicy: Pod 内所有容器的重启策略。对于 Job 重启策略只能是 OnFailure 和 Never,默认是 Always。
    • OnFailure
    • Never
    • Always(default)

创建 Job 对象

$ kubectl apply -f job-pi.yaml 
job.batch/pi created

查看 Job 创建的所有对象

$ kubectl get all
NAME           READY   STATUS    RESTARTS   AGE
pod/pi-866nk   1/1     Running   0          2m46s

NAME           COMPLETIONS   DURATION   AGE
job.batch/pi   0/1           2m46s      2m46s

运行完成后再次查看,Pod 的状态变为 Completed,不会自动删除,方便您查看日志。

$ kubectl get all
NAME           READY   STATUS      RESTARTS   AGE
pod/pi-866nk   0/1     Completed   0          11m

NAME           COMPLETIONS   DURATION   AGE
job.batch/pi   1/1           10m        11m

日志查看

$ kubectl logs pod/pi-866nk
3.141592653589793238462643383279502884197169399375105820974944592307\
81640628620899862803482534211706798214808651328230664709384460955058\
......

删除 Job 对象,Pod 也会一起被删除。

$ kubectl delete job pi
job.batch "pi" deleted

Job 对象和 Pod 对象的关联

Kubernetes 会给 Pod 模板自动增加 controller-uid 标签,创建的每个 Pod 对象都带有这个标签,Job 对象使用标签选择器进行关联。

查看 Job 对象的描述

$ kubectl describe job pi
Selector:       controller-uid=2b025eb2-3cc2-4a5a-919a-afb1187544f5
Labels:         controller-uid=2b025eb2-3cc2-4a5a-919a-afb1187544f5
                job-name=pi
Pod Template:
  Labels:  controller-uid=2b025eb2-3cc2-4a5a-919a-afb1187544f5
           job-name=pi

查看 Pod 对象的描述

$ kubectl describe pod pi-866nk 
Labels:       controller-uid=2b025eb2-3cc2-4a5a-919a-afb1187544f5
              job-name=pi

运行多个 Pod 对象

编写 Job 的 YAML 文件(job-multi-pi.yaml)

apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  completions: 5
  parallelism: 2
  template:
    spec:
      restartPolicy: Never
      activeDeadlineSeconds: 300
      containers:
      - name: pi
        image: alpine
        command: ["sh", "-c", "echo 'scale=6000; 4*a(1)' | bc -l"]
  • completions: 希望作业运行多少次
  • parallelism: 并行运行多少个作业(Pod)
  • activeDeadlineSeconds: Pod 运行时间超过这个时间,终止 Pod,并标记为失败。

创建 Job 对象

$ kubectl apply -f job-multi-pi.yaml 
job.batch/pi created

查看 Job 创建的所有对象

$ kubectl get all
NAME           READY   STATUS              RESTARTS   AGE
pod/pi-82qd8   0/1     ContainerCreating   0          20s
pod/pi-wzcr8   0/1     ContainerCreating   0          20s

NAME           COMPLETIONS   DURATION   AGE
job.batch/pi   0/5           20s        20s
$ kubectl get all
NAME           READY   STATUS              RESTARTS   AGE
pod/pi-82qd8   0/1     Completed           0          3m34s
pod/pi-dxrrp   1/1     Running             0          28s
pod/pi-r9892   0/1     ContainerCreating   0          11s
pod/pi-wzcr8   0/1     Completed           0          3m34s

NAME           COMPLETIONS   DURATION   AGE
job.batch/pi   2/5           3m34s      3m34s

限制 Job 任务完成时间

编写 Job 的 YAML 文件(job-pi.yaml)

apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  backoffLimit: 2
  template:
    spec:
      restartPolicy: Never
      activeDeadlineSeconds: 60
      containers:
      - name: pi
        image: alpine
        command: ["sh", "-c", "echo 'scale=6000; 4*a(1)' | bc -l"]
  • backoffLimit: Job 被标记为失败之前可以重试的次数。默认为6。
  • activeDeadlineSeconds: Pod 运行时间超过这个时间,终止 Pod,并标记为失败。

创建 Job 对象

$ kubectl apply -f job-pi.yaml 
job.batch/pi created

查看 Job 对象的描述

通过 Pods Statuses 和 Events 属性可以看到失败的情况及原因。

$ kubectl describe jobs pi
Name:           pi
Namespace:      kubia
Selector:       controller-uid=a42d4024-c4d4-4bc3-a7c6-8d2139ca6310
Labels:         controller-uid=a42d4024-c4d4-4bc3-a7c6-8d2139ca6310
                job-name=pi
Annotations:    Parallelism:  1
Completions:    1
Start Time:     Thu, 08 Jul 2021 01:32:56 +0000
Pods Statuses:  0 Running / 0 Succeeded / 3 Failed
Pod Template:
  Labels:  controller-uid=a42d4024-c4d4-4bc3-a7c6-8d2139ca6310
           job-name=pi
  Containers:
   pi:
    Image:      alpine
    Port:       <none>
    Host Port:  <none>
    Command:
      sh
      -c
      echo 'scale=6000; 4*a(1)' | bc -l
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type     Reason                Age    From            Message
  ----     ------                ----   ----            -------
  Normal   SuccessfulCreate      6m6s   job-controller  Created pod: pi-27f7v
  Normal   SuccessfulCreate      5m6s   job-controller  Created pod: pi-zz2xh
  Normal   SuccessfulCreate      3m55s  job-controller  Created pod: pi-gwkwt
  Warning  BackoffLimitExceeded  2m35s  job-controller  Job has reached the specified backoff limit

CronJob

编写 CronJob 的 YAML 文件(cronjob.yaml)

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - "date; echo Hello Kubernetes"

这个 Cron 表达式里 */1 中的 * 表示从 0 开始,/ 表示“每”,1 表示偏移量。所以,它的意思就是:从 0 开始,每 1 个时间单位执行一次。

Cron 时间表语法

# ┌───────────── 分钟 (0 - 59)
# │ ┌───────────── 小时 (0 - 23)
# │ │ ┌───────────── 月的某天 (1 - 31)
# │ │ │ ┌───────────── 月份 (1 - 12)
# │ │ │ │ ┌───────────── 周的某天 (0 - 6) (周日到周一;在某些系统上,7 也是星期日)
# │ │ │ │ │                                   
# │ │ │ │ │
# │ │ │ │ │
# * * * * *

创建 CronJob 对象

$ kubectl apply -f cronjob.yaml 
cronjob.batch/hello created

查看 CronJob 创建的所有对象

通过观察一段时间,发现 Job 和 Pod 对象并不会一直存在,会保留最近成功运行的 3 个作业。可以根据自己的需要来设置 spec.successfulJobsHistoryLimit。

$ kubectl get all
NAME                         READY   STATUS      RESTARTS   AGE
pod/hello-1625713980-x2999   0/1     Completed   0          2m55s
pod/hello-1625714040-jkj5r   0/1     Completed   0          115s
pod/hello-1625714100-m2kgf   0/1     Completed   0          55s

NAME                         COMPLETIONS   DURATION   AGE
job.batch/hello-1625713980   1/1           19s        2m55s
job.batch/hello-1625714040   1/1           17s        115s
job.batch/hello-1625714100   1/1           23s        55s

NAME                  SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob.batch/hello   */1 * * * *   False     0        57s             23m

任务的运行方式

当前任务没有执行完成,要创建新任务的策略

  • concurrencyPolicy
    • Allow(default) 任务可以同时存在。
    • Forbid 不会创建新的任务,该创建周期被跳过。
    • Replace 新的任务会替换旧的没有执行完的。

startingDeadlineSeconds

对于每个 CronJob,CronJob 控制器(Controller) 检查从上一次调度的时间点到现在所错过了调度次数。如果错过的调度次数超过 100 次, 那么它就不会启动这个任务.需要注意的是,如果 startingDeadlineSeconds 字段非空,则控制器会统计从 startingDeadlineSeconds 设置的值到现在而不是从上一个计划时间到现在错过了多少次 Job。 例如,如果 startingDeadlineSeconds 是 200,则控制器会统计在过去 200 秒中错过了多少次 Job。未能在调度时间内创建 CronJob,则计为错过(miss)。

参考资料