容器使用NFS作为存储导致节点故障问题记录#
1、基本信息#
| 项目 | 内容 |
|---|---|
| 环境 | 生产环境 |
| 影响服务 | OA系统ekpfront服务 |
| 影响范围 | worker-s007节点上部分Pod |
| 事件级别 | P3S2 |
| 事件状态 | 已处理 |
| 发生事件 | 2026/01/04 |
| 发现时间 | 2026/01/08 |
| 恢复时间 | 2026/01/09 |
2、现象描述#
(1)、OA系统业务反馈他们一个服务(ekpfront-3)在定时任务执行重启之后无法正常启动,其在Web端手动删除该Pod无反应;
(2)、当时从命令行kubectl get pods -n oa查看ekpfront-3的状态处于Terminating,并且时间为4天前(即2026/01/04);
(3)、在所在节点上通过crictl ps | grep ekp查看containerd依然处于Running状态;
(4)、尝试在闭市后通过kubectl delete pod ekpfront-3 -n oa --force强制删除,可删除,但是依然调度本节点上,依然处于之前非正常状态。
3、排查过程#
3.1、初步判断#
根据kubectl describe pod ekpfront-3 -n oa查看Sataus: Terminating(lasts 7h30m)就已经说明了SatefulSet已经发送Delete Pod的指令,并且kubelet应该也发了SIGTERM信号,但是当前查看container依然是Running状态,由此可以初步判断问题是在Pod内部有什么资源没有释放。
3.2、进一步排查#
(1)、通过查看journalctl -u kubelet | grep ekpfront日志
Jan 08 09:22:38 worker-s007 kubelet[14972]: E0108 09:22:38.031080 14972 kubelet.go:1964] [failed to "KillContainer" for "ekpfront" with KillContainerError: "rpc error: code = DeadlineExceeded desc = context deadline exceeded", failed to "KillPodSandbox" for "89caf9fb-a7fc-4da2-9f87-1692b4543f7c" with KillPodSandboxError: "rpc error: code = DeadlineExceeded desc = context deadline exceeded"]
Jan 08 09:22:38 worker-s007 kubelet[14972]: E0108 09:22:38.031119 14972 pod_workers.go:1294] "Error syncing pod, skipping" err="[failed to \"KillContainer\" for \"ekpfront\" with KillContainerError: \"rpc error: code = DeadlineExceeded desc = context deadline exceeded\", failed to \"KillPodSandbox\" for \"89caf9fb-a7fc-4da2-9f87-1692b4543f7c\" with KillPodSandboxError: \"rpc error: code = DeadlineExceeded desc = context deadline exceeded\"]" pod="oa/ekpfront-3" podUID=89caf9fb-a7fc-4da2-9f87-1692b4543f7c
Jan 08 09:25:08 worker-s007 kubelet[14972]: E0108 09:25:08.058531 14972 kuberuntime_container.go:747] "Container termination failed with gracePeriod" err="rpc error: code = DeadlineExceeded desc = context deadline exceeded" pod="oa/ekpfront-3" podUID=89caf9fb-a7fc-4da2-9f87-1692b4543f7c containerName="ekpfront" containerID="containerd://14c5b29b3bea669da9a3c5aec2928c54dc9ba449d2127870b62b825f1ba86224" gracePeriod=30
Jan 08 09:25:08 worker-s007 kubelet[14972]: E0108 09:25:08.058556 14972 kuberuntime_container.go:772] "Kill container failed" err="rpc error: code = DeadlineExceeded desc = context deadline exceeded" pod="oa/ekpfront-3" podUID=89caf9fb-a7fc-4da2-9f87-1692b4543f7c containerName="ekpfront" containerID={Type:containerd ID:14c5b29b3bea669da9a3c5aec2928c54dc9ba449d2127870b62b825f1ba86224}text可以看到kubectl在不停的重试KillContainer,但是并没有成功。
(2)、通过在节点查看容器进程信息
[root@worker-s007 /]# crictl inspect 14c5b29b3bea6 | grep -i pid
"pid": 51990,
"pid": 1
"type": "pid"shell但是通过nsenter -t 51990 -p -m -u -n -i -- ps -ef发现已经无法进入进程空间了
nsenter: cannot open /proc/51990/ns/ipc: No such file or directoryshell再通过以下命令确认了进程状态
[root@worker-s007 /]# ps -o pid,stat,wchan,cmd -p 51990
PID STAT WCHAN CMD
51990 Ss do_wai [startekp.sh]shell通过这个进程状态(do_wait)可以看到在startekp.sh等待子进程结束。通过crictl stop和critctl rm发现也无法直接删除container。
(3)、现在基本可以从容器层次转移到节点系统层次上了。并且通过top查看当前节点负载很高,但是cpu利用率比较低。符合I/O阻塞的典型特征。
(4)、目前已经无法通过df -Th查看相关信息,只能通过df -lh只查看本机文件系统正常。查看NFS挂载信息cat /proc/self/mounts | grep nfs可以看到九个挂载的NFS,通过stat检测发现有三个NFS超时卡死。
3.3、根因分析#
根据以上排查过程,基本可以推断是因为NFS挂载stat卡住,造成kubectl delete pod ekpfront-3 -n oa无法正常删除。
同因导致节点负载持续增长。
4、处理方式#
4.1、临时处理#
(1)、因为worker-s007节点上容器除ekpfront-3外没有发生重启,所以目前受到影响的之后oa系统。为避免扩大影响,将该节点设置为不可调度,并将ekpfront-3强制删除,将其调度到其他节点上。
4.2、修复方式#
若在虚拟机环境中遇到NFS挂载卡顿问题,可尝试执行umount命令解除挂载状态。但鉴于容器与虚拟机的运行机制存在本质差异,且从集群维护角度考量,节点上驱逐容器的操作成本相对可控。因此选择择机通过以下命令组合完成故障修复:首先执行kubectl drain worker-s007 --force --ignore-daemonsets --delete-emptydir-data强制迁移该节点上的所有Pod,随后对该节点实施重启操作以恢复服务能力。。
重启节点后状态恢复健康,恢复调度重新参与集群调度。
5、改进措施#
(1)、为避免出现类似问题建议业务pod中修正PID 1为Java进程;
(2)、建议增加preStop钩子优雅退出;
(3)、集群节点负载较高,发出的告警未接收到。需要优化
【20260423补充】#
今日在测试环境碰到同样的问题,通过挨个节点查看uptime系统负载,发现有四个节点出现高负载问题,其中一个节点出现了10000多的负载。
1、按照之前的经验进行排查,发现df -lh正常,df -Th会卡死,这么基本确定问题又出在NFS上了。
2、通过mount | grep nfs(得亏还能使)查看挂载信息,并通过stat /data/var/lib/kubelet/pods/5006c03b-649b-45b4-8652-32a1585a61de/volumes/kubernetes.io~csi/pvc-8c5a8ec7-3a4b-4376-841c-372a4e889cfc/mount对各挂载点进行尝试查询,以及通过timeout 3 showmount -e <NFS_SERVER>查看是否可正常通信。经过排查发现showmount其中一个NFS Server的时候报错。
3、和改NFS Server负责人以及NFS管理员确认,改NFS已经停止服务,但是从Kubernetes集群上查看使用该NFS的Pod还在运行,并且因为挂载模式为hard,所以会卡死。
4、因为相关Pod负责人反馈已经下线,所以通过把所有使用该NFS的Pod进行强制删除kubectl delete pod <pod-name> -n one --force --grace-period=0
5、强删pod之后,到对应节点上挨个把相关挂载卸载umount -lf /data/var/lib/kubelet/pods/5006c03b-649b-45b4-8652-32a1585a61de/volumes/kubernetes.io~csi/pvc-8c5a8ec7-3a4b-4376-841c-372a4e889cfc/mount
6、基本可以恢复正常,可以通过ps -eo state,pid,cmd | grep "^D"查看umount前后区别。
这次故障和之前生产的问题有一个区别,在于如何恢复,因为本次是使用NFS的Pod皆可以删除,所以