一、前言

      前一章节我们介绍了RC,RS控制器,其主要针对在线业务Pod部署,比如nginx,这些业务是需要确保7*24持续运行的,还有一类离线业务,比如定时任务,大数据离线计算等,在有任务的才需要启动,且任务完成后可以销毁,释放资源。很显然,这类使用RC,RS控制器并不合适,K8S为这类任务提供了Job控制器。

     还有一类业务,比如日志,监控,安全等,需要固定常驻在某个节点,且不需要多副本,也不适合使用RC,RS控制器,K8S为这类任务提供了Daemonset控制器。

二、Job

Job为了完成某次任务,创建并启动Pod,当任务完成后,销毁Pod。

1、Job创建

我们先看下Job的yaml文件,内容如下:

[root@k8s-master yaml]# cat job-pod.yaml 
apiVersion: batch/v1
kind: Job
metadata:
  name: job-pod
spec:
  template:
    spec:
     restartPolicy: OnFailure
     containers:
     - name: echo-job
       image: busybox
       args:
       - /bin/sh
       - -c
       - echo ok;sleep 30

与RC一样,Job的yaml也是嵌套了Pod的定义,其嵌套关系如下:

     这里使用busybox 镜像,执行"echo ok",并sleep 30s后退出。需要注意的是,在Pod层级的restartPolicy不能定义为Always(Always就是一直保持在线)。

我们执行下该文件,创建job

[root@k8s-master yaml]# kubectl apply -f job-pod.yaml 
job.batch/job-pod created
[root@k8s-master yaml]# kubectl get job
NAME      COMPLETIONS   DURATION   AGE
job-pod   0/1           18s        18s

再看下Job创建的pod

[root@k8s-master yaml]# kubectl get pod
[root@k8s-master yaml]# kubectl get pod
NAME                                READY   STATUS             RESTARTS           AGE
job-pod-6wnb7                       1/1     Running            0                  4s

生成了以Job名称为前缀的Pod,30s后,我们在查看下pod,该pod已经完成。

[root@k8s-master yaml]# kubectl get pod
NAME                                READY   STATUS             RESTARTS           AGE
job-pod-6wnb7                       0/1     Completed          0                  92m

2、运行多个实例

      实际工程中,我们可能需要启动多个pod实例同时完成某项任务,可以配置Job的如下两个属性:

completions:需要运行的pod数量。

parallelism:允许并发运行的 Pod 数量,默认为1,即顺序执行。

改写下前面的yaml文件,设置 completions为5,parallelism为2

[root@k8s-master yaml]# cat job-pod.yaml 
apiVersion: batch/v1
kind: Job
metadata:
  name: job-pod
spec:
  completions: 5  
  parallelism: 2
  template:
    spec:
     restartPolicy: OnFailure 
     containers:
     - name: echo-job
       image: busybox
       args:
       - /bin/sh
       - -c
       - echo ok;sleep 30;

创建job并查看

[root@k8s-master yaml]# kubectl apply -f job-pod.yaml 
job.batch/job-pod created
[root@k8s-master yaml]# kubectl get job
NAME      COMPLETIONS   DURATION   AGE
job-pod   0/5           10s        10s

 监控 pod的运行实例,启动并保持两个pod并行运行

[root@k8s-master yaml]# kubectl get pod
NAME                                READY   STATUS             RESTARTS            AGE
job-pod-qc9bl                       1/1     Running            0                   20s
job-pod-tk5bd                       1/1     Running            0                   20s

最终完成5个pod

[root@k8s-master yaml]# kubectl get pod --watch
NAME                                READY   STATUS      RESTARTS           AGE
job-pod-qc9bl                       0/1     Completed   0                  3m53s
job-pod-rrjhf                       0/1     Completed   0                  2m25s
job-pod-tk5bd                       0/1     Completed   0                  3m53s
job-pod-zmltq                       0/1     Completed   0                  3m21s
job-pod-zmrc6                       0/1     Completed   0                  3m5s

另外还有以下两个属性控制Pod的运行,大家可以自行尝试下。

activeDeadlineSeconds:设置 Pod 运行的超时时间。

backoffLimit:设置 Pod 的失败重试次数。

三、CronJob

     Job资源创建时会立即执行,但一些批处理任务需要在特定的时间内运行,或者定时循环执行,这类任务称之为cron任务,K8S提供了CronJob控制器支持这种任务。

    CronJob的定义较简单,在Job模板外层再增加个schedule,配置cron表达式,我们看下yaml文件。

[root@k8s-master yaml]# cat cronjob-pod.yaml 
apiVersion: batch/v1
kind: CronJob
metadata:
  name: cronjob-pod
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure 
          containers:
          - name: echo-job
            image: busybox
            args:
            - /bin/sh
            - -c
            - echo ok;sleep 30;

同样的,我们来图示下嵌套模型

    在ConJob的层级中,我们增加了schedule属性,该属性支持cron表达式设置定时规则,关于cron表达式网上有很多资料,这里简单描述下,其时间列表从左到右,分别表示分钟,小时,每月中的第几天,月,星期几。比如本例中,表示间隔一分钟(从执行开始时间算起 ),执行一次。

