控制器-Job: 只要完成就立即退出,不需要重启或重建。
控制器 - Job
Kubernetes中的 Job 对象将创建一个或多个 Pod,并确保指定数量的 Pod 可以成功执行到进程正常结束:
- 当 Job 创建的 Pod 执行成功并正常结束时,Job 将记录成功结束的 Pod 数量
- 当成功结束的 Pod 达到指定的数量时,Job 将完成执行
- 删除 Job 对象时,将清理掉由 Job 创建的 Pod
一个简单的例子是:创建一个 Job 对象用来确保一个 Pod 的成功执行并结束。在第一个 Pod 执行失败或者被删除(例如,节点硬件故障或机器重启)的情况下,该 Job 对象将创建一个新的 Pod 以重新执行。
当然,也可以使用 Job 对象并行执行多个 Pod。
运行一个Job的例子
在下面这个 Job 的例子中,Pod 执行了一个跟 π 相关的计算,并打印出最终结果,该计算大约需要 10 秒钟执行结束。
1 | apiVersion: batch/v1 |
创建Job
1 | [root@k8s-master 0407]# kubectl apply -f job1.yaml |
查看已创建的Job
1 | [root@k8s-master 0407]# kubectl get job |
执行以下命令可获得该 Job 所有 Pod 的名字:
1 | [root@k8s-master 0407]# pods=$(kubectl get pods --selector=job-name=pi --output=jsonpath='{.items[*].metadata.name}') |
执行以下命令可查看 Pod 的日志:
1 | [root@k8s-master 0407]# kubectl logs $pods |
编写Job的定义
与所有的 Kubernetes 对象一样,Job 对象的 YAML 文件中,都需要包括如下三个字段:
.apiVersion.kind.metadata
Job 对象的 YAML 文件,还需要一个 .spec 字段。
Pod Template
除了 Pod 所需的必填字段之外,Job 中的 pod template 必须指定
- 合适的标签
.spec.template.spec.labels - 指定合适的[重启策略 restartPolicy
.spec.template.spec.restartPolicy,此处只允许使用Never和OnFailure两个取值
处理Pod和容器的失败
Pod 中的容器可能会因为多种原因执行失败,例如:
- 容器中的进程退出了,且退出码(exit code)不为 0
- 容器因为超出内存限制而被 Kill
- 其他原因
如果 Pod 中的容器执行失败,且 .spec.template.spec.restartPolicy = "OnFailure",则 Pod 将停留在该节点上,但是容器将被重新执行。此时,应用程序需要处理在原节点(失败之前的节点)上重启的情况。或者,设置为 .spec.template.spec.restartPolicy = "Never"。
整个 Pod 也可能因为多种原因执行失败,例如:
- Pod 从节点上被驱逐(节点升级、重启、被删除等)
- Pod 的容器执行失败,且
.spec.template.spec.restartPolicy = "Never"
当 Pod 执行失败时,Job 控制器将创建一个新的 Pod
Pod失败重试
Pod backoff failure policy
某些情况下(例如,配置错误),可以在 Job 多次重试仍然失败的情况下停止该 Job。此时,可通过 .spec.backoffLimit 来设定 Job 最大的重试次数。该字段的默认值为 6.
Job 中的 Pod 执行失败之后,Job 控制器将按照一个指数增大的时间延迟(10s,20s,40s … 最大为 6 分钟)来多次重新创建 Pod。如果没有新的 Pod 执行失败,则重试次数的计数将被重置。
Job的终止和清理
当 Job 完成后:
- 将不会创建新的 Pod
- 已经创建的 Pod 也不会被清理掉。此时,您仍然可以继续查看已结束 Pod 的日志,以检查 errors/warnings 或者其他诊断用的日志输出
- Job 对象也仍然保留着,以便您可以查看该 Job 的状态
- 由用户决定是否删除已完成的 Job 及其 Pod
- 可通过
kubectl命令删除 Job,例如:kubectl delete jobs/pi或者kubectl delete -f job.yaml - 删除 Job 对象时,由该 Job 创建的 Pod 也将一并被删除
- 可通过
Job 通常会顺利的执行下去,但是在如下情况可能会非正常终止:
- 某一个 Pod 执行失败(且
restartPolicy=Never) - 或者某个容器执行出错(且
restartPolicy=OnFailure)- 此时,Job 按照处理Pod和容器的失败中
.spec.bakcoffLimit描述的方式进行处理 - 一旦重试次数达到了
.spec.backoffLimit中的值,Job 将被标记为失败,且尤其创建的所有 Pod 将被终止
- 此时,Job 按照处理Pod和容器的失败中
- Job 中设置了
.spec.activeDeadlineSeconds。该字段限定了 Job 对象在集群中的存活时长,一旦达到.spec.activeDeadlineSeconds指定的时长,该 Job 创建的所有的 Pod 都将被终止,Job 的 Status 将变为type:Failed、reason: DeadlineExceeded
Job的自动清理
系统中已经完成的 Job 通常是不在需要里的,长期在系统中保留这些对象,将给 apiserver 带来很大的压力。如果通过更高级别的控制器(例如 CronJobs)来管理 Job,则 CronJob 可以根据其中定义的基于容量的清理策略自动清理Job。
TTL 机制
除了 CronJob 之外,TTL 机制是另外一种自动清理已结束Job(Completed 或 Finished)的方式:
- TTL 机制由 TTL 控制器 提供
- 在 Job 对象中指定
.spec.ttlSecondsAfterFinished字段可激活该特性
当 TTL 控制器清理 Job 时,TTL 控制器将删除 Job 对象,以及由该 Job 创建的所有 Pod 对象。
1 | apiVersion: batch/v1 |
字段解释 ttlSecondsAfterFinished:
- Job
pi-with-ttl的ttlSecondsAfterFinished值为 100,则,在其结束100秒之后,将可以被自动删除 - 如果
ttlSecondsAfterFinished被设置为0,则 TTL 控制器在 Job 执行结束后,立刻就可以清理该 Job 及其 Pod - 如果
ttlSecondsAfterFinished值未设置,则 TTL 控制器不会清理该 Job