大家好!今天,我们将了解Kubernetes中管理工作负载的四大核心之一,一个执行着特殊任务的朋友。它不像Web服务器或API服务器那样根据流量进行伸缩。它是一个默默无闻、必须在每个节点(服务器)上存在一个的基础设施级守护者,那就是DaemonSet。🛡️
CKAD考试中也经常出现“仅在特定节点上部署日志收集器”之类的题目,所以今天我们投入15分钟,彻底掌握这个概念吧!

###
1. 引言:为什么每个节点都需要一个Pod? 🤔
我们通常使用的Deployment,当你请求“为我们的服务启动3个Pod!”时,调度器会自动将它们适当地放置在有可用资源的节点上。一个节点上可能会启动2个,或者3个Pod都分布在不同的节点上。
但如果情况改变了呢?
假设你有一个由100台服务器(节点)组成的Kubernetes集群。你需要收集这100台服务器上产生的所有系统日志。
- 使用Deployment设置`replicas: 100`可以吗?
- 👉 不行! 如果运气不好,某些节点上可能会启动2个日志收集器,而某些节点上一个都没有。
这时就需要DaemonSet,它是一个控制器,能够“确保集群中所有节点(或满足特定条件的节点)上精确地运行一个Pod副本”。
2. DaemonSet的主要任务 (Use Cases) 🛠️
DaemonSet通常用于执行基础设施级别的任务,而非应用程序逻辑。它的主要职责是作为管理或监控节点本身的“代理”。
典型的使用场景如下:
- 📝 运行日志收集守护进程:
- 收集每个节点上产生的容器日志或系统日志,并将其发送到中央日志存储(如Elasticsearch、Loki等)。
- 示例: Fluentd, Fluent Bit, Filebeat
- 📊 运行监控守护进程:
- 收集每个节点的CPU、内存、磁盘使用情况等节点自身的状态信息。
- 示例: Prometheus Node Exporter, Datadog Agent
- 🌐 集群存储守护进程和网络插件:
- 帮助在每个节点上挂载存储,或运行负责节点间网络通信的CNI插件。
- 示例: Glusterd, Ceph, Calico, Flannel
- RollingUpdate (默认值):
- 这是最推荐的方式。它不像Deployment那样一次性杀死所有Pod,而是逐个节点地顺序删除旧版本Pod并创建新版本Pod。这可以在不中断服务的情况下更新基础设施代理。
- `maxUnavailable`设置可以控制同时有多少个节点可以进行更新(即有多少个Pod可以暂时不可用)(默认值为1)。
- OnDelete:
- 顾名思义,“删除时”更新。即使修改了模板,正在运行的Pod也不会改变。
- 操作员必须手动使用`kubectl delete pod …`删除相应节点上的Pod,DaemonSet控制器才会创建新版本的Pod。当你想完全手动控制更新时机时使用。
- 记住目的: 它的目的是“每个节点的独立基础设施管理”,而不是“服务扩展(Scaling)”。
- YAML结构: 务必记住没有`replicas`字段。
- 节点选择: 如果考试中出现“仅部署到特定节点”的要求,不要慌张,只需在Pod模板(`spec.template.spec`)中添加`nodeSelector`。
- Toleration: 如果需要部署到主节点(控制平面),可能需要`tolerations`设置来容忍主节点的Taint。(虽然最新版本有时会自动添加,但明确声明更好。)
💡 核心总结: 当新的节点加入集群时,DaemonSet会自动创建Pod;当节点被移除时,它也会一并清理Pod。它真是个可靠的守护者,不是吗?
3. CKAD实战!YAML中的DaemonSet 📄
百闻不如一见!让我们通过实际代码来看看它与Deployment有何不同。
最大的区别是没有`replicas`字段。Pod的数量由节点的数量决定!
下面是一个简单的DaemonSet示例,用于在所有节点上部署名为fluentd的日志收集器。
apiVersion: apps/v1
kind: DaemonSet # 👈 类型是 DaemonSet。
metadata:
name: fluentd-elasticsearch
namespace: kube-system # 通常,基础设施相关的部署在 kube-system 中。
labels:
k8s-app: fluentd-logging
spec:
# replicas: 3 👈 与 Deployment 不同,此字段不存在!
selector:
matchLabels:
name: fluentd-elasticsearch
template: # 从这里开始,与 Pod 模板相同。
metadata:
labels:
name: fluentd-elasticsearch
spec:
# 将节点系统日志路径挂载到 Pod 的设置(示例)
volumes:
- name: varlog
hostPath:
path: /var/log
containers:
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
volumeMounts:
- name: varlog
mountPath: /var/log
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
# 如果要部署到主节点(控制平面),可能需要容忍污点。
tolerations:
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
4. CKAD进阶:“我只想部署到特定节点!” (Node Selector) 🎯
在CKAD考试中,除了简单地创建DaemonSet,给出条件的情况也很多。
“仅在带有GPU的节点上以DaemonSet形式部署监控代理。”
DaemonSet默认部署在所有节点上,但你可以使用`nodeSelector`或`affinity`来仅在带有特定标签的节点上启动Pod。
示例场景: 如果你想只部署到带有`type=gpu-node`标签的节点上怎么办?
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: gpu-monitor
spec:
selector:
matchLabels:
app: gpu-monitor
template:
metadata:
labels:
app: gpu-monitor
spec:
# 👇 这部分是关键!
nodeSelector:
type: gpu-node
containers:
- name: nvidia-gpu-exporter
image: nvidia/gpu-monitoring-tools
# ... 省略 ...
这样设置后,DaemonSet控制器将从集群节点中选择带有`type=gpu-node`标签的节点,并在每个节点上创建一个Pod。非常智能,不是吗? 🧠
5. DaemonSet的更新策略 (RollingUpdate vs OnDelete) 🔄
如果更改了DaemonSet部署的Pod镜像会发生什么?与Deployment一样,DaemonSet也有更新策略。
6. 总结:CKAD考场小贴士 🍯
DaemonSet只要概念掌握牢固,就和Deployment一样简单。
今天学习的DaemonSet,感觉如何?它是不是像一个可靠的支援者,在幕后默默工作,以保持集群的稳定? 👮♂️
如果您在准备CKAD考试时有任何疑问,请随时提问。我衷心祝愿您考试成功!加油! 💪
发表回复