探索 Kubernetes 中的 DaemonSet
学习目标
比较 ReplicaSet 与 DaemonSet
为工作负载编写 DaemonSet 清单
Kubernetes 中的 DaemonSet
使用场景
使用 Deployment 时,您必须显式地在集群的每个节点上运行工作负载。一位经验更丰富的同事告诉您,应该改用 DaemonSet。您想了解什么是 DaemonSet 以及它是如何工作的。
Kubernetes 中的 DaemonSet 是什么?
使用 ReplicaSet 时,您可以指定某个 Pod 应在集群中运行多少个副本。但是,您无法决定这些 Pod 运行在哪些节点上。作为容器编排器,Kubernetes 会根据节点上的可用资源来决定 Pod 应调度到哪些节点。然而,在某些情况下,集群中特定的一组节点上必须只运行一个 Pod 副本。
DaemonSet 是一种独特的 Kubernetes 工作负载,它确保某个 Pod 在 Kubernetes 集群的一部分节点上运行。通常,DaemonSet 适用于日志代理、监控代理等服务,或者其他需要在集群中一部分节点上以单副本形式运行的服务。

定义为 DaemonSet 的工作负载不由默认调度器 kube-scheduler 调度。相反,DaemonSet 控制器会默认在每个节点上创建一个 Pod。可以通过指定节点选择器(node selector)来选择一部分节点。随后,DaemonSet 控制器会在每个与所指定节点选择器匹配的节点上创建一个 Pod。
该控制器确保 Pod 在指定的节点上运行。如果该节点被删除,控制器会在新节点上创建新的 Pod。与 kube-scheduler 一样,DaemonSet 控制器也会运行协调循环(reconciliation loop),以确保始终满足期望状态,并在必要时重新调度 Pod。
DaemonSet 清单
查看一个声明了 fluentd 日志代理的简单 DaemonSet 清单:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-daemon
spec:
selector:
matchLabels:
app: fluentd-daemon
template:
metadata:
labels:
app: fluentd-daemon
spec:
containers:
- name: fluentd-daemon
image: fluent/fluentd
...
此示例中未指定显式的节点选择器。因此,DaemonSet 控制器会在所有工作节点上调度一个 Pod。
通过添加节点选择器,您可以定义一个针对分配给节点的标签的选择器。随后,DaemonSet 控制器会在其标签与所指定选择器匹配的每个节点上创建一个 Pod。
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-daemon
spec:
selector:
matchLabels:
app: fluentd-daemon
template:
metadata:
labels:
app: fluentd-daemon
spec:
nodeSelector:
run-fluentd: "true"
containers:
- name: fluentd-daemon
image: fluent/fluentd
...
通过 kubectl label nodes <node-name> run-fluentd=true 标记的节点会被节点选择器选中,DaemonSet 控制器会在其中每个节点上调度一个 Pod。
小结
在本课中,您了解了 ReplicaSet 与 DaemonSet 之间的区别。您还了解到,通过在 DaemonSet 清单中添加节点选择器,可以确保某个 Pod 在集群中的一部分节点上运行。