DaemonSet 滚动更新:节点一台接一台宕机,根因在更新策略
场景: DaemonSet 滚动更新 CNI 配置 → DaemonSet Pod 逐节点终止重建 → 节点逐台 NotReady路径: Pod → CRI → Node → 集群 逐层排查版本: K8s v1.25上篇讲了 Pod 调度不均衡问题——nodeAffinity 配置写反导致 Pod 挤在同一台节点资源利用率一边倒。这篇我们来看另一个因配置引发的连锁反应DaemonSet 滚动更新导致节点逐个宕机。更新一个 DaemonSet 的配置发布后节点一台接一台变成 NotReady——不是硬件故障不是 kubelet 挂了是 DaemonSet controller 的 RollingUpdate 策略在每个节点上执行 terminate → 等待 Ready → 再继续下一节点。当被终止的是 CNI 网络插件 Pod如 Calico节点网络瞬间断连kubelet 的 NodeStatus 上报超时node controller 直接判 NotReady。K8s 的 RollingUpdate 只保证你的 Pod 被替换——不保证你的节点还在线上。【坐标】→ 节点逐台失联现象很直接发布一个 DaemonSet 配置更新后监控面板上节点开始一台一台变红。用kubectl get nodes -w能看到 Node 状态变化的时间线——间隔大约 1-2 分钟一台完全跟 DaemonSet 滚动更新的节奏吻合。kubectl describe node node-name查看 NotReady 节点的 ConditionConditions: Type Status LastHeartbeatTime Reason Message ---- ------ ----------------- ------ ------- Ready Unknown... NodeStatusUnknown Kubelet stopped postingnodestatus.... MemoryPressure False... DiskPressure False...关键信息Kubelet stopped posting node status——kubelet 不再上报心跳。不是 kubelet 进程挂了是它无法跟 API server 通信了。这里立即引发直觉kubelet 的网络依赖什么答案是 CNI 插件Container Network Interface它通常以 DaemonSet 形式运行在每个节点上。如果 CNI Pod 被终止了节点就失去了网络能力。— 去查 DaemonSet 状态。Pod 层kubectl get pods -n kube-system -l k8s-appcalico-node -w。DaemonSetDaemonSet——在每个节点上运行一个 Pod 的控制器常用于网络插件、监控代理等基础设施组件正在逐节点更新新 Pod 全部卡在 Init 阶段。【分层】→ 逐层排查排查路径从 Pod 内日志/Events出发逐层往下到 CRI 运行时再到 Node 层面最后看集群范围。不跳过任何一层。Pod 层DaemonSet 更新序列kubectl describe daemonset calico-node -n kube-system确认更新策略。C2 — DaemonSet controller 的 RollingUpdate 逻辑DaemonSet controller 在 RollingUpdate 模式下每次选择一个节点终止其上的旧 Pod等待新 Pod 变为 Ready然后才继续下一个节点。maxUnavailable: 1意味着同一时间最多只有一个节点的 Pod 处于不可用状态。这不是并发的——是逐节点的串行操作。当新 Pod 永远无法 Ready 时controller 卡在当前节点不再继续更新其他节点。但这里的现象是节点逐个宕机——说明新 Pod 虽然没 Ready但旧 Pod 已经被终止了节点网络已经断了。kubectl logs calico-node-def34 -n kube-system看不到日志Pod 在 Init 阶段需要用crictlCRI 命令行工具用于直接与容器运行时交互比 kubectl logs 能看到已退出容器的历史日志查已退出的 Init Container。CRI 层CNI 容器启动失败先找到节点上的容器 ID# 在 NotReady 节点上执行crictlps-a|grepcalicocrictl ps -a | grep calico输出如下CONTAINER IMAGE CREATED STATE NAME a1b2c3d4e calico-node:v3.262minutes ago Exited install-cni e5f6g7h8i calico-node:v3.261minute ago Exited calico-node两个容器都 Exited。crictl logs a1b2c3d4e看 Init Container 输出2026/07/0310:22:15[INFO]Installing CNI binaries...2026/07/0310:22:16[ERROR]Failed to create CNI config: configfile/host/etc/cni/net.d/10-calico.conflist not found根因明确新版本 Calico 的 CNI 配置文件路径变了旧配置挂载没有覆盖新路径导致 CNI 安装失败。节点上没有 CNI 配置 → kubelet 无法设置 Pod 网络 → 节点失去网络能力。Node 层kubelet 心跳断连journalctl -u kubelet -f --since 10 minutes ago查看 kubelet 日志Jul 0310:22:20 node-1 kubelet[1234]: E Failed to updatenodestatus: Posthttps://api-server:6443/api/v1/nodes/node-1/status:dial tcp10.0.0.1:6443: connect: no route tohostJul 0310:22:30 node-1 kubelet[1234]: E Failed to updatenodestatus:...C2 解释kubelet 每隔 10s--node-status-update-frequency向 API server 报告一次 Node 状态。当 CNI 不可用kubelet 无法通过网络连接 API serverNodeStatus 上报连续超时。node controllercontroller-manager 内的节点管理组件负责监控节点心跳状态在--node-monitor-grace-period默认 40s内没收到上报将 Node 标记为Unknown再过--node-monitor-period默认 5s标记为NotReady。时间线时间事件T0sDaemonSet controller 终止 node-1 的 calico-node PodT5sCNI 配置丢失节点网络断连T10skubelet 首次上报失败T40snode controller 标记 node-1 为 UnknownT50snode controller 标记 node-1 为 NotReadyT60sDaemonSet controller 继续下一个节点用maxUnavailable: 1的串行滚动集群层DaemonSet controller 的 RollingUpdate回到集群视角。DaemonSet controller 的行为是保证每个节点上有一个 Pod 运行它在滚动更新时并不知道节点的网络能力依赖它的 Pod。controller 的职责边界止于 Pod 生命周期——它检查新 Pod 是否 Ready不是检查节点是否 Ready。# DaemonSet controller 的逻辑简化for each node:terminate old Pod on node create new Pod on node wait for new Pod to become Readyif timeout:stop,dont continueelse:next node这个循环里新 Pod 的 ready 检查依赖于 kubelet 的健康检查。但 kubelet 的健康检查依赖于 CNI。CNI 依赖于 DaemonSet 自己。这是一个循环依赖——DaemonSet controller 不知道也无法知道。【路径】→ 下次先查 DaemonSet 状态遇到节点逐台宕机第一反应不是查节点——是查 DaemonSet。# 1. 看哪个 DaemonSet 在滚动更新kubectl rollout status daemonset--all-nkube-system# 2. 看更新策略kubectl describe daemonsetname-nns|grep-A5UpdateStrategy# 3. 看 DaemonSet Pod 更新序列kubectl get pods-nkube-system-lk8s-appapp-w# 4. 看 Node NotReady 时间线kubectl get nodes-owide|grepNotReady# 5. 定位节点失联时间点kubectl describenodenode-name|grep-A10Conditions判断标准如果 NotReady 节点的数量和时间跟某个 DaemonSet 的 Pod 终止节奏吻合——问题在 DaemonSet不在节点。【定位】→ 最常误判❌ 大多数人会这么查“节点 NotReady → 登录节点查 kubelet 状态 → systemctl restart kubelet → 短暂恢复 → 又挂了 → 再重启 → 重复。”浪费大量时间在节点层打转重启 kubelet 只是暂时恢复了网络连接但 CNI 问题没解决网络会再次断连。✅ 正确的排查思路遇到节点逐个宕机先做两件事检查 DaemonSet 状态kubectl rollout status daemonset --all -n kube-system——看是否某个 DaemonSet 正在更新对比时间线DaemonSet Pod 终止时间 vs Node NotReady 时间如果吻合直接定位到 DaemonSet。然后如果是 CNI 插件 DaemonSet → 节点网络依赖它更新前必须评估对节点网络的影响如果是其他基础设施 DaemonSetlog agent / monitoring agent→ 影响范围较小但同样可能引发级联问题两者的差异前者从节点现象出发Node NotReady后者从集群视角出发DaemonSet 更新 时间线交叉。不出节点层永远找不到根因。【标点】→ 修复 Check-list紧急止损直接回滚 DaemonSet 到上一个版本kubectl rollout undo daemonset/calico-node-nkube-system回滚后DaemonSet controller 重新在每个节点上创建旧版本的 Pod。CNI 恢复节点网络恢复kubelet 重新上报node controller 将 Node 状态恢复为 Ready。回滚效果对比# before: 新版本 CNI 配置路径不对volumes:-name:cni-configconfigMap:name:calico-config-v2# ❌ 新路径新版本# after: 旧版本volumes:-name:cni-configconfigMap:name:calico-config# ✅ 旧路径正常工作预防配置# 方案 AmaxUnavailable: 25%先建后删比例updateStrategy:rollingUpdate:maxUnavailable:25%# 方案 BOnDelete手动控制每台节点更新updateStrategy:type:OnDelete# 方案 C加 PodDisruptionBudgetPDB - Pod 中断预算保证最少可用的 Pod 数量apiVersion:policy/v1kind:PodDisruptionBudgetmetadata:name:calico-node-pdbnamespace:kube-systemspec:minAvailable:90%selector:matchLabels:k8s-app:calico-nodemaxUnavailable: 25%限制同时不可用的 Pod 数不会整节点断网OnDelete策略要求手动删除 Pod 才触发更新适合 CNI 等关键基础设施PDB 保证至少 90% 的节点有 CNI 可用排查 Check-list故障排查的终点不是修好了——是把排查路径写成 check-list。□ 发现节点逐台 NotReady → 先查 DaemonSet kubectl rollout status daemonset--all-nkube-system □ 确认滚动更新 kubectl describe daemonsetname-nkube-system|grep-A5UpdateStrategy □ 确认 DaemonSet Pod 终止时间线 kubectl get pods-nkube-system-lk8s-appapp-w□ 确认节点 NotReady 时间线 kubectl get nodes-owide|grepNotReady kubectl describenodenode-name|grep-A10Conditions □ 回滚止损 kubectl rollout undo daemonset/name-nkube-system □ 排查新版本配置差异 kubectl describe daemonsetname-nkube-systembefore.yaml# 对比版本间 ConfigMap / 环境变量 / 卷挂载变化□ 验证回滚后节点恢复 kubectl get nodes-wkubectl get pods-nkube-system-lk8s-appapp-w附完整命令清单# 查看 DaemonSet 滚动更新状态kubectl rollout status daemonset/calico-node-nkube-system# 查看 DaemonSet 更新策略kubectl describe daemonset/calico-node-nkube-system|grep-A5UpdateStrategy# 查看 DaemonSet Pod 状态持续监听kubectl get pods-nkube-system-lk8s-appcalico-node-w# 查看节点状态kubectl get nodes-owide kubectl describenodenode-name|grep-A10Conditions# 回滚 DaemonSetkubectl rollout undo daemonset/calico-node-nkube-system# 查看 DaemonSet 历史版本kubectl rollouthistorydaemonset/calico-node-nkube-system# 回滚到指定版本kubectl rollout undo daemonset/calico-node-nkube-system --to-revisionN# 节点上查看已退出容器CRI 层crictlps-a|grepcalico crictl logscontainer-id# 查看 kubelet 日志journalctl-ukubelet-f--since30 minutes ago下篇我们聊 DaemonSet OnDelete vs RollingUpdate 选择陷阱——什么场景该用哪种策略以及为什么你的基础设施 DaemonSet 应该用 OnDelete。

