DaemonSet 删节点标签后,Pod 为何仍被终止
DaemonSet会持续检查节点是否匹配模板。删标签后的Pod终止不由IgnoredDuringExecution或OnDelete阻止,须核对节点资格与管理记录。
DaemonSet 的节点亲和性写着 requiredDuringSchedulingIgnoredDuringExecution。Pod 已经运行,删除节点上参与匹配的标签后,它仍被终止。改成 OnDelete 更新策略也未能保留这个 Pod。
这里要区分调度器的亲和性检查和 DaemonSet 控制器的节点管理。DaemonSet 持续判断哪些节点应该运行自己的 Pod。节点标签变化后不再满足模板条件,控制器可以删除该节点上的 DaemonSet Pod;字段名里的 IgnoredDuringExecution 不能用来保证这种 Pod 永远留在原节点。
先找 Pod 的控制器与标签变化
以下命令读取实际资源,名称需替换:
kubectl -n observability get pod node-agent-abc12 -o yaml
kubectl -n observability get daemonset node-agent -o yaml
kubectl get node worker-01 --show-labels
kubectl -n observability describe daemonset node-agent
先通过 ownerReferences 确认 Pod 由这个 DaemonSet 管理,再看它所在节点及删除时间。已经删除的 Pod 应使用此前保存的对象、事件或审计记录,不能拿新生成 Pod 的状态替代旧时间线。
对照 DaemonSet 的 spec.template.spec.nodeSelector 和 spec.template.spec.affinity.nodeAffinity,检查参与匹配的标签在什么时间被谁修改。事件有保留期限;没有事件,不足以证明没有发生过标签或删除操作。
还要排除节点维护、外部发布工具、人工删除和未容忍的 NoExecute 污点。普通 NoSchedule 污点对已运行 Pod 的作用不同,可参照控制平面污点与调度条件。不要把所有终止都归到亲和性。
原模板与生成的 Pod 可能显示不同亲和性
DaemonSet 控制器用模板中的原节点条件判断合格节点。创建具体 Pod 时,会把它的节点亲和性替换为匹配目标节点名称的条件,随后由调度器将其绑定到该节点。
因此,读取 Pod 只看到 metadata.name 对应某个节点,不代表模板里的标签约束已经失效。排查节点资格时要读 DaemonSet 原模板,再与节点标签比较,不能只读生成 Pod 的 affinity。
Kubernetes 1.35 的控制器实现中,节点名称或所需亲和性不匹配,会同时判定“不应新建”和“不应继续运行”。已有 DaemonSet Pod 随后进入删除处理。这也解释了为什么把更新策略改成 OnDelete 无效:它控制模板版本更新的替换方式,不会暂停节点资格管理。
标签误改与有意迁移,处理方式不同
若标签是误删,先从审定配置或审计记录确认该节点原本应该承载这个 DaemonSet,再恢复指定节点上那个标签的准确值。检查是否有其他控制器会再次覆盖它,不要把同一个标签随手加到所有节点。
条件恢复以后,控制器可以在合格节点重新创建 Pod。旧 Pod 已经终止时,恢复标签不会恢复原进程;需要确认新 Pod 的启动、就绪及它负责的节点功能。例如日志代理应恢复采集,网络或存储代理则要检查相应的节点服务。
如果是有意撤销节点资格,应把删除 Pod 当作这次迁移的一部分。修改前保存标签与模板,确认网络、日志、监控或存储能力会怎样受影响,准备替代覆盖与回退安排。不能仅靠 IgnoredDuringExecution 维持旧覆盖,也不要为了留下旧进程取消全部节点限制。
验收同时检查原节点是否符合预期、新合格节点是否具备所需 Pod、未计划节点是否被错误覆盖,以及节点服务和业务实际状态。需要撤回时恢复审定的标签或模板,再观察新建 Pod;已经产生的采集中断、进程退出或存储操作不会因为标签恢复自动消失。


