Job控制器

官方文档:https://v1-16.docs.kubernetes.io/zh/docs/concepts/workloads/controllers/jobs-run-completion/

与deployment与DaemonSet控制器管理的守护进程类应用服务不同的是,Job控制器主要用于处理运行一次性的任务,容器中的进程在正常执行结束后不会对其进行重启,而是将Pod对象置于”Completed”(完成)状态,若容器中的进程因错误而终止,则需要根据配置确定是否重启,未运行完成的Pod对象因其所在的节点故障而意外终止后会被重新调度 下面是适合作为Job运行的三种主要任务类型:

  • 非并行Job:通常创建一个Pod直到其成功结束
  • 固定次数的并行Job:设置spec.completions为非0的值,创建多个Pod,直到.spec.completions个Pod成功结束
  • 具有工作队列的并行Job:不指定spec.completions的话,默认为.spec.parallelism,当所有Pod结束并且至少有一个成功时,Job就认为是成功的
    对于非并行Job,可以不设置spec.completions.spec.parallelism。两者均为设置,默认值为1
    对于固定次数的Job,应该将spec.completions设置为所需要的完成数量,.spec.parallelism可以设置,也可以不设置,默认值为1
    对于一个工作队列job,不能设置spec.completions,并且将.spec.parallelism设置一个非负整数

实践中,有的作业任务可能需要运行不止一次,用户可以配置它们以串行或并行的方式运行。总结起来,这种类型的Job控制器对象有两种

  • 单工作队列(work queue)的串行式job:即多个一次性的作业方式串行执行多次作业,直至满足期望的次数,这种Job也可以理解为并行度为1的作业执行方式
  • 多工作队列的并行式job:这种方式可以设置工作对列数,即作业数,每个队列负责运行一个作业,也可以用有限的工作队列运行较多的作业,即工作队列数少于总作业数,相当于运行多个串行作业队列,工作队列数即为同时运行的Pod资源数

创建Job对象

Job控制器的spec字段内嵌的必要字段为template,它的使用方式与Deployment等控制器并无不同。Job会为其Pod对象自动添加”job-name=JOB_NAME”和”controller-uid=UID”标签,并使用标签选择器完成对controller-uid标签的关联。需要注意的是,Job位于API群组,”batch/v1”之内。下面的资源清单文件(job-example.yaml)中定义了一个job控制器,我们为busybox0.1定义了一个command,表示要执行的job命令,重启策略表示重不重启

  1. apiVersion: batch/v1
  2. kind: Job
  3. metadata:
  4. name: job-example
  5. spec:
  6. template:
  7. spec:
  8. containers:
  9. - name: myjob
  10. image: registry.cn-hangzhou.aliyuncs.com/jiangyida/busybox:0.1
  11. command: ["/bin/sh","-c","sleep 30"]
  12. restartPolicy: Never

注意:Pod模板中的spec.restartPolicy默认为”Always”,着对Job控制器来说并不适用,因此必须在Pod模板中将此值设置为”Never”或者”OnFailure”

使用kubectl createkubectl apply命令完成创建后即可查看相关的任务状态 COMPLETIONS字段表示完成的个数,DURATION表示执行的时间

  1. [root@k8s-master01 nginx]# kubectl get jobs job-example
  2. NAME COMPLETIONS DURATION AGE
  3. job-example 1/1 32s 35s
  4. [root@k8s-master01 nginx]#

相关的Pod资源能够以Job控制器名称为标签进行匹配

  1. [root@k8s-master01 nginx]# kubectl get pods -l job-name=job-example
  2. NAME READY STATUS RESTARTS AGE
  3. job-example-9gmrl 0/1 Completed 0 2m30s
  4. [root@k8s-master01 nginx]#

并行式Job

将并行度属性.spec.parallelism的值设置为1,并设置总任务数.spec.completion属性便能够让Job控制器以串行方式运行多任务。下面是一个串行运行5次任务的job控制器示例

  1. apiVersion: batch/v1
  2. kind: Job
  3. metadata:
  4. name: job-multi
  5. spec:
  6. completions: 5
  7. template:
  8. spec:
  9. containers:
  10. - name: myjob
  11. image: registry.cn-hangzhou.aliyuncs.com/jiangyida/busybox:0.1
  12. command: ["/bin/sh","-c","sleep 20"]
  13. restartPolicy: Never