相关新闻

# TCP和UDP到底有什么区别?一篇文章彻底搞懂两种网络通信协议

# TCP和UDP到底有什么区别?一篇文章彻底搞懂两种网络通信协议

TCP和UDP到底有什么区别?一篇文章彻底搞懂两种网络通信协议 前言 在嵌入式开发、服务器开发、物联网设备以及网络通信领域,经常会遇到两个非常重要的协议: TCPUDP 很多初学者都会问: TCP和UDP到底有什么区别?为什么…

2026/11/12 17:16:53 阅读更多 →
知识蒸馏实战:从ResNet-50到ResNet-18的模型压缩与部署指南

知识蒸馏实战:从ResNet-50到ResNet-18的模型压缩与部署指南

在实际 AI 应用开发和模型部署的语境下,“蒸馏”通常指知识蒸馏(Knowledge Distillation),这是一种将大型、复杂模型(教师模型)的知识迁移到小型、轻量模型(学生模型)中的技术。其核…

2026/11/6 2:04:59 阅读更多 →
在Yank Note中集成AI:打造高效Markdown写作工作流

在Yank Note中集成AI:打造高效Markdown写作工作流

1. 项目概述:当Markdown编辑器遇上AI作为一名长期与文字和代码打交道的创作者,我一直在寻找一个能让我“沉浸式”写作,同时又能无缝整合现代AI能力的工具。传统的Markdown编辑器要么功能过于简陋,要么为了追求大而全变得异常臃肿&…

2026/11/4 4:45:36 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/12 5:00:00 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/12 5:13:20 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/12 5:13:20 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/11 17:16:37 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/11 17:16:37 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/12 5:13:20 阅读更多 →

日新闻

周新闻

月新闻