执行该文件,创建cronjob对象

[root@k8s-master yaml]# kubectl apply -f cronjob-pod.yaml 
cronjob.batch/cronjob-pod created
[root@k8s-master yaml]# kubectl get cronjob
NAME          SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob-pod   */1 * * * *   False     0        <none>          10s

执行一段时间后,看下pod的情况

[root@k8s-master yaml]# kubectl get pod
NAME                                READY   STATUS             RESTARTS            AGE
cronjob-pod-27930314-jv726          0/1     Completed          0                   3m38s
cronjob-pod-27930315-hqg2s          0/1     Completed          0                   2m38s
cronjob-pod-27930316-vq5pc          0/1     Completed          0                   98s
cronjob-pod-27930317-ts8fn          1/1     Running            0                   38s

按照cron的配置,每分钟调度一次job,创建并启动pod执行。

四、Daemonset

在实际工程中,有以下几种类型业务:

  • 监控,监控节点的运行状态,并实时上报。
  • 日志采集,采集节点上产生的日志数据。
  • 安全应用,对节点进行安全扫描,管控审计等

这些业务的Pod,有以下几个共同特点

  • 与固定的节点绑定,不会漂移。
  • 常驻的守护进程,每个节点只存在一个,不会有多副本。

   为了满足这些特性,K8S提供了Daemonset控制器,其目标是在集群的每个节点上运行且仅运行一个 Pod,为节点配置一条"看门狗"。

1、Daemonset创建

我们先看下Daemonset的yaml文件

[root@k8s-master yaml]# cat nginx-daemonset.yaml 
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx-daemonset
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: nginx-daemonset
  template:
    metadata:
      labels:
        app: nginx-daemonset
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

同样的我们画出嵌套模型

     可以与K8S初级入门系列之六-控制器(RC/RS/Deployment)章节的deployment比较下,其差别在于不需要配置replicas属性。执行结果如下

[root@k8s-master yaml]# kubectl get daemonset
NAME              DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
nginx-daemonset   1         1         1       1            1           <none>          27m
[root@k8s-master yaml]# kubectl get pod -o wide
NAME                                READY   STATUS              RESTARTS           AGE    IP               NODE         NOMINATED NODE   READINESS GATES
nginx-daemonset-pxxb5               1/1     Running             0                  28m    10.244.36.100    k8s-node1    <none>           <none>

      可以看到,在节点(k8s-node1节点)上正确的创建一个daemonset Pod,但我们的环境中有两个节点,还有一个master节点,是没有部署的,是为什么呢?

   在K8S初级入门系列之五-Pod的高级特性章节中,我们了解了污点和容忍度的概念,正是因为master节点存在node-role.kubernetes.io/master:NoSchedule污点,所以pod无法调度到master节点,当然也包括daemonset创建的Pod,我们可以添加对该污点的容忍度,这样就可以调度了。修改的yaml如下

[root@k8s-master yaml]# cat nginx-daemonset.yaml 
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx-daemonset
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: nginx-daemonset
  template:
    metadata:
      labels:
        app: nginx-daemonset
    spec:
      tolerations:
      - key: "node-role.kubernetes.io/master"
        operator: "Exists"
        effect: "NoSchedule"
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

再看下创建的Pod结果

[root@k8s-master yaml]# kubectl get pod -o wide
NAME                                READY   STATUS             RESTARTS            AGE     IP               NODE         NOMINATED NODE   READINESS GATES
nginx-daemonset-7plhc               1/1     Running            0                   2m6s    10.244.36.122    k8s-node1    <none>           <none>
nginx-daemonset-s2hrs               1/1     Running            0                   2m6s    10.244.235.197   k8s-master   <none>           <none>

可以看到,k8s-master节点也运行了该pod。

五、总结

       本章节我们介绍了Job,CronJob,DaemonSet三种控制器,包括其应用场景和方式。

      Job使用于一次性的任务,执行完成后,Pod资源会释放,一般适用离线计算等场景。可以通过completions,parallelism设置需要运行Pod的总量,以及并行运行Pod的数量。

       CronJob是一种特定类型的Job,可以通过schedule属性,配置cron表达式,实现定时任务的执行。

      DaemonSet控制器实现节点的"看门狗"任务,比如日志采集,监控等,它的特点是每个节点上都固定运行一个Pod,不会漂移,也不会有多副本。

 附:

K8S初级入门系列之一-概述

K8S初级入门系列之二-集群搭建

K8S初级入门系列之三-Pod的基本概念和操作

K8S初级入门系列之四-Namespace/ConfigMap/Secret

K8S初级入门系列之五-Pod的高级特性

K8S初级入门系列之六-控制器(RC/RS/Deployment)

K8S初级入门系列之七-控制器(Job/CronJob/Daemonset)

K8S初级入门系列之八-网络

K8S初级入门系列之九-共享存储

K8S初级入门系列之十-控制器(StatefulSet)

K8S初级入门系列之十一-安全

K8S初级入门系列之十二-计算资源管理

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