【k8s系列十一】k8s控制器 之 Job

297 阅读7分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第22天,点击查看活动详情

Job

Job 负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个 Pod 成功结束.

来理解一下这句话, 前半句, 说明很明确, job使用来处理批处理任务的,仅执行一次. 那什么叫一个或者多个pod的成功结束呢? 举个例子: 我有一个备份数据库的任务, 把这个任务封装在job里. 假如我只需要一天备份一次, 那么这个job执行完就完事了, 结束了. 那如果我想一天备份3次呢?我要创建多个job么?不是的. 不会这么傻的. 假如要执行3次任务, job会创建3个pod去执行, 并且要成功返回为0,才算成功, job才算结束.

对于Job有一些特殊说明, 具体如下:

  • spec.template格式同Pod
  • RestartPolicy仅支持Never或OnFailure. 这个是重启策略, 也就是重来都不重启,或者失败重启. 只有这两个选项.
  • 单个Pod时,默认Pod成功运行后Job即结束 也就是任务执行完了,并且返回成功, job就结束了, pod也没了.
  • .spec.completions 标志Job结束需要成功运行的Pod个数,默认为1 最后返回成功的pod的个数
  • .spec.parallelism 标志并行运行的Pod的个数,默认为1 并行运行的个数是1. 举个例子: job结束需要成功运行5个pod, 每次并行运行1个, 那么这5个pod就是一个运行结束了另一个在运行,一直到5个.而job结束的条件是要成功运行5个pod,才算结束.
  • spec.activeDeadlineSeconds`标志失败Pod的重试最大时间,超过这个时间不会继续重试 如果一个pod失败了, 那么她会重试, 但是有一个重试的最大时间, 如果超过了这个时间, 依然失败, 就不再重试了, 就标记为失败.

案例: 第一步: 准备镜像文件

kind: Job
apiVersion: batch/v1
metadata:
  name: test-job
spec:
  template:
    metadata:
      name: test-job
    spec:
      containers:
      - name: hello
        image: busybox:latest
        command: ["echo","hello k8s job"]
      restartPolicy: Never
  • 首先定义了一个Job, group类是在batch/v1, job的名称是test-job
  • pod使用的镜像是busybox
  • 这个job的任务是打印输出hello k8s job

第二步: 创建job

kubectl create -f test-job.yaml

image 我们看到job启动以后, 执行完打印, 任务状态就变成了completed的状态, 说明执行成功了.

第三步: 设置Job需要成功运行的Pod个数为5, 并行个数为2 修改资源清单

kind: Job
apiVersion: batch/v1
metadata:
  name: test-job
spec:
  completions: 5
  parallelism: 2
  template:
    metadata:
      name: test-job
    spec:
      containers:
      - name: hello
        image: busybox:latest
        command: ["echo","hello k8s job"]
      restartPolicy: Never

修改完资源清单, 创建job 并 get job

kubectl create -f test-job.yaml & kubectl get pod -o wide

image 我们看到job每次会创建2个, 并且要等所有的pod都complted了, job才能complted

6. CronJob

cronJob的使用前提条件:当前使用的 Kubernetes 集群,版本 >= 1.8(对 CronJob)。对于先前版本的集群,版本 < 1.8,启动 API Server时,通过传递选项--runtime-config=batch/v2alpha1=true可以开启 batch/v2alpha1 API

Cron Job管理基于时间的 Job,可以理解为轮循的计划任务。

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

CronJob归根结底依然是job, 所以, job中的特性, cronJob也适用. 比如:

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

然而, cronJob也有自己的特点, cronJob会去创建job, 但是他会根据一定的时间创建, 比如分, 时, 日, 月等.

  • .spec.schedule:调度,必需字段,指定任务运行周期,格式同 Cron

  • .spec.jobTemplate:Job 模板,必需字段,指定需要运行的任务,格式同 Job

  • .spec.startingDeadlineSeconds :启动 Job 的期限(秒级别),该字段是可选的。如果因为任何原因而错过了被调度的时间,那么错过执行时间的 Job 将被认为是失败的。如果没有指定,则没有期限 如何理解这个字段呢? CronJob会创建job, job会创建pod. job创建的pod如果在指定时间内没有返回成功, 那么这个pod就是执行失败. 而这里不是pod执行失败了, 是job在指定的时间内没有返回成功, 那么这个job就是失败的.

  • .spec.concurrencyPolicy:并发策略,该字段也是可选的。它指定了如何处理被 Cron Job 创建的 Job 的并发执行。只允许指定下面策略中的一种:

    • Allow(默认):允许并发运行 Job
    • Forbid:禁止并发运行,如果前一个还没有完成,则直接跳过下一个
    • Replace:取消当前正在运行的 Job,用一个新的来替换 注意,当前策略只能应用于同一个 Cron Job 创建的 Job。如果存在多个 Cron Job,它们创建的 Job 之间总是允许并发运行。

    这个字段是什么含义呢? 举个例子: 定义了一个cronJob, 这个cronJob按照分钟级别运行, 第一个job被创建了, 当第一个job还没有执行完的时候, 第二个job又要被创建了.如果当前的并发策略是allow, 那么就允许任务一和任务二同时运行; 如果当前的并发策略是forbid, 则禁止创建第二个job, 第一个job继续执行; 如果当前的并发策略是replace, 则取消第一个job, 执行第二个job.

  • .spec.suspend :挂起,该字段也是可选的。如果设置为 true,后续所有执行都会被挂起。它对已经开始执行的 Job 不起作用。默认值为 false 这个字段的意思是, 假如有一个cronJob现在不想用了, 但还不想删, 就可以将其设置为暂停状态, 也就是挂起.

  • .spec.successfulJobsHistoryLimit.spec.failedJobsHistoryLimit :历史限制,是可选的字段。它们指定了可以保留多少完成和失败的 Job。默认情况下,它们分别设置为 31。设置限制的值为 0,相关类型的 Job 完成后将不会被保留。 这个字段的含义怎么理解呢? 一个cronJob会创建很多个Job, 可能会有成百上千个, 我们要保留下每一次创建的job的完成结果么? 这些结果都是写入到etcd数据库中的,这样会很浪费资源. 所以, 我们会设置保存几个成功执行的历史job,和几个失败执行的历史job, 默认是3和1.

典型的用法如下所示:

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

CronJob运行的时候也有三连. CronJob会创建Job, Job在创建pod

CrondJob 本身的一些限制: 创建 Job 操作应该是 幂等的

案例演示: 第一步: 准备资源清单

apiVersion: batch/v1
kind: CronJob
metadata:
  name: cronjob-test
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure
  • 定义一个CronJob, 名字是cronJob-test
  • spec.schedule: 指定cronJob创建Job的周期, 这里是每隔1分钟创建1个
  • 在template中创建了一个pod, 并打印欢迎词.
  • pod的重试策略是, 失败了重新执行

第二步: 创建cronJob控制器

kubectl apply -f cronJob-test.yaml

image

image

image

从上图可以看出, 每隔1分钟创建一个job, job在创建一个pod.

第三步:暂停cronJob

kubectl edit cronjob.batch/cronjob-test

image 修改suspend参数为true, 即挂起.

查看cronjob的状态

kubectl get cronjob

此时已经挂起, 不会再创建job了

image