一、前言
前一章节我们介绍了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初级入门系列之十二-计算资源管理