k8s入门教程八:Pod控制器之DaemonSet、Job与CronJob

DaemonSet

DaemonSet简介

DaemonSet守护进程简称DS,适用于在所有node节点或部分节点运行一个daemon守护进程,,DaemonSet具有如下特点:

  • DaemonSet确保所有节点运行一个Pod副本
  • 指定节点运行一个Pod副本,通过标签选择器或者节点亲和性
  • 新增节点会自动在节点增加一个Pod
  • 移除节点时垃圾回收机制会自动清理Pod

DaemonSet适用于每个node节点均需要部署一个守护进程的场景,常见的场景例如:

  • 日志采集agent,如fluentd或logstash
  • 监控采集agent,如Prometheus Node Exporter,Sysdig Agent,Ganglia gmond
  • 分布式集群组件,如Ceph MON,Ceph OSD,glusterd,Hadoop Yarn NodeManager等
  • k8s必要运行组件,如网络flannel,weave,calico,kube-proxy等

安装k8s时默认在kube-system命名空间已经安装了有两个DaemonSet,分别为网络插件和kube-proxy,分别负责overlay网络的互通和service代理的实现

1
2
3
4
[root@master ~]# kubectl get ds -n kube-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
kube-proxy 3 3 2 3 2 beta.kubernetes.io/os=linux 57d
weave-net 3 3 2 3 2 <none> 57d

DaemonSet定义

DaemonSet的定义和Deployment定义使用相类似,需要定义apiVersion,Kind,metadata和spec属性信息,spec中不需要定义replicas个数,spec.template即定义DS生成容器的模版信息,如下是运行一个fluentd-elasticsearch镜像容器的daemon守护进程,运行在每个node上通过fluentd采集日志上报到ElasticSearch。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
apiVersion: apps/v1              #api版本信息
kind: DaemonSet #类型为DaemonSet
metadata: #元数据信息
name: fluentd-elasticsearch
namespace: kube-system #运行的命名空间
labels:
k8s-app: fluentd-logging
spec: #DS模版
selector:
matchLabels:
name: fluentd-elasticsearch
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers: #容器信息
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
resources: #resource资源
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts: #挂载存储,agent需要到这些目录采集日志
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
terminationGracePeriodSeconds: 30
volumes: #将主机的目录以hostPath的形式挂载到容器Pod中。
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers

DaemonSet支持滚动更新,即先终止旧的pod,再创建一个新的pod,逐步进行替换的。

DaemonSet实例

ds-demo.yaml如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: redis
role: logstor
template:
metadata:
labels:
app: redis
role: logstor
spec:
containers:
- name: redis
image: redis:4.0-alpine
ports:
- name: redis
containerPort: 6379
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: filebeat-ds
namespace: default
spec:
selector:
matchLabels:
app: filebeat
release: stable
template:
metadata:
labels:
app: filebeat
release: stable
spec:
containers:
- name: filebeat
image: ikubernetes/filebeat:5.6.5-alpine
env:
- name: REDIS_HOST
value: redis.default.svc.cluster.local
- name: REDIS_LOG_LEVEL
value: info

如上,filebeat-ds是由环境变量REDIS_HOST与redis通信的。创建所需要的资源:

1
2
kubectl apply -f ds-demo.yaml
kubectl expose deployment redis --port=6379

测试redis是否收到日志:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
[root@master k8s_study]# kubectl exec -it filebeat-ds-mt4fx -- /bin/sh
/ # ps
PID USER TIME COMMAND
1 root 0:02 /usr/local/bin/filebeat -e -c /etc/filebeat/filebeat.yml
16 root 0:00 /bin/sh
24 root 0:00 ps
/ # cat /etc/filebeat/filebeat.yml
filebeat.registry_file: /var/log/containers/filebeat_registry
filebeat.idle_timeout: 5s
filebeat.spool_size: 2048

logging.level: info

filebeat.prospectors:
- input_type: log
paths:
- "/var/log/containers/*.log"
- "/var/log/docker/containers/*.log"
- "/var/log/startupscript.log"
- "/var/log/kubelet.log"
- "/var/log/kube-proxy.log"
- "/var/log/kube-apiserver.log"
- "/var/log/kube-controller-manager.log"
- "/var/log/kube-scheduler.log"
- "/var/log/rescheduler.log"
- "/var/log/glbc.log"
- "/var/log/cluster-autoscaler.log"
symlinks: true
json.message_key: log
json.keys_under_root: true
json.add_error_key: true
multiline.pattern: '^\s'
multiline.match: after
document_type: kube-logs
tail_files: true
fields_under_root: true

output.redis:
hosts: ${REDIS_HOST:?No Redis host configured. Use env var REDIS_HOST to set host.}
key: "filebeat"
/ # echo $REDIS_HOST
redis.default.svc.cluster.local
/ # ping $REDIS_HOST
PING redis.default.svc.cluster.local (10.111.198.19): 56 data bytes
^C
--- redis.default.svc.cluster.local ping statistics ---
4 packets transmitted, 0 packets received, 100% packet loss
/ #
/ # ^C
/ # command terminated with exit code 130



[root@master ~]# kubectl exec -it redis-646cf89449-kgz7g -- /bin/sh
/data # ls
/data # redis-cli -h redis
redis:6379> KEYS * #由于redis在filebeat后面才启动,日志可能已经发走了,所以查看key为空
(empty list or set)
redis:6379>

Job

Job简介

