介绍

DaemonSet控制器

1
官网:https://kubernetes.io/zh/docs/concepts/workloads/controllers/daemonset/

通过该控制器的名称我们可以看出它的用法:Daemon,就是用来部署守护进程的,DaemonSet用于在每个 Kubernetes 节点中将守护进程的副本作为后台进程运行,说白了就是在每个节点部署一个 Pod副本,当节点加入到 Kubernetes 集群中,Pod 会被调度到该节点上运行,当节点从集群只能够被移除后,该节点上的这个 Pod 也会被移除,当然,如果我们删除 DaemonSet,所有和这个对象相关的 Pods都会被删除。

应用场景:

  • 集群存储守护程序,如 glusterd、ceph 要部署在每个节点上以提供持久性存储;
  • 节点监控守护进程,如 Prometheus 监控集群,可以在每个节点上运行一个 node-exporter 进程来收集监控节点的信息;
  • 日志收集守护程序,如 fluentd 或 logstash,在每个节点上运行以收集容器的日志
  • 节点网络插件,比如 flannel、calico,在每个节点上运行为 Pod 提供网络服务。

这里需要特别说明的一个就是关于 DaemonSet 运行的 Pod 的调度问题,正常情况下,Pod 运行在哪个节点上是由 Kubernetes 的调度器策略来决定的,然而,由 DaemonSet 控制器创建的 Pod 实际上提前已经确定了在哪个节点上了(Pod创建时指定了.spec.nodeName),所以:

  • 如果node节点存在unshedulable字段,DaemonSet不会在意继续调度;
  • DaemonSet 如果有污点则不会调度Pod
  • DaemonSet 可以创建 Pod,即使调度器还没有启动。

DaemonSet功能:

  • 在每一个Node上运行一个Pod
  • 新加入的Node也同样会自动运行一个Pod

部署 filebeat Pod

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
[root@pool1 data]# cat daemonset-filebeat.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: filebeat
namespace: kube-system
spec:
selector:
matchLabels:
app: filebeat
template:
metadata:
labels:
app: filebeat
spec:
containers:
- name: firebeat
image: elastic/filebeat:7.3.2
volumeMounts:
- name: filebeat-log
mountPath: /filebeat_log
volumes:
- name: filebeat-log
hostPath:
path: /var/lib/docker/containers

创建

1
2
[root@pool1 data]# kubectl apply -f daemonset-filebeat.yaml
daemonset.apps/daemonset-filebeat.yaml created

查看pod状态

1
2
3
4
5
6
7
8
9
10
[root@pool1 yaml]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
pool1 Ready control-plane,master 40d v1.21.0
pool2 Ready,`SchedulingDisabled` <none> 40d v1.21.0
pool3 Ready <none> 40d v1.21.0
# 可以看到pool2节点已经有unshedulable字段了
[root@pool1 data]# kubectl get pods -n kube-system -o wide | grep filebeat
filebeat-j78mf 1/1 Running 0 7m7s 10.244.52.236 pool2 <none> <none>
filebeat-vrbd7 1/1 Running 0 7m7s 10.244.206.48 pool3 <none> <none>
# filebeat依然还会将pod调度到pool2节点上(如果是其他控制器就不会调度过去了)

我们观察可以发现除了 pool1节点之外的2个节点上都有一个相应的 Pod 运行,因为 master 节点上默认被打上了污点,所以默认情况下不能调度普通的 Pod 上去。

集群中的 Pod 和 Node 是一一对应d的,而 DaemonSet 会管理全部机器上的 Pod 副本,负责对它们进行更新和删除。

那么,DaemonSet 控制器是如何保证每个 Node 上有且只有一个被管理的 Pod 呢?

  • 首先控制器从 Etcd 获取到所有的 Node 列表,然后遍历所有的 Node。
  • 根据资源对象定义是否有调度相关的配置,然后分别检查 Node 是否符合要求。
  • 在可运行 Pod 的节点上检查是否已有对应的 Pod,如果没有,则在这个 Node 上创建该 Pod;如果有,并且数量大于 1,那就把多余的 Pod 从这个节点上删除;如果有且只有一个 Pod,那就说明是正常情况。