Kubernetes中的Job和CronJob,批量任务执行

  • Post author:
  • Post category:其他


我们经常需要进行批量数据处理和分析,以及按照时间进行调度执行。可以在Kubenrtes中使用容器技术完成,使用Job和CronJob来执行。这样,可以维护较为干净的执行环境,减少不同任务工具的相互干扰。同时可以在集群上按照任务要求和资源状况进行动态伸缩执行。

  • 任务主要包含两种:

    • Job负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。
    • CronJob是基于调度的Job执行将会自动产生多个job,调度格式参考Linux的cron系统。
  • 执行环境:

    • 无论是job还是CronJob,


      执行时都产生一个pod,然后在里面运行给定的命令


      • 要执行自己的任务,需要一个自己的Docker镜像和yaml格式的job描述文件。


    • 执行环境是容器隔离


      的,外部存储可以通过pvc/pv等挂载进去,与pod配置参数完全一致。
    • 任务可以在整个集群环境中调度执行,因此:



      • 资源访问是漂移的,可以使用nodeSelector固定要执行的节点


参考:



1、Job,执行一次任务



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/v1beta1


  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

  • 注意,里面的template配置方法与Deployment配置参数是完全一样的,用于生成运行时的pod。可以在其中指定挂载卷、运行的命令等等。

执行工作任务:



  1. $ kubectl create -f ./job.yaml


  2. job "pi" created


  3. $ pods=$(kubectl get pods --selector=job-name=pi --output=jsonpath={.items..metadata.name})


  4. $ kubectl logs $pods


  5. 3.141592653589793238462643383279502...



2、CronJob,周期执行任务


Cron Job

管理基于时间的

Job

,即:

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

一个 CronJob 对象类似于

crontab

(cron table)文件中的一行。

典型的用法如下所示:

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


注意:

  • 预估job的执行时间。给定的间隔一般不应少于该job的执行时间。
  • 如果当前job尚未结束,达到时间触发点时,系统仍然会启动新的任务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。

    • 默认没有限制,所有成功和失败的 Job 都会被保留。

    • 当运行一个 Cron Job 时,Job 可以很快就堆积很多,推荐设置这两个字段的值。

    • 设置限制的值为

      0

      ,相关类型的 Job 完成后将不会被保留。



创建任务描述文件



  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:

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



Cron Job 限制

Cron Job 在每次调度运行时间内

“大概”

会创建一个 Job 对象。我们之所以说

“大概”

,是因为在特定的环境下可能会创建两个 Job,或者一个 Job 都没创建。我们尝试少发生这种情况,但却不能完全避免。因此,创建 Job 操作应该是

幂等的

Job 根据它所创建的 Pod 的并行度,负责重试创建 Pod,并就决定这一组 Pod 的成功或失败。Cron Job 根本就不会去检查 Pod。



删除 Cron Job

一旦不再需要 Cron Job,简单地可以使用

kubectl

命令删除它:



  1. $ kubectl delete cronjob hello


  2. cronjob "hello" deleted

这将会终止正在创建的 Job。然而,运行中的 Job 将不会被终止,不会删除 Job 或 它们的 Pod。为了清理那些 Job 和 Pod,需要列出该 Cron Job 创建的全部 Job,然后删除它们:



  1. $ kubectl get jobs


  2. NAME DESIRED SUCCESSFUL AGE


  3. hello-1201907962 1 1 11m


  4. hello-1202039034 1 1 8m


  5. ...


  6. $ kubectl delete jobs hello-1201907962 hello-1202039034 ...


  7. job "hello-1201907962" deleted


  8. job "hello-1202039034" deleted


  9. ...

一旦 Job 被删除,由 Job 创建的 Pod 也会被删除。注意,所有由名称为“hello” 的 Cron Job 创建的 Job 会以前缀字符串 “hello-” 进行命名。如果想要删除当前 Namespace 中的所有 Job,可以通过命令

kubectl delete jobs --all

立刻删除它们。

转载于:https://my.oschina.net/u/2306127/blog/1784978