Jobs是kubernetes中实现一次性计划任务的Pod控制器—JobController,通过控制Pod来执行任务,其特点为:

  • 创建Pod运行特定任务,确保任务运行完成
  • 任务运行期间节点异常时会自动重新创建Pod
  • 支持并发创建Pod任务数和指定任务数

Jobs任务运行方式有如下三种:

  • 运行单个Jobs任务,一般运行一个pod,pod运行结束任务运行完成;
  • 运行特定数量的任务,通过completion指定总计运行任务;
  • 并发运行任务,通过parallelism指定并发数

运行单个Jobs任务

定义一个jobs任务,通过在command中运行特定一个脚本,将当前的时间打印100次:

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(20)"]
restartPolicy: Never #设置为Never,jobs任务运行完毕即可完成
backoffLimit: 4

运行如下:

1
2
3
4
5
6
7
8
[root@master ~]# kubectl get jobs.batch
NAME COMPLETIONS DURATION AGE
pi 1/1 13m 48m
[root@master ~]# kubectl get pod pi-mqxz7
NAME READY STATUS RESTARTS AGE
pi-mqxz7 0/1 Completed 0 45m
[root@master ~]# kubectl logs pi-mqxz7
3.14159265358979323846

YMAL文件重要字段:

  • spec.template格式同Pod
  • RestartPolicy仅支持Never或OnFailure
  • 单个Pod时,默认Pod成功运行后Job即结束
  • .spec.completions 标志Job结束需要成功运行的Pod个数,默认为1
  • .spec.parallelism 标志并行运行的Pod的个数,默认为1
  • spec.activeDeadlineSeconds 标志失败Pod的重试最大时间,超过这个时间不会继续重试

CronJobs

CronJobs简介

CronJobs用于实现类似Linux下的cronjob周期性计划任务,CronJobs控制器通过时间线创建Jobs任务,从而完成任务的执行处理,其具有如下特点:

  • 实现周期性计划任务
  • 调用Jobs控制器创建任务
  • CronJobs任务名称小于52个字符
  • 应用场景如:定期备份,周期性发送邮件

CronJobs可通过schedule指定任务运行的周期,其使用参数和cronjob类似,分别使用:分时日月星5个参数表示周期性,其中*表示任意时间点,/表示每隔多久,-表示范围

  • 分钟 范围为0-59
  • 小时 范围为0-23
  • 日期 范围为1-31
  • 月份 范围为1-12
  • 星期 范围为0-7,其中0和7表示星期日

举例子说明:

  • */1 * * * * 表示每隔1分钟运行任务
  • 1 0 * * 6-7 表示每周六日的0点01分运行任务

其用法跟crontab类似。

运行Cronjobs任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure

上述yaml等同于:

1
kubectl run hello --schedule="*/1 * * * *" --restart=OnFailure --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster"

加上 -o yaml --dry-run可以看到跟上面的yaml基本上是等同的。

yaml字段说明:

  • .spec.schedule :调度,必需字段,指定任务运行周期,格式同 Cron
  • .spec.jobTemplate :Job 模板,必需字段,指定需要运行的任务,格式同 Job
  • .spec.startingDeadlineSeconds :启动 Job 的期限(秒级别),该字段是可选的。如果因为任何原因而错过了被调度的时间,那么错过执行时间的 Job 将被认为是失败的。如果没有指定,则没有期限
  • .spec.concurrencyPolicy :并发策略,该字段也是可选的。它指定了如何处理被 Cron Job 创建的 Job 的 并发执行。只允许指定下面策略中的一种:
    • Allow (默认):允许并发运行 Job
    • Forbid :禁止并发运行,如果前一个还没有完成,则直接跳过下一个
    • Replace :取消当前正在运行的 Job,用一个新的来替换
    • 注意,当前策略只能应用于同一个 Cron Job 创建的 Job。如果存在多个 Cron Job,它们创建的 Job 之间总 是允许并发运行。
  • .spec.suspend :挂起,该字段也是可选的。如果设置为 true ,后续所有执行都会被挂起。它对已经开始 执行的 Job 不起作用。默认值为 false
  • .spec.successfulJobsHistoryLimit 和 .spec.failedJobsHistoryLimit :历史限制,是可选的字段。它 们指定了可以保留多少完成和失败的 Job。默认情况下,它们分别设置为 3 和 1 。设置限制的值为 0 ,相 关类型的 Job 完成后将不会被保留。

运行如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@master ~]# kubectl create -f cronjob.yaml
cronjob.batch/hello created
[root@master ~]# kubectl get cronjobs.batch -w
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
hello */1 * * * * False 0 59s 112s
hello */1 * * * * False 1 6s 119s
[root@master ~]# kubectl get pod |grep hello
hello-1581133500-ptlfl 0/1 Completed 0 95s
hello-1581133560-8mk5x 0/1 Completed 0 34s
[root@master ~]#
[root@master ~]# kubectl logs hello-1581133500-ptlfl
Sat Feb 8 03:45:14 UTC 2020
Hello from the Kubernetes cluster
[root@master ~]# kubectl logs hello-1581133560-8mk5x
Sat Feb 8 03:46:14 UTC 2020
Hello from the Kubernetes cluster
[root@master ~]# kubectl delete cronjobs.batch hello
cronjob.batch "hello" deleted

参考资料

  • 本文作者: wumingx
  • 本文链接: https://www.wumingx.com/k8s/kubernetes-DaemonSet.html
  • 本文主题: k8s入门教程八:Pod控制器之DaemonSet、Job与CronJob
  • 版权声明: 本站所有文章除特别声明外,转载请注明出处!如有侵权,请联系我删除。
0%