在创建之后或者创建之前,可以在另外一个终端启动资源的列出命令kubectl get pods -l job-name=job-multi --watch来监控其变动

  1. [root@k8s-master01 nginx]# kubectl apply -f job-example.yaml --record
  2. job.batch/job-multi created
  3. [root@k8s-master01 nginx]#
  4. [root@k8s-master01 nginx]# kubectl get jobs job-multi
  5. NAME COMPLETIONS DURATION AGE
  6. job-multi 3/5 69s 69s
  7. [root@k8s-master01 nginx]#
  8. [root@k8s-master01 nginx]# kubectl get jobs job-multi
  9. NAME COMPLETIONS DURATION AGE
  10. job-multi 5/5 107s 118s
  11. [root@k8s-master01 nginx]#
  12. [root@k8s-master01 nginx]# kubectl get pods -l job-name=job-multi --watch
  13. NAME READY STATUS RESTARTS AGE
  14. job-multi-5d89g 0/1 Pending 0 0s
  15. job-multi-5d89g 0/1 Pending 0 0s
  16. job-multi-5d89g 0/1 ContainerCreating 0 0s
  17. job-multi-5d89g 1/1 Running 0 2s
  18. job-multi-5d89g 0/1 Completed 0 22s
  19. job-multi-dbxpx 0/1 Pending 0 0s
  20. job-multi-dbxpx 0/1 Pending 0 0s
  21. job-multi-dbxpx 0/1 ContainerCreating 0 0s
  22. job-multi-dbxpx 1/1 Running 0 1s
  23. job-multi-dbxpx 0/1 Completed 0 21s
  24. job-multi-vclw7 0/1 Pending 0 0s
  25. job-multi-vclw7 0/1 Pending 0 0s
  26. job-multi-vclw7 0/1 ContainerCreating 0 0s
  27. job-multi-vclw7 1/1 Running 0 1s
  28. job-multi-vclw7 0/1 Completed 0 21s
  29. job-multi-bbd98 0/1 Pending 0 0s
  30. job-multi-bbd98 0/1 Pending 0 0s
  31. job-multi-bbd98 0/1 ContainerCreating 0 1s
  32. job-multi-bbd98 1/1 Running 0 1s
  33. job-multi-bbd98 0/1 Completed 0 22s
  34. job-multi-m9fpk 0/1 Pending 0 0s
  35. job-multi-m9fpk 0/1 Pending 0 0s
  36. job-multi-m9fpk 0/1 ContainerCreating 0 0s
  37. job-multi-m9fpk 1/1 Running 0 1s
  38. job-multi-m9fpk 0/1 Completed 0 21s
  39. [root@k8s-master01 nginx]# kubectl get pods -l job-name=job-multi
  40. NAME READY STATUS RESTARTS AGE
  41. job-multi-5d89g 0/1 Completed 0 2m30s
  42. job-multi-bbd98 0/1 Completed 0 86s
  43. job-multi-dbxpx 0/1 Completed 0 2m8s
  44. job-multi-m9fpk 0/1 Completed 0 64s
  45. job-multi-vclw7 0/1 Completed 0 107s
  46. [root@k8s-master01 nginx]#

