尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Kubernetes DaemonSet 实战:每节点一个 Agent、与 Deployment 的区别与污点容忍

Kubernetes DaemonSet 实战:每节点一个 Agent、与 Deployment 的区别与污点容忍 Kubernetes DaemonSet 实战:每节点一个 Agent、与 Deployment 的区别与污点容忍你想在集群里部署一个日志采集器,要求「每台节点上都跑一个,一个不多一个不少」。用 Deployment 加副本数?那不行——Deployment 只管「一共跑几个」,不保证每个节点都有,而且扩容后新节点上还是空的。这种「每节点一份」的场景,正是 DaemonSet 存在的意义。这篇讲清楚它和 Deployment 的根本区别,以及部署监控/日志类 Agent 时必须处理的污点问题。Deployment 管数量,DaemonSet 管覆盖先把两者的心智模型分清楚:Deployment:声明「我要 N 个副本」,调度器把这 N 个 Pod 撒到合适的节点上,可能几个挤在同一节点。适合无状态业务应用。DaemonSet:声明「每个(符合条件的)节点跑一个」,节点加入集群时自动补一个 Pod,节点移除时对应 Pod 也删掉。适合节点级的基础设施:日志采集(Fluent Bit)、监控(node-exporter)、网络插件(CNI)、存储驱动。关键差异一句话:Deployment 关心总数,DaemonSet 关心「每个节点都覆盖到」。所以 DaemonSet 的 YAML 里根本没有replicas字段——副本数由节点数量决定。一个最小可用的 DaemonSet下面部署一个 node-exporter(采集节点 CPU/内存/磁盘指标),这是最典型的 DaemonSet 用例:apiVersion:apps/v1kind:DaemonSetmetadata:name:node-exporternamespace:monitoringspec:selector:matchLabels:app:node-exportertemplate:metadata:labels:app:node-exporterspec:hostNetwork:true# 用宿主机网络,直接暴露节点端口containers:-name:node-exporterimage:prom/node-exporter:v1.8.2ports:-containerPort:9100hostPort:9100# 绑到节点的 9100,Prometheus 直接抓resources:requests:cpu:50mmemory:30Milimits:memory:60Mikubectl apply -f之后看看效果:$ kubectl-nmonitoring get daemonset NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR node-exporter33333noneDESIRED3 意味着集群有 3 个可调度节点。此时用kubectl get pod -o wide会看到 3 个 Pod 分别落在 3 个不同节点上,一个都不重叠。第一个坑:控制平面节点被污点挡住上面 DESIRED 是 3,但如果你的集群有 master/control-plane 节点,你会发现监控 Agent没跑到 master 上。原因是控制平面节点默认带一个污点(taint):$ kubectl describenodemaster-1|grepTaints Taints: node-role.kubernetes.io/control-plane:NoScheduleNoSchedule会拒绝所有不「容忍」这个污点的 Pod。而监控和日志 Agent 恰恰需要覆盖所有节点,master 也不能漏。解决办法是给 DaemonSet 加上对应的 toleration:spec:tolerations:# 容忍控制平面污点,让 Agent 也能落到 master-key:node-role.kubernetes.io/control-planeoperator:Existseffect:NoSchedule# 老版本集群用的是 master 这个 key,一并容忍-key:node-role.kubernetes.io/masteroperator:Existseffect:NoSchedulecontainers:-name:node-exporter# ...operator: Exists且不写 value,表示「只要有这个 key 的污点,不管值是什么都容忍」。加上后 DESIRED 数会把 master 也算进去。这是部署监控/日志 DaemonSet 最常被忽略的一步。只想跑在部分节点:用 nodeSelector如果 Agent 只需要覆盖特定节点(比如只在带 GPU 的节点上跑显卡监控),用nodeSelector或亲和性圈定范围:spec:nodeSelector:hardware:gpu# 只调度到有 hardwaregpu 标签的节点给节点打标签:kubectl label node node-2 hardwaregpu。之后 DaemonSet 的 DESIRED 就只统计带这个标签的节点,新打标签的节点会自动补上 Pod,去掉标签则对应 Pod 被回收。第二个坑:更新策略默认是滚动,但要控节奏DaemonSet 更新镜像时默认走RollingUpdate,但因为每节点只有一个 Pod,更新期间该节点的 Agent 会短暂中断。用maxUnavailable控制同时更新多少节点,避免一次性把整个集群的采集全断掉:spec:updateStrategy:type:RollingUpdaterollingUpdate:maxUnavailable:1# 一次只更新一个节点,稳如果是网络插件这种改动风险高、想手动逐台验证的场景,可以设type: OnDelete——改了镜像不自动更新,只有你手动删掉某个 Pod,新版本才在那个节点上起来。排查:某个节点上没有 Pod 怎么办如果 DESIRED 数少于你预期的节点数,或某节点明明在却没跑 Agent,按这个顺序查:# 1. 看该节点有没有污点没被容忍kubectl describenodenode|grepTaints# 2. 看 DaemonSet 的事件,有没有调度失败信息kubectl-nmonitoring describe daemonset node-exporter# 3. 该节点是否 Ready、是否被 nodeSelector 排除kubectl getnodenode--show-labels九成的「节点没覆盖到」都是污点没容忍或标签不匹配,对着这两点查基本能定位。小结DaemonSet 保证「每个符合条件的节点跑一个 Pod」,节点增删自动跟随;Deployment 只保证总副本数。所以 DaemonSet 没有replicas。部署监控/日志 Agent 要覆盖控制平面节点,必须加对应污点的 toleration,这是最常见的漏项。用nodeSelector/亲和性限定只在部分节点跑;更新用maxUnavailable控制节奏,高风险组件可用OnDelete手动逐台更新。节点没覆盖到,先查污点容忍和节点标签,describe daemonset看调度事件。一句话记忆:要「每台一份」就用 DaemonSet,而且别忘了给 master 的污点加 toleration——否则你的监控永远缺控制平面那几台。
返回列表