Job

Job负责批量处理短暂的一次性任务 (short lived one-off tasks),即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。
Kubernetes支持以下几种Job:

  • 非并行Job:通常创建一个Pod直至其成功结束
  • 固定结束次数的Job:设置.spec.completions,创建多个Pod,直到.spec.completions个Pod成功结束
  • 带有工作队列的并行Job:设置.spec.Parallelism但不设置.spec.completions,当所有Pod结束并且至少一个成功时,Job就认为是成功

根据.spec.completions和.spec.Parallelism的设置,可以将Job划分为以下几种pattern:

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

Job Controller

Job Controller负责根据Job Spec创建Pod,并持续监控Pod的状态,直至其成功结束。如果失败,则根据restartPolicy(只支持OnFailure和Never,不支持Always)决定是否创建新的Pod再次重试任务。
k8s -- Job/CronJob 控制器 - 图1

Job Spec格式

  • spec.template格式同Pod
  • RestartPolicy仅支持Never或OnFailure
  • 单个Pod时,默认Pod成功运行后Job即结束
  • .spec.completions 标志Job结束需要成功运行的Pod个数,默认为1
  • .spec.parallelism 标志并行运行的Pod的个数,默认为1
  • spec.activeDeadlineSeconds 标志失败Pod的重试最大时间,超过这个时间不会继续重试

一个简单的例子:

  1. apiVersion: batch/v1
  2. kind: Job
  3. metadata:
  4. name: pi
  5. spec:
  6. template:
  7. metadata:
  8. name: pi
  9. spec:
  10. containers:
  11. - name: pi
  12. image: perl
  13. command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
  14. restartPolicy: Never

CronJob

CronJob即定时任务,就类似于Linux系统的crontab,在指定的时间周期运行指定的任务。在Kubernetes 1.5,使用CronJob需要开启batch/v2alpha1 API,即 –runtime-config=batch/v2alpha1。

CronJob Spec

  • spec.template 格式同 Pod
  • RestartPolicy 仅支持 Never 或 OnFailure
  • 单个 Pod 时,默认 Pod 成功运行后 Job 即结束
  • .spec.completions 标志 Job 结束需要成功运行的 Pod 个数,默认为1
  • .spec.parallelism 标志并行运行的 Pod 的个数,默认为1
  • spec.activepeadlineseconds 标志失败 Pod 的重试最大时间,超过这个时间不会继续重试

CronJob

Cron Job管理基于时间的Job,即:

  • 在给定时间点只运行一次
  • 周期性地在给定时间点运行

使用条件:当前使用的Kubernetes 集群,版本>=1.8(对Cronjob)

典型的用法如下所示:

  • 在给定的时间点调度Job运行
  • 创建周期性运行的Job,例如:数据库备份、发送邮件

CronJob Spec

  • .spec.schedule 调度,必需字段,指定任务运行周期,格式同Cron
  • .spec.jobTemplate Job 模板,必需字段,指定需要运行的任务,格式同Job
  • .spec.startingDeadlineSeconds 启动Job的期限(秒级别),该字段是可选的。如果因为任何原因而错过了被调度的时间,那么错过执行时间的Job将被认为是失败的。如果没有指定,则没有期限
  • .spec.concurrencyPolicy 指定任务的并发策略,该字段也是可选的。它指定了如何处理被Cron Job创建的Job的并发执行。只允许指定下面策略中的一种:

    • Allow (默认):允许并发运行Job
    • Forbid 禁止并发运行,如果前一个还没有完成,则直接跳过下一个
    • Replace 取消当前正在运行的Job,用一个新的来替换

      注意,当前策略只能应用于同一个Cron Job创建的Job。如果存在多个Cron Job,它们创建的Job之间总是允许并发运行。

  • .spec.suspend 挂起,该字段也是可选的。如果设置为 true ,后续所有执行都会被挂起。它对已经开始执行的 Job 不起作用。默认值为 false

  • .spec.successfulJobsHistoryLimit.spec.failedJobsHistoryLimit 历史限制,是可选的字段。它们指定了可以保留多少完成和失败的 Job。默认情况下,它们分别设置为 31 。设置限制的值为 0 ,相关类型的 Job 完成后将不会被保留。

Example:

  1. apiVersion: batch/v1beta1
  2. kind: CronJob
  3. metadata:
  4. name: hello
  5. spec:
  6. schedule: "*/1 * * * *"
  7. jobTemplate:
  8. spec:
  9. template:
  10. spec:
  11. containers:
  12. - name: hello
  13. image: busybox
  14. args:
  15. - /bin/sh
  16. - -c
  17. - date; echo Hello from the Kubernetes cluster
  18. restartPolicy: OnFailure
  1. $ kubectl create -f cronjob.yaml
  2. cronjob "hello" created

当然,也可以用kubectl run来创建一个CronJob:

  1. kubectl run hello --schedule="*/1 * * * *" --restart=OnFailure --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster"
  1. $ kubectl get cronjob
  2. NAME SCHEDULE SUSPEND ACTIVE LAST-SCHEDULE
  3. hello */1 * * * * False 0 <none>
  4. $ kubectl get jobs
  5. NAME DESIRED SUCCESSFUL AGE
  6. hello-1202039034 1 1 49s
  7. $ pods=$(kubectl get pods --selector=job-name=hello-1202039034 --output=jsonpath={.items..metadata.name} -a)
  8. $ kubectl logs $pods
  9. Mon Aug 29 21:34:09 UTC 2016
  10. Hello from the Kubernetes cluster
  11. # 注意,删除cronjob的时候不会自动删除job,这些job可以用kubectl delete job来删除
  12. $ kubectl delete cronjob hello
  13. cronjob "hello" deleted

CronJob 本身的限制

创建 Job 操作应该是 幂等的
cronjob无法获取操作成功的状态