.spec.parallelism能够定义作业的并行度,将其设置为2或者以上的数值即可实现多队列任务并行执行。同时,如果.spec.completions 使用是默认值1,则表示并行度即作业总数,而如果.spec.completions属性值设置大于.spec.parallelism的属性值,则表示使用多队列串行任务作业模式,例如,将Job-multi控制器的spec字段嵌套命令如下,表示每次以2个队列并行的方式,总共运行5次的作业

  1. apiVersion: batch/v1
  2. kind: Job
  3. metadata:
  4. name: job-multi
  5. spec:
  6. completions: 5
  7. parallelism: 2
  8. template:
  9. spec:
  10. containers:
  11. - name: myjob
  12. image: registry.cn-hangzhou.aliyuncs.com/jiangyida/busybox:0.1
  13. command: ["/bin/sh","-c","sleep 20"]
  14. restartPolicy: Never
  1. [root@k8s-master01 nginx]# kubectl apply -f job-example.yaml --record
  2. job.batch/job-multi created
  3. [root@k8s-master01 nginx]#
  4. [root@k8s-master01 nginx]# kubectl get pods -l job-name=job-multi --watch
  5. NAME READY STATUS RESTARTS AGE
  6. job-multi-gbs57 1/1 Running 0 7s
  7. job-multi-l8487 1/1 Running 0 7s
  8. [root@k8s-master01 nginx]# kubectl get pods -l job-name=job-multi
  9. NAME READY STATUS RESTARTS AGE
  10. job-multi-gbs57 0/1 Completed 0 31s
  11. job-multi-hkbvr 1/1 Running 0 10s
  12. job-multi-l8487 0/1 Completed 0 31s
  13. job-multi-rvglk 1/1 Running 0 9s
  14. [root@k8s-master01 nginx]#
  15. [root@k8s-master01 nginx]# kubectl get jobs job-multi
  16. NAME COMPLETIONS DURATION AGE
  17. job-multi 4/5 47s 47s
  18. [root@k8s-master01 nginx]#
  19. [root@k8s-master01 nginx]# kubectl get pods -l job-name=job-multi
  20. NAME READY STATUS RESTARTS AGE
  21. job-multi-b9zt5 0/1 Completed 0 35s
  22. job-multi-gbs57 0/1 Completed 0 77s
  23. job-multi-hkbvr 0/1 Completed 0 56s
  24. job-multi-l8487 0/1 Completed 0 77s
  25. job-multi-rvglk 0/1 Completed 0 55s
  26. [root@k8s-master01 nginx]#

Job扩容

Job控制器的.spec.parallelism字段定义的并行度表示同时运行的Pod对象数,此属性值支持运行时调整从而改变其队列总数,实现扩容和缩容。使用的命令与此前的Deployment对象相同,即kubectl scale --replicas命令,例如在其运行过程中(未完成之前)将job-multi的并行度扩展未两路

  1. kubectl scale jobs jpb-multi --replicas=2

根据工作节点及资源可用量,适度提高Job的并行度,能够大大提升完成效率,缩短运行时间

删除Job

Job控制器待其Pod资源运行完成后,将不再占用系统资源。用户可按需保留或使用资源删除命令将其删除。不过,如果某job控制器的容器应用总是无法正常结束运行,而其restartPolicy又定为了重启。则它可能会一直处于不停的重启和错误的循环当中。所幸的是,Job控制器提供了两个属性用于抑制这种情况的发生,具体如下

  • .spec.activeDeadlineSeconds<integer>:Job的deadline,用于指定其最大活动时间长度,无论该控制器下有多少Pod,超出此时长的作业都将被终止
  • .spec.backoffLimit<integer>:将作业标记为失败状态之前的重试次数,默认值为6
    例如,下面的配置片段表示其失败重试的次数为3次,并且如果超出100秒的时间还没有执行完成,那么就将其终止
  1. spec
  2. backoffLimit: 3
  3. activeDeadlineSeconds: 100

如果系统中已经完成的job通常不再被需要的话。将它保留在系统中会给API服务器带来压力。如果job由更高级别的控制器管理,比如CronJobs,则job可以由CronJobs基于指定的清理策略来进行删除

清理已经完成的Job的另一个方式是通过使用TTL控制器(文档:https://v1-16.docs.kubernetes.io/zh/docs/concepts/workloads/controllers/ttlafterfinished/) 提供的TTL机制,TTL通过指定Job的.spec.ttlSecondsAfterFinished字段来清理已完成资源 当TTL控制器清理Job时,它将级联删除Job,即删除它的依赖对象,比如Pod将会和Job一起被删除

  1. spec:
  2. ttlSecondsAfterFinished: 100

表示该job在完成后100秒将会被删除。如果此字段为0,那么job将在完成后立即被自动删除掉。如果此字段没有被设置,则Job在完成后将不会被删除。该功能在1.6的版本中处于alpha阶段