daemonset 由 kubernetes 控制器管理,go 程序仅负责 crud 操作和监听状态变化;需严格匹配 spec.selector 与 template.labels,用 informer 监听、显式设置 propagationpolicy 删除关联 pod。

Go 程序本身不“管理” DaemonSet 的守护行为,DaemonSet 是 Kubernetes 控制器负责调度和保活的;你用 Go 写的代码只该做两件事:定义/操作 DaemonSet 资源(CRUD),或监听其状态变化。别试图在 Go 里 fork 出守护进程去“运行 DaemonSet”,那既没意义也做不到。
用 client-go 创建和更新 DaemonSet
核心是构造 v1.DaemonSet 对象并提交给 API Server。注意字段必须完整,尤其是 spec.selector 和 spec.template.metadata.labels 必须严格匹配,否则创建会失败并报错 error validating data: invalid spec.selector: invalid label selector。
-
spec.selector.matchLabels和spec.template.metadata.labels的键值对必须完全一致,少一个或拼错一个都会导致创建失败 - 如果想让 DaemonSet 只跑在特定节点上,别只靠
nodeSelector,务必加tolerations(比如容忍node-role.kubernetes.io/control-plane:NoSchedule) - 更新时用
Update()而非Replace(),后者会绕过服务端校验,可能引入非法配置 - 示例关键字段片段:
spec: selector: matchLabels: app: my-daemon template: metadata: labels: app: my-daemon spec: nodeSelector: kubernetes.io/os: linux tolerations: - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule
监听 DaemonSet 变化用 Informer 而不是轮询
直接调 List() + time.Sleep 轮询不仅浪费 API Server 资源,还容易漏事件。Informer 自动处理连接断开、重连、增量同步和本地缓存,是标准做法。
- 初始化时传入
cache.NewListWatchFromClient,不要自己写ListFunc/WatchFunc - 注册
AddFunc/UpdateFunc时,检查oldObj == newObj避免无意义触发(DeepEqual 比较太重,用 ResourceVersion 判断更轻量) - Informer 默认不监听 namespace 级资源变化,若只关心某命名空间,用
cache.NewSharedIndexInformer并指定namespace参数 - 别在回调里做耗时操作(如 HTTP 请求、DB 写入),应发消息到 channel 或 worker pool 异步处理
删除 DaemonSet 后 Pod 不立即消失?检查 propagationPolicy
调 Delete() 默认只删 DaemonSet 对象,关联的 Pod 还在运行——这是故意设计,防止误删导致节点功能中断。要连带清理 Pod,必须显式设置 PropagationPolicy。
- 使用
metav1.DeletePropagationBackground(默认):只删 DaemonSet,Pod 异步被 GC 清理(通常几秒内) - 用
metav1.DeletePropagationForeground:先给所有 Pod 加deletionTimestamp,等它们终止后再删 DaemonSet - 用
metav1.DeletePropagationOrphan:只删 DaemonSet,Pod 变成“孤儿”,继续运行但不再受控(危险,慎用) - 代码中必须传
&metav1.DeleteOptions{PropagationPolicy: &propagation},漏掉这个参数就等于没设
最易忽略的是:DaemonSet 的生命周期完全由 Kubernetes 控制平面管理,Go 程序只是它的客户端。你写的逻辑再“健壮”,也不能替代控制器对节点加入/退出、污点变更、Pod 崩溃的响应能力。重点放在资源建模准确性和事件响应及时性上,而不是模拟守护行为。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











