记录一次线上k8s工作节点无法创建容器的问题排查思路与解决办法
记录因CPU配置变更导致的K8s节点容器初始化故障排查过程,涉及kubelet的static CPU管理策略与超线程配置冲突问题。
故障现象速览
- 环境版本:
K8s版本:1.17.2
docker版本:19.03.5 - 核心症状:
节点维护后状态Ready但所有Pod卡在PodInitializing
节点机无容器进程(docker ps无输出)
kubelet报错:invalid memory address or nil pointer dereference
结论先行
问题根源
- kubelet 启动参数配置cpu管理策略为:
--cpu-manager-policy=static
- 节点启用CPU超线程导致CPU核心数变化
- kubelet static策略记录的CPU分配与实际拓扑不匹配
修复方案
# 清除失效的CPU分配记录
systemctl stop kubelet
mv /var/lib/kubelet/cpu_manager_state{,.bak}
systemctl start kubelet
排查过程
现象详细描述:k8s节点重启后状态恢复为Ready,但是该节点上包括calico-node、kube-proxy在内的所有Pod都一直处于PodInitializing状态,查看Pod的Events只有一条成功调度到节点机的事件,到节点机上docker ps查看没有任何容器创建,每次容器调度到该节点机时,kubelet有一条报错如下:
E0212 15:52:49.795723 194079 runtime.go:78] Observed a panic: "invalid memory address or nil pointer dereference" (runtime error: invalid memory address or nil pointer dereference)
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: goroutine 29537 [running]:
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/runtime.logPanic(0x3a218e0, 0x6d74f50)
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: /workspace/anago-v1.17.2-beta.0.2+59603c6e503c87/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go:74 +0xa3
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/runtime.HandleCrash(0x0, 0x0, 0x0)
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: /workspace/anago-v1.17.2-beta.0.2+59603c6e503c87/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go:48 +0x82
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: panic(0x3a218e0, 0x6d74f50)
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: /usr/local/go/src/runtime/panic.go:679 +0x1b2
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: k8s.io/kubernetes/pkg/kubelet/cm.(*qosContainerManagerImpl).setCPUCgroupConfig(0xc000230460, 0xc001fbb050, 0x42717de, 0xa)
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: /workspace/anago-v1.17.2-beta.0.2+59603c6e503c87/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/pkg/kubelet/cm/qos_container_manager_linux.go:169 +0x3b
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: k8s.io/kubernetes/pkg/kubelet/cm.(*qosContainerManagerImpl).UpdateCgroups(0xc000230460, 0x0, 0x0)
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: /workspace/anago-v1.17.2-beta.0.2+59603c6e503c87/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/pkg/kubelet/cm/qos_container_manager_linux.go:285 +0x291
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: k8s.io/kubernetes/pkg/kubelet/cm.(*containerManagerImpl).UpdateQOSCgroups(0xc0004038c0, 0xc001d68800, 0xc001fd4600)
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: /workspace/anago-v1.17.2-beta.0.2+59603c6e503c87/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_linux.go:560 +0x3a
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: k8s.io/kubernetes/pkg/kubelet.(*Kubelet).syncPod(0xc0007a4a80, 0x0, 0xc001d68800, 0x2, 0xc001fd4000, 0x0, 0xc001fd0060, 0xc000880390)
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: /workspace/anago-v1.17.2-beta.0.2+59603c6e503c87/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/pkg/kubelet/kubelet.go:1626 +0x214b
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: k8s.io/kubernetes/pkg/kubelet.(*podWorkers).managePodLoop.func1(0xc000fbaea0, 0xc00073c5b0, 0xc001fbbe88, 0x6, 0xc0009bf018)
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: /workspace/anago-v1.17.2-beta.0.2+59603c6e503c87/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/pkg/kubelet/pod_workers.go:175 +0x25d
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: k8s.io/kubernetes/pkg/kubelet.(*podWorkers).managePodLoop(0xc00073c5b0, 0xc001fd0000)
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: /workspace/anago-v1.17.2-beta.0.2+59603c6e503c87/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/pkg/kubelet/pod_workers.go:184 +0x13f
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: k8s.io/kubernetes/pkg/kubelet.(*podWorkers).UpdatePod.func1(0xc00073c5b0, 0xc001fd0000)
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: /workspace/anago-v1.17.2-beta.0.2+59603c6e503c87/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/pkg/kubelet/pod_workers.go:222 +0x6c
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: created by k8s.io/kubernetes/pkg/kubelet.(*podWorkers).UpdatePod
Feb 12 15:52:49 fs1288d23-k8s kubelet[194079]: /workspace/anago-v1.17.2-beta.0.2+59603c6e503c87/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/pkg/kubelet/pod_workers.go:220 +0x3d3
初试无果
一开始不知道CPU被重新配置过也没有任何思路,尝试重启Docker、Kubelet没有效果。
以为是节点重启后文件被损坏,对比其它节点机上docker和Kubelet配置文件的权限和状态均正常。
关键突破
通过报错中的关键信息pkg/kubelet/cm/qos_container_manager_linux.go
和@Paco大佬的帮助,搜索到kubernetes#86676该ISSUE和我遇到的报错信息类似,尝试删除cpu_manager_state文件后再启动kubelet重新生成该cpu_manager_state文件,此时已经恢复正常。
复盘新发现
虽然几经波折解决了这个问题,还是没发现这个问题的根本原因,难道和kubernetes#86676一样是由于Kubelet的Bug引起?其实并不是
1.确认Kubelet CPU管理策略
$ ps aux | grep kubelet | grep -o 'cpu-manager-policy=[^ ]*'
cpu-manager-policy=static
2.通过对比cpu_manager_state文件的两个版本,其实问题容易发现原先defaultCpuSet为0-23,现在为0-47
$ diff /var/lib/kubelet/cpu_manager_state*
1c1
< {"policyName":"static","defaultCpuSet":"0-47","checksum":990655235}
\ No newline at end of file
---
> {"policyName":"static","defaultCpuSet":"0-23","checksum":533444001}
\ No newline at end of file
3.通过lscpu命令查看CPU信息,获取当前CPU拓扑
$ lscpu | grep -E 'CPU\(s\)|Thread|Core|Socket'
CPU(s): 48 # 逻辑核心数
On-line CPU(s) list: 0-47
Thread(s) per core: 2 # 每个核心的线程数,表示超线程开启
Core(s) per socket: 12 # 每个 CPU 上的物理核心数量
Socket(s): 2 # 物理 CPU 插槽数量
NUMA node0 CPU(s): 0-11,24-35
NUMA node1 CPU(s): 12-23,36-47
根据输出信息:48 = 2×12x2,可以判定CPU被开启了超线程
4.同时我们再回过头去查看kubelet日志发现 kubelet启动时有如下报错,开始被我们忽略了:
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: E0212 12:09:48.667131 3776 runtime.go:76] Observed a panic: [cpumanager] - please drain node and remove policy state file
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: goroutine 534 [running]:
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/runtime.logPanic(0x3755be0, 0x48b6e70)
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: /workspace/anago-v1.17.2-beta.0.2+59603c6e503c87/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/ru
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/runtime.HandleCrash(0x0, 0x0, 0x0)
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: /workspace/anago-v1.17.2-beta.0.2+59603c6e503c87/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/ru
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: panic(0x3755be0, 0x48b6e70)
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: /usr/local/go/src/runtime/panic.go:679 +0x1b2
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: k8s.io/kubernetes/pkg/kubelet/cm/cpumanager.(*staticPolicy).Start(0xc00081d380, 0x4a4c780, 0xc000894600)
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: /workspace/anago-v1.17.2-beta.0.2+59603c6e503c87/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_stati
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: k8s.io/kubernetes/pkg/kubelet/cm/cpumanager.(*manager).Start(0xc0002ce500, 0xc00090e0b0, 0x497a860, 0xc00081de60, 0x7f226c77f248, 0xc000895380, 0x7f2272e
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: /workspace/anago-v1.17.2-beta.0.2+59603c6e503c87/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager.
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: k8s.io/kubernetes/pkg/kubelet/cm.(*containerManagerImpl).Start(0xc00040b8c0, 0xc000358f00, 0xc00090e0b0, 0x497a860, 0xc00081de60, 0x7f226c77f248, 0xc0008
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: /workspace/anago-v1.17.2-beta.0.2+59603c6e503c87/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_linux
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: k8s.io/kubernetes/pkg/kubelet.(*Kubelet).initializeRuntimeDependentModules(0xc0006fca80)
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: /workspace/anago-v1.17.2-beta.0.2+59603c6e503c87/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/pkg/kubelet/kubelet.go:1378 +0x2a8
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: sync.(*Once).doSlow(0xc0006fd228, 0xc000e89de8)
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: /usr/local/go/src/sync/once.go:66 +0xe3
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: sync.(*Once).Do(...)
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: /usr/local/go/src/sync/once.go:57
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: k8s.io/kubernetes/pkg/kubelet.(*Kubelet).updateRuntimeUp(0xc0006fca80)
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: /workspace/anago-v1.17.2-beta.0.2+59603c6e503c87/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/pkg/kubelet/kubelet.go:2199 +0x4e8
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/wait.JitterUntil.func1(0xc0008e6bd0)
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: /workspace/anago-v1.17.2-beta.0.2+59603c6e503c87/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/wa
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/wait.JitterUntil(0xc0008e6bd0, 0x12a05f200, 0x0, 0x1, 0xc0001160c0)
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: /workspace/anago-v1.17.2-beta.0.2+59603c6e503c87/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/wa
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/wait.Until(0xc0008e6bd0, 0x12a05f200, 0xc0001160c0)
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: /workspace/anago-v1.17.2-beta.0.2+59603c6e503c87/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/util/wa
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: created by k8s.io/kubernetes/pkg/kubelet.(*Kubelet).Run
Feb 12 12:09:48 fs1288d23-k8s kubelet[3776]: /workspace/anago-v1.17.2-beta.0.2+59603c6e503c87/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes/pkg/kubelet/kubelet.go:1427 +0x162
5.同时统计kubelet重启次数发现有多次重启,其实Kubelet报错后已经重启过,只是启动太快我们没发现,如果当时有发现这个也能断定是kubelet的问题。
sudo journalctl -u kubelet | grep -i "Started kubelet" | wc -l
最终结论
所以问题最终结论就是:
如果kubelet 启动参数--cpu-manager-policy=static
(可以通过systemctl status kubelet -l
查看),那么就会在参数 --root-dir
指定的目录(默认是/var/lib/kubelet
)下生成一个 cpu_manager_state 这样一个绑定文件。
cpu_manager_state 内容大致长得如下:
{ "policyName": "static", "defaultCpuSet": "0-23", "checksum": 533444001 }
当你升级或修改这个 k8s node 节点的 CPU 配置,并且使用了 static cpu 管理模式,那么 kubelet 会读取 cpu_manager_state 文件,然后跟现有的宿主运行的资源做对比,如果不一致,kubelet 就会有问题。
附:cpu_manager_state 文件机制
属性 | 说明 | 故障影响 |
---|---|---|
存储路径 | --root-dir指定(默认/var/lib/kubelet) | 路径错误导致配置失效 |
数据结构 | JSON格式记录CPU分配状态 | 格式损坏引发空指针异常 |
校验机制 | checksum校验CPU拓扑一致性 | 拓扑变化导致校验失败 |
1、功能定义
cpu_manager_state 是 Kubelet 组件在使用 static CPU 管理策略时生成的状态持久化文件,用于记录容器与 CPU 核心的绑定关系。其作用包括:
存储已分配独占 CPU 的容器信息(如 Pod UID、容器名称及分配的 CPU 核心)。
维护共享池(Shared Pool)中可用的 CPU 核心列表。
确保节点重启后,Kubelet 能根据历史记录恢复 CPU 分配状态,避免资源冲突。
2、工作流程
当 Pod 调度到节点时,Kubelet 的 CPU Manager 根据静态策略(static)从共享池中选择最优的 CPU 核心组合分配给容器。
分配的 CPU 核心信息会被写入 cpu_manager_state 文件,并更新 CGroup 的 cpuset.cpus 参数。
容器删除时,分配的 CPU 核心会归还到共享池,并同步更新状态文件。
3、关键性影响
若该文件损坏或与当前节点 CPU 拓扑不匹配(如节点 CPU 升级后),Kubelet 将无法启动。
文件路径由 --root-dir 参数指定,默认位于 /var/lib/kubelet。
对于以上文中提到的错误原因
1、该错误通常发生在以下场景:
状态文件解析异常:当 cpu_manager_state 文件内容不完整或格式错误时,Kubelet 在加载文件时可能访问未初始化的内存地址。
空指针引用:代码逻辑中未对可能为 nil 的变量进行安全检查(如未正确处理旧版本状态文件的结构差异)。
拓扑信息不一致:节点硬件变更(如 CPU 核心数变化)导致状态文件记录的 CPU 分配与实际拓扑冲突,引发空指针解引用5。
2、典型触发条件
节点重启后,Kubelet 尝试加载过时或损坏的 cpu_manager_state 文件。
Kubernetes 1.17 及其之前版本的 CPU Manager 模块在异常处理逻辑上存在缺陷,未充分校验文件内容或硬件状态,在Kubernetes 1.18中修复
总结
- 发现错误应该引起重视,不要想当然的忽视关键错误信息
- 对于CPU 管理器策略的更改,需要通过删除 kubelet 根目录中的状态文件 cpu_manager_state 来手动重置 CPU 管理器。这在kubernetes官方文档中也有说明,见参考1