查 containerd shim 卡住需先用 ps 找 PID,再通过 ls -l /proc//fd/ 检查残留 fd,最后用 strace -p 观察阻塞在 wait4/epoll_wait/recvfrom;若 runc 已退出但 shim 仍持 socket,需手动清理对应 runtime 目录。
containerd shim 进程卡住,怎么查它在等什么?
shim 进程本身不执行容器,只做 containerd 和 runc 之间的“传话员”;它卡住,通常不是 shim 本身坏了,而是它在等
返回、或等容器进程退出、或等 cgroup 状态就绪。最直接的判断方式是看它的子进程和状态:
用
找出卡住的 shim PID
用
看它是否还持着
或
的 fd(常见于容器没正确 detach)
用
观察最后阻塞在哪个系统调用(通常是
、
或
)
如果
持有
的 socket 连接但
已退出,说明 runc 崩溃后没清理 socket,需手动 kill 并清理
下残留目录
runc exec 进入容器失败,报 “no such process” 或 “container not running”
这不是权限或路径问题,而是
查找容器状态时依赖
文件,而这个文件由 shim 维护——如果 shim 挂了但容器进程还在,
就会找不到合法状态。关键点在于:runc 不直接跟内核打交道,它只读
,并据此生成
和绑定到容器 init 进程的
。
先确认容器是否真在跑:
检查
是否存在且
;若文件损坏或 status 是
,说明 shim 没完成启动流程
必须指定
或通过
指向正确的 runc root(默认
),否则会去错地方找 state
不要用
直接操作——containerd v2 runtime 要求 runc 使用自己的 bundle layout,路径必须匹配 shim 创建时的
字段
调试 OCI runtime 时,如何让 runc 输出详细日志?
默认静默,但它的日志开关不在命令行参数里,而在环境变量和配置中。真正生效的是
+
,且仅当 runc 编译时启用了 debug 支持(主流发行版包通常关闭了)。
Docker Desktop(linux)
当前 Docker 最新稳定版本之一,主要针对稳定性和兼容性进行了修复优化,适合生产环境与日常开发使用。该版本继续强化 AI 开发支持、容器日志管理以及 Docker Engine 的安全能力,对 Windows/macOS/Linux 平台兼容性进行了进一步优化。
下载
临时启用:运行前加
参数必须显式带上,否则
被忽略
注意日志路径需 shim 进程有写权限(比如 containerd 启动 shim 时用的是
用户,不是 root)
如果看到
,大概率是
里多了注释或用了 tab 缩进——OCI spec 严格要求纯 JSON,不能有注释、尾逗号、tab
containerd 重启后容器消失,但 runc list 还能看到?
这是典型的生命周期管理错位:
只扫
下的 state 文件,而 containerd v2 runtime 把容器状态存在
,两者完全不互通。runc 看到的是“孤儿容器”,containerd 认为它们已丢失。
不要直接
这些容器——可能残留 cgroup、网络命名空间、mount ns,导致后续创建失败
正确做法是先用
(如安装了 containerd-devel 包),或手动清理:
更稳妥的是启用 containerd 的
和
配置,避免因 OOM 导致 shim 异常退出却不通知 containerd
所有生产环境务必开启
中的
,否则 cgroup v2 下 runc 和 containerd 对 cgroup 路径解析不一致,重启后状态无法对齐
OCI runtime 调试真正的难点不在命令怎么敲,而在于每个组件只认自己那一小段契约:shim 信 state.json,runc 信 bundle 目录结构,containerd 信 shim 的 gRPC 响应。一旦其中一环状态没同步(比如 shim panic 但没删 state.json),整个链就断成两截,得靠交叉验证才能定位真实断点。
runcps -o pid,ppid,comm,state -C containerd-shimls -l /proc//fd/ initctlconsole-socketstrace -p wait4epoll_waitrecvfromshimruncrunc/run/containerd/io.containerd.runtime.v2.task/// runcstate.jsonrunc exec/run/containerd/io.containerd.runtime.v2.task///state.json exec.fifostdin/stdout/stderrps -eo pid,ppid,comm,args | grep state.json"status": "running"createdrunc exec--pid-file--root/var/run/runcrunc --root /run/containerd/runc/ exec ... bundleruncRUNC_LOGRUNC_LOG_LEVELRUNC_LOG=/tmp/runc.log RUNC_LOG_LEVEL=debug runc --debug run -b --debugRUNC_LOGcontainerdfailed to load OCI config: invalid characterconfig.jsonrunc list/var/run/runc/run/containerd/io.containerd.runtime.v2.task///state.json runc deletecontainerd-stress cleanupfind /run/containerd/io.containerd.runtime.v2.task -name state.json -exec dirname {} \; | xargs -r rm -rfoom_score_adjreclaimable[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]SystemdCgroup = true