本节摘要:DaemonSet 保证"每个(符合条件的)节点恰好运行一个指定 Pod",新节点加入自动补种、节点移除自动回收,适合日志采集、监控代理、网络插件等节点级组件。本节为书屋种下日志采集稻草人,验证其每节点一苗的特性,并讲解 nodeSelector 与容忍度如何圈定稻草人的站岗范围。
书屋的日志方案是每台节点上跑一个采集代理,把本机所有苗的日志转发到集中管道。这类组件有个鲜明特征:它不属于任何业务,只属于节点本身——多一个业务不多个采集器,多一台机器必须多一个采集器。用 Deployment 种它很别扭:replicas 写几?机器数会变;写在哪些节点?没人保证均匀。
DaemonSet 为这个场景而生:声明一份"每节点一株"的期望,园丁持续对账——新节点报到,立刻补种一株;节点除名,苗随之消失;不多不少,正好每块田埂一个。手册叫它稻草人:不为收割而来,只为守着这块田。
# 稻草人清单:日志采集代理每节点一株 apiVersion: apps/v1 kind: DaemonSet metadata: name: log-collector namespace: kube-system # 节点级组件常放系统田 便于统一管理 spec: selector: matchLabels: app: log-collector template: metadata: labels: app: log-collector spec: containers: - name: collector image: fluent-bit:2.1 volumeMounts: - name: varlog mountPath: /var/log # 苗的日志落在节点这个目录 - name: varlibdockercontainers mountPath: /var/lib/docker/containers readOnly: true volumes: - name: varlog hostPath: path: /var/log # 借用节点本机的目录 - name: varlibdockercontainers hostPath: path: /var/lib/docker/containers
kubectl apply -f log-daemonset.yaml -n kube-system # daemonset.apps/log-collector created kubectl get ds log-collector -n kube-system # NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE # log-collector 5 5 5 5 5 # DESIRED 五:正好等于当前节点数 一块田埂不多一株 kubectl get pods -n kube-system -l app=log-collector -o wide # NAME NODE AGE # log-collector-7xz9m node-1 3m # log-collector-k2p8v node-2 3m # log-collector-qw4nt node-3 3m # log-collector-r9m2b node-4 3m # log-collector-t3v7c node-5 3m # 五株各自常驻一台节点 名字后缀依旧随机:稻草人之间可互换
注意最后一点:稻草人株与株之间仍是可互换的(随机后缀、无编号、无专属地块),它特殊在"贴着节点长",不在"有身份"。与 6.1 的果树对照记忆:果树特殊在身份,稻草人特殊在驻地。
默认规则是"每个节点都站"。两种常见微调:
圈定范围。 有些代理只想给带特定标签的节点装(比如只在带 GPU 的田里装驱动守护):
# 模板 spec 里加一段节点筛选(节选) nodeSelector: disk-type: ssd # 只站带这块牌的田
容忍禁地。 集群里有些节点被打了污点——一个"生人勿近"的标记,普通苗不被调度过去(控制平面节点通常带污点,所以业务苗从不落上去)。节点级组件往往必须进驻这些禁地(监控代理不守着主节点,主节点就成了盲区),于是清单里要写容忍:
# 容忍主节点污点:稻草人也守播种总站(节选) tolerations: - key: node-role.kubernetes.io/control-plane effect: NoSchedule # 声明:这个禁地我进得
污点与容忍是一对配合使用的调度机制:节点立牌子"勿近",苗声明"我例外"。业务清单通常不用管它,节点级组件必须懂它。给书屋的监控代理补上这段后,五台业务田加一台总站,六处都有稻草人值守。
| 组件 | 为什么必须每节点一个 |
|---|---|
| 日志采集 | 日志文件写在节点本地磁盘 |
| 监控代理 | 要读本机 CPU 内存等指标 |
| 网络插件 | 要在本机配置路由与转发规则 |
| 存储插件 | 要在本机挂载卷 |
| 安全代理 | 要在本机做网络策略或入侵检测 |
共同点一眼可见:都要伸手摸节点本身(读本地文件、配本机内核、挂本机磁盘)。反过来说,凡是"只通过网络对外服务"的组件(网页、接口、数据库),没有理由做成 DaemonSet——它们需要的是副本与伸缩,那是 Deployment 的地盘。另外注意上表里的网络与存储插件在多数集群里以 DaemonSet 形态预装着,你动它们之前先想清楚,那是承重墙。
💡 排错小技巧:怀疑某节点"网络不对、监控没数、日志缺行"时,第一步看该节点的 DaemonSet 苗在不在、健康不健康。节点级组件一躺,那台节点上的一切都会"哑"。
DaemonSet 的更新策略值得认一眼:默认 RollingUpdate 逐节点换,批量和间隔都可指定;另有 OnDelete 模式,等节点维护时手动触发。节点级组件常与内核、网络相关,一哄而上全换风险高,生产惯例是把批量压小、间隔拉长,必要时配合节点排空——先把业务苗请走,再换稻草人,最后放苗回田。