DaemonSet 是 Kubernetes 中确保每个匹配节点运行且仅运行一个 Pod 的控制器,适用于日志收集、监控采集、网络插件、GPU代理和安全审计等需与宿主机强绑定的场景,其规模由节点数动态决定,不支持扩缩容。

DaemonSet 是 Kubernetes 中专为节点级部署设计的核心控制器,它不按副本数调度,而是确保每个(或匹配条件的)节点上运行且仅运行一个 Pod 实例。这种“一节点一实例”的机制,天然适配系统级守护进程场景,无需手动逐台配置,也不依赖节点数量预设规模。
适合 DaemonSet 的典型任务类型
不是所有服务都该用 DaemonSet —— 它专用于需要与宿主机强绑定、感知节点本地状态的任务:
-
日志收集代理:如 Fluentd、Filebeat,需挂载
/var/log和/var/lib/docker/containers等主机路径读取日志 -
监控采集器:如 Prometheus Node Exporter,直接读取
/proc、/sys等节点级指标源 -
网络插件组件:如 Calico CNI 的
calico-node、Cilium 的cilium-agent,负责配置 iptables 或 eBPF 规则 -
GPU 或硬件加速代理:如 Triton Inference Server(绑定单卡)、NVIDIA Device Plugin,需访问
/dev/nvidia*设备文件 - 安全审计工具:如 Falco,依赖 eBPF 或内核模块监听系统调用,必须在每个节点运行
关键配置要点与常见陷阱
写好一个可用的 DaemonSet,光有模板远远不够,以下细节决定成败:
-
节点选择要明确:用
nodeSelector或affinity.nodeAffinity限定范围(例如只在hardware-type=ssd节点运行监控),避免误调度到控制平面节点 —— 若需容忍 master 节点,必须显式添加tolerations -
主机路径挂载要谨慎:
hostPath类型卷必须指定type: DirectoryOrCreate或Directory,否则在新节点可能因路径不存在导致 Pod 启动失败 -
特权模式不是默认开启:涉及设备访问(GPU、USB)、修改内核参数(如 sysctl)、加载模块等操作,必须设置
securityContext.privileged: true并确认集群允许该策略 -
更新策略影响运维体验:默认
RollingUpdate会逐个节点替换 Pod;若业务对中断敏感,可设maxUnavailable: 1控制并发更新数;不建议用OnDelete手动触发
验证与调试实用方法
部署后不能只看 kubectl get ds 显示 READY,要确认实际运行状态是否符合预期:
- 检查每个节点是否真有一个 Pod:
kubectl get pods -o wide | grep your-daemonset-name,观察 NODE 列是否覆盖全部目标节点 - 快速定位失败原因:
kubectl describe daemonset your-ds-name查看 Events;再挑一个 Pending 状态的 Pod,用kubectl describe pod <pod-name>看调度失败提示(如 node selector 不匹配、资源不足、toleration 缺失) - 进入容器验证功能:
kubectl exec -it <pod-name> -- sh,检查挂载路径是否存在、设备文件能否访问、端口是否监听(netstat -tlnp) - 模拟节点加入:扩容节点后,观察是否自动创建新 Pod;缩容或驱逐节点时,对应 Pod 是否被自动清理(非强制删除)
和 Deployment 的本质区别
选错控制器会导致架构隐患。DaemonSet 和 Deployment 的核心差异不在语法,而在语义和行为:
- Deployment 关注“服务整体可用性”,通过副本数保证高可用,Pod 可跨节点漂移;DaemonSet 关注“节点能力完整性”,每个节点是独立执行单元,Pod 与节点生命周期强绑定
- Deployment 支持水平扩缩容(
kubectl scale);DaemonSet 不支持扩缩容命令,它的“规模”由节点数量动态决定 - Deployment 的滚动更新基于副本集切换;DaemonSet 的滚动更新是逐节点替换,无法跳过特定节点(除非临时加 taint)
- 集群升级或节点维护时,Deployment Pod 可被调度到其他节点继续提供服务;DaemonSet Pod 随节点下线而终止,服务即消失 —— 这正是设计本意


















