docker & containerd 13
好,这一版我按 SRE可观测模型 + Pod生命周期真实状态机 + 你当前日志 给你重新画一张“不会误导”的流程图,并把你这个“DaemonSet看起来正常但Pod少”的现象彻底讲透。
🧠 0. 先给你一个核心结论(避免走偏)
你现在的问题本质是:
❗不是 DaemonSet 统计问题
❗不是 Node NotReady
❗而是 Pod 生命周期卡在 kubelet → CRI → kernel 执行链路中
🧩 1. 正确的 Kubernetes Pod 生命周期(SRE视角)
下面这张是“真实可观测链路”(重点不是K8s逻辑,而是执行点)
┌──────────────────────────────┐│ 1. DaemonSet Controller ││ (desired=3) │└────────────┬─────────────────┘│ create Pod object▼┌──────────────────────────────┐│ 2. API Server ││ Pod object exists (3) │└────────────┬─────────────────┘│ schedule bind▼┌──────────────────────────────┐│ 3. Scheduler ││ Node assignment OK │└────────────┬─────────────────┘│ pod assigned to node▼┌────────────────────────────────────────┐│ 4. kubelet syncPod (关键分界点) ││ ││ VerifyControllerAttachedVolume ││ ↓ ││ CNI setup ││ ↓ ││ CRI: CreatePodSandbox ❌ BLOCK │└────────────┬───────────────────────────┘│┌────────────▼───────────────┐│ 5. containerd (CRI runtime) ││ create container ❌ stuck │└────────────┬───────────────┘│ syscall hang▼┌──────────────────────────────┐│ 6. kernel / IO / fs layer ││ mount / cgroup / disk stall │└──────────────────────────────┘
🧠 2. 你看到的“矛盾现象”解释
你说:
kubectl get daemonset = 3/3 正常
kubectl get pods = 2个
kubelet pprof hang + containerd create stuck
⚠️ 关键点:你在比较两个“不同维度的状态系统”
🧩 3. DaemonSet 为什么看起来是 3/3?
DaemonSet 的 READY / DESIRED 本质是:
controller cache + Pod status condition(非 runtime)
它依赖:
-
Pod对象是否存在
-
Pod是否进入某些 condition(Ready/Assigned)
❗关键误区
DaemonSet 不依赖:
-
container 是否真正 Running
-
kubelet 是否完成 createPodSandbox
-
runtime 是否成功启动
👉 所以会出现:
✔ DaemonSet = “逻辑达标”
❌ 实际 Pod = “执行失败”
🧠 4. 你这个 case 的真实状态(必须这样理解)
我们重建真实状态:
🟢 Node A
-
Pod1 ✔ Running
-
Pod2 ✔ Running
🔴 Node B(异常节点)
-
Pod3 ❌ 已分配
-
kubelet syncPod 卡住
-
containerd create stuck
-
无 Running 上报
👉 所以:
DaemonSet:desired=3observed=3 (object exists)Pods:actual runtime = 2 running + 1 stuck in execution pipeline
🧠 5. kubelet 日志的真实含义(重点拆)
🔴 (1) volume attach
VerifyControllerAttachedVolume started
👉 kubelet 已进入:
volume mount / attach reconcile loop
🔴 (2) reconciler
Reconciler: start to sync state
👉 kubelet进入 syncPod主循环
🔴 (3) Readiness probe fail trigger
Failed to trigger a manual run probe="Readiness"
👉 不是 probe fail,而是:
❗probe worker thread 已阻塞(event loop blocked)
🔴 (4) client throttling
Waited for 1.17s due to client-side throttling
👉 只是 API 延迟,不是 root cause
🧠 6. kubelet pprof hang 的真实意义(核心)
pprof hang =:
❗kubelet event loop 被 syscall block
通常只有三类:
A. CRI call hang(你这里有)
-
CreatePodSandbox stuck
-
containerd RPC blocked
B. mount / volume syscall hang(你这里也有迹象)
-
VerifyControllerAttachedVolume
-
attach/mount 阶段
C. kernel IO stall(最底层)
-
D state
-
fs freeze
-
disk latency spike
🔥 7. containerd create stuck(关键证据点)
这是整个链路“断点”。
✔ 含义:
kubelet → containerd CreatePodSandbox RPC blocked
👉 关键工程结论:
❗containerd 不是“失败”,而是“调用卡死”
🧠 8. 为什么 kubelet sync 会“卡死不推进”
kubelet syncPod 是串行状态机:
syncPod()├── volume mount├── CNI setup├── CRI CreatePodSandbox ❌ BLOCK├── container start├── status update
👉 你现在卡在:
CRI CreatePodSandbox 或 volume mount syscall
🧠 9. 最关键解释(解决你困惑)
❓为什么 DaemonSet 看起来正常?
因为:
DaemonSet 只看“对象级状态”,不看 runtime execution
❓为什么 kubectl get pods 少?
因为:
那个 Pod 已经进入 kubelet,但没有完成生命周期
❓为什么 kubelet hang?
因为:
CRI / kernel syscall 阻塞导致 event loop 停止推进
🔥 10. 最终SRE级定性(可以写RCA)
✔ 故障类型
Node-level Pod execution pipeline stall
✔ 因果链
Kernel / IO / mount stall↓
containerd CreatePodSandbox blocked↓
kubelet syncPod stuck↓
readiness probe / reconciler stall↓
Pod lifecycle not completed↓
DaemonSet 逻辑正常但实际少 Pod
✔ 关键点
-
DaemonSet ≠ runtime truth
-
Pod object ≠ Pod running
-
kubelet hang = syscall block
-
containerd hang = symptom not cause
🚀 11. 如果你要继续往下(建议)
下一步不是看 kubectl,而是:
🔍 必查三件事
-
dmesg(IO / fs / kernel stall)
-
iostat(await / util)
-
containerd logs(shim / create hang)
🧠 一句话总结(SRE版)
你看到的“DaemonSet正常但Pod少”,本质是控制面对象已经收敛,但节点执行链路在 kubelet → CRI → kernel 阶段阻塞,导致 Pod 生命周期未完成,从而产生逻辑一致但运行不一致的现象。
如果你下一步想更深入,我可以帮你画一张:
👉 “kubelet syncPod 卡点分支决策图(直接定位是 volume / CRI / kernel)”
这个可以直接用于线上秒级定位故障。
