每天5分钟玩转Kubernetes | Job

Posted COCOgsta

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每天5分钟玩转Kubernetes | Job相关的知识,希望对你有一定的参考价值。

书籍来源:cloudman《每天5分钟玩转Kubernetes》

一边学习一边整理老师的课程内容及试验笔记,并与大家分享,侵权即删,谢谢支持!


容器按照持续运行的时间可分为两类:服务类容器和工作类容器。

服务类容器通常持续提供服务,需要一直运行,比如HTTP Server、Daemon等。工作类容器则是一次性任务,比如批处理程序, 完成后容器就退出。

Kubernetes的Deployment、ReplicaSet和DaemonSet都用于管理服务类容器;对于工作类容器,我们使用Job。

先看一个简单的Job配置文件myjob.yml,如下所示。

[root@k8s-master ~]# cat myjob.yml 
apiVersion: batch/v1
kind: Job
metadata:
  name: myjob
spec:
  template:
    metadata:
      name: myjob
    spec:
      containers:
      - name: hello
        image: busybox
        command: ["echo", "hello k8s job! "]
      restartPolicy: Never
[root@k8s-master ~]# 

① batch/v1是当前Job的apiVersion。

② 指明当前资源的类型为Job。

③ restartPolicy指定什么情况下需要重启容器。对于Job,只能设置为Never或者OnFailure。对于其他controller(比如Deployment),可以设置为Always。

通过kubectl apply -f myjob.yml启动Job,如图所示。

通过kubectl get job查看Job的状态,如图所示。

COMPLETIONS为1,表示按照预期启动了一个 Pod,并且已经成功执行。通过kubectl get pod查看Pod的状态,如图所示。

因为Pod执行完毕后容器已经退出,可以看到Completed状态。

通过kubectl logs可以查看Pod的标准输出,如图所示。

5.3.1 Pod失败的情况

以上是Pod成功执行的情况,如果Pod失败了会怎么样呢?

我们做个试验,修改myjob.yml,故意引入一个错误,如图所示。

[root@k8s-master ~]# cat myjob.yml 
apiVersion: batch/v1
kind: Job
metadata:
  name: myjob
spec:
  template:
    metadata:
      name: myjob
    spec:
      containers:
      - name: hello
        image: busybox
        command: ["invalid_command", "hello k8s job! "]
      restartPolicy: Never
[root@k8s-master ~]# 

先删除之前的Job,如图所示。

运行新的Job并查看状态,如图所示。

可以看到有多个Pod,状态均不正常。通过kubectl describe pod查看某个Pod的启动日志,如图所示。

日志显示没有可执行程序,符合我们的预期。

下面解释一个现象:为什么kubectl get pod会看到这么多个失败的Pod?

原因是:当第一个Pod启动时,容器失败退出,根据restartPolicy: Never,此失败容器不会被重启,所以Job controller会启动新的Pod。对于我们这个例子,Job controller会一直创建新的Pod。为了终止这个行为,只能删除Job,如图所示。

如果将restartPolicy设置为OnFailure会怎么样?下面我们实践一下,修改myjob.yml后重新启动,如图所示。Job的COMPLETIONS还是0,再看看Pod的情况。

这里只有一个Pod,不过RESTARTS为1,而且不断增加,说明OnFailure生效,容器失败后会自动重启。

5.3.2 Job的并行性

有时我们希望能同时运行多个Pod,提高Job的执行效率。这个可以通过parallelism设置,如下所示。

[root@k8s-master ~]# cat myjob.yml 
apiVersion: batch/v1
kind: Job
metadata:
  name: myjob
spec:
  parallelism: 2
  template:
    metadata:
      name: myjob
    spec:
      containers:
      - name: hello
        image: busybox
        command: ["echo", "hello k8s job! "]
      restartPolicy: OnFailure
[root@k8s-master ~]# 

这里我们将并行的Pod数量设置为2,实践一下,如图所示。 Job一共启动了两个Pod,而且AGE相同,可见是并行运行的。

我们还可以通过completions设置Job成功完成Pod的总数,如下所示。

[root@k8s-master ~]# cat myjob.yml 
apiVersion: batch/v1
kind: Job
metadata:
  name: myjob
spec:
  completions: 6
  parallelism: 2
  template:
    metadata:
      name: myjob
    spec:
      containers:
      - name: hello
        image: busybox
        command: ["echo", "hello k8s job! "]
      restartPolicy: OnFailure
[root@k8s-master ~]# 

上面配置的含义是:每次运行两个Pod,直到总共有6个Pod成功 完成。实践一下,如图所示。

如果不指定 completions和parallelism,默认值均为1。

上面的例子只是为了演示Job的并行特性,实际用途不大。不过现实中确实存在很多需要并行处理的场景。比如批处理程序,每个副本(Pod)都会从任务池中读取任务并执行,副本越多,执行时间就越短,效率就越高。这种类似的场景都可以用Job来实现。

5.3.3 定时Job

Linux中有cron程序定时执行任务,Kubernetes的CronJob提供了类似的功能,可以定时执行Job。CronJob配置文件示例如下所示。

[root@k8s-master ~]# cat cronjob.yml 
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            command: ["echo", "hello k8s job!"]
          restartPolicy: OnFailure
[root@k8s-master ~]# 

① batch/v2alpha1是当前CronJob的apiVersion。

② 指明当前资源的类型为CronJob。

③ schedule指定什么时候运行Job,其格式与Linux cron一致。这里*/1 * * * *的含义是每一分钟启动一次。

④ jobTemplate定义Job的模板,格式与前面的Job一致。

接下来通过kubectl apply创建CronJob,如图所示。

这次成功了。通过kubectl get cronjob查看CronJob的状态,如图所示。

等待几分钟,然后通过kubectl get jobs查看Job的执行情况,如图所示。

可以看到每隔一分钟就会启动一个Job。执行kubectl logs可查看某个Job的运行日志,如图所示。

以上是关于每天5分钟玩转Kubernetes | Job的主要内容,如果未能解决你的问题,请参考以下文章

每天5分钟玩转Kubernetes | 默认的健康检查

每天5分钟玩转Kubernetes | 汇总

回滚 - 每天5分钟玩转 Docker 容器技术(141)

每天5分钟玩转Kubernetes | Kubernetes集群日志管理

每天5分钟玩转Kubernetes | Kubernetes Dashboard安装

每天5分钟玩转Kubernetes | Deployment