文件系统读写锁死在K8s中表现为进程D状态、exec无响应、Pod假运行;需通过ps查D进程、iostat看IO延迟、dmesg查内核阻塞日志定位,优先驱逐Pod而非强制删除,清理overlay2 inode残留并配置overlay2优化参数预防。

文件系统读写锁死在 K8s 环境中往往不会直接表现为“容器崩溃”,而是容器进程卡在 UNINTERRUPTIBLE(D)状态、docker exec 或 kubectl exec 无响应、docker ps 卡住、Pod 持续处于 Running 但服务不可用——这类异常极易被误判为应用逻辑问题,实则根因在底层存储 I/O 阻塞。
确认是否为文件系统锁死引发的卡顿
先排除资源耗尽、网络或配置类问题,聚焦 I/O 层:
- 在宿主机执行
ps aux | awk '$8 ~ /D/ {print}',查看是否存在大量状态为D的进程(尤其是dockerd、containerd-shim或容器内主进程) - 运行
iostat -x 1,观察%util是否长期 100%、await和r_await/w_await是否飙升(>100ms 且持续) - 检查
/proc/mounts中容器使用的挂载点(如/var/lib/docker/overlay2/...)是否含ro(只读)或errors=remount-ro字样,说明文件系统已触发保护性只读 - 查看内核日志:
dmesg -T | grep -i "overlay\|ext4\|xfs\|IO\|blocked",重点关注INFO: task .* blocked for more than 120 seconds或Buffer I/O error
快速恢复业务:绕过锁死容器,避免连锁影响
不要强行 docker kill 或 kubectl delete pod——若底层文件系统已 hang,这些命令本身也会卡住。应优先隔离:
- 对受影响 Pod 执行
kubectl scale deploy/<name> --replicas=0,清空该服务所有实例,防止新请求打到卡死节点 - 若需保留节点上其他 Pod,可临时驱逐该 Pod 所在节点:
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data - 不重启
dockerd或containerd——它们可能正阻塞在内核 I/O 调用中;改用systemctl stop kubelet停止调度,再尝试清理
定位并清理锁死根源(overlay2 / devicemapper 场景)
绝大多数锁死由 overlay2 元数据损坏或 inode 耗尽引发:
- 检查 inode 使用:
df -i /var/lib/docker,若Use%≥ 95%,说明大量小文件(如日志、临时文件)占满 inode,即使磁盘空间充足也会导致 write lock - 定位高 inode 占用目录:
find /var/lib/docker/overlay2 -xdev -type d | sort | uniq -c | sort -nr | head -10 - 若发现某 overlay2 layer 下存在大量
diff/或merged/子目录残留,大概率是容器异常退出未清理 shim,执行:containerd-shim -namespace moby -id <container-id> -address /run/containerd/containerd.sock -publish-binary /usr/bin/containerd publish(慎用),更安全方式是:pkill -f "shim.*<container-id>"→ 再rm -rf /var/lib/docker/overlay2/<layer-id>(仅当该 layer 无其他容器复用时) - 验证 overlay2 健康:
overlayfs-check /var/lib/docker/overlay2(需安装overlayfs-tools)
长期规避策略:从部署与配置入手
锁死本质是“不可恢复的 I/O 故障”,预防优于抢救:
- 禁用
devicemapper(已废弃),统一使用overlay2,并在/etc/docker/daemon.json中启用"storage-driver": "overlay2", "storage-opts": ["overlay2.override_kernel_check=true"] - 为容器设置
securityContext.fsGroup和volumeMounts.readOnly: true(对非必需写入卷),减少意外写操作 - 在节点级限制单个容器最大打开文件数:
systemctl edit docker→ 添加LimitNOFILE=65536,防止 fd 耗尽拖垮整个 daemon - 定期清理镜像与 dangling volume:
docker system prune -af --volumes放入 cron,并监控docker system df输出


















