DeamonSets类似于Replica Sets,因为它们可以帮助我们部署多个pod实例,但是它在Kubernetes集群的每个节点上只运行一个pod副本。
DaemonSets确保所有(或部分)节点运行Pod的副本。随着节点被添加到集群中,pod也被添加到集群中,当节点从集群中移除时,这些pod将会被删除。
下面是一些典型的daemonset用例:
在一个简单的情况下,可以为每种不同类型的守护进程使用一个Daemonset(覆盖所有节点)。我们也可以为单一类型的守护进程配置多个daemonset,使用不同的标志、内存、CPU等。
Kube-dns的职责是使用其名称发现服务IP,并且只需Kube-dns的一个副本就足以将服务名称解析为其IP。因此,我们将kube-dns作为一个部署,因为我们不需要在每个节点上都部署kube-dns。
守护进程控制器管理像部署、复制集和状态集这样的pod。
在本例中,我们将在集群的每个节点上部署prometheus节点导出代理pod。
下面是一个DaemonSet manifest文件的示例:
root@kube-master:~/DaemonSet# cat daemonset_demo.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: daemonset-demo-prometheus
spec:
selector:
matchLabels:
tier: monitoring
name: prometheus-exporter # Label selector that determines which Pods belong to the DaemonSet
template:
metadata:
labels:
tier: monitoring # Pod template's label selector
name: prometheus-exporter # Pod template's label selector
spec:
containers:
- name: prometheus
image: prom/node-exporter
ports:
- containerPort: 80
关于daemonset_demo.yml的说明
使用kubectl命令创建DaemonSet
root@kube-master:~/DaemonSet# kubectl apply -f daemonset_demo.yml --record
daemonset.apps/daemonset-demo-prometheus created
--record 表示将跟踪通过每次编辑所做的更改
验证创建的DaemonSet
root@kube-master:~/DaemonSet# kubectl get daemonsets daemonset-demo-prometheus -o wide
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR
daemonset-demo-prometheus 3 3 3 3 3 2m13s prometheus prom/node-exporter name=prometheus-exporter,tier=monitoring
获取更多有关DaemonSet的详细信息:
root@kube-master:~/DaemonSet# kubectl describe daemonsets daemonset-demo-prometheus
Name: daemonset-demo-prometheus
Selector: name=prometheus-exporter,tier=monitoring
Node-Selector:
Labels:
Annotations: deprecated.daemonset.template.generation: 1
kubernetes.io/change-cause: kubectl apply --filename=daemonset_demo.yml --record=true
Desired Number of Nodes Scheduled: 3
Current Number of Nodes Scheduled: 3
Number of Nodes Scheduled with Up-to-date Pods: 3
Number of Nodes Scheduled with Available Pods: 3
Number of Nodes Misscheduled: 0
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: name=prometheus-exporter
tier=monitoring
Containers:
prometheus:
Image: prom/node-exporter
Port: 80/TCP
Host Port: 0/TCP
Environment:
Mounts:
Volumes:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 2m52s daemonset-controller Created pod: daemonset-demo-prometheus-2l57n
Normal SuccessfulCreate 2m52s daemonset-controller Created pod: daemonset-demo-prometheus-8sgfk
Normal SuccessfulCreate 2m52s daemonset-controller Created pod: daemonset-demo-prometheus-ffbp6
在Pod中获取更多DaemonSet的信息
root@kube-master:~/DaemonSet# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
daemonset-demo-prometheus-2l57n 1/1 Running 0 5m1s 192.168.221.241 kube-master
daemonset-demo-prometheus-8sgfk 1/1 Running 0 5m1s 192.168.194.4 kube-worker1
daemonset-demo-prometheus-ffbp6 1/1 Running 0 5m1s 192.168.161.240 kube-worker2
从上面的输出可以看到,部署了3个pod。主节点和工作节点各一个。在这里,守护进程确保每个节点有一个pod,而不使用任何关联规则。
像所有其他Kubernetes对象一样,DaemonSet也可以通过使用创建它的相同的manifest file或使用kubectl命令来删除。
root@kube-master:~/DaemonSet# kubectl delete -f daemonset_demo.yml
daemonset.apps "daemonset-demo-prometheus" deleted
root@kube-master:~/DaemonSet# kubectl delete daemonsets daemonset-demo-prometheus
daemonset.apps "daemonset-demo-prometheus" deleted
可以通过更改以下规格来更新DaemonSet:
我们可以使用以下两种更新策略来更新守护进程:
rolllingupdate —这是默认策略,将在配置更改时应用。它会自动删除并重新创建DaemonSet pod。
OnDelete -当使用此策略时,Kubernetes不会自动删除DaemonSet pods,并在配置更改时重新创建它们。我们必须手动删除pod,然后控制器将创建一个带有新更改的新pod。
DaemonSet确保所有符合条件的节点都运行Pod的副本。通常,Kubernetes调度器决定Pod运行的节点。但是,DaemonSet pod是由DaemonSet控制器创建和调度的。
但这会导致以下问题:
那么如何解决这种问题?
ScheduleDaemonSetPods允许我们使用默认调度器而不是DaemonSet控制器来调度DaemonSet,通过将NodeAffinity 添加到DaemonSet pods中,而不是.spec.nodename。然后使用默认调度器将pod绑定到目标主机。
下面的清单文件使用节点关联规则创建一个pod。
apiVersion: v1
kind: Pod
metadata:
name: web-servers
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: workload
operator: In
values:
- staging
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
如果你观察上面的main file,我们有一个使用requiredduringscheduleingignoredduringexecution类型节点亲和力和表达式key-value作为workload: staging调度的Pod。这意味着pod将只被安排在具有workload=staging标签的节点上。
Daemon Pods 允许污点和容忍度。node.kubernetes.io/ unscheable:将NoSchedule容忍自动添加到DaemonSet Pods中。默认调度程序在调度DaemonSet pod时忽略不可调度的节点。
我们可以通过不同的方式与DaemonSets创建的pod进行通信。
当我们想要部署需要在所有或某些节点上运行的应用程序时,daemonset非常有用。此类任务的示例包括日志收集守护进程(如logstash)、存储守护进程(如ceph)和节点监控守护进程(如prometheus node-export)等。