Docker 找不到 N 卡:从宿主机到容器的四层排查路线
在容器里敲下nvidia-smi回来的却是command not found或者宿主机上跑得好好的脚本一进镜像就抛出no CUDA-capable device is detected——这套组合症状圈子里被笼统地叫作Docker 找不到 N 卡。它几乎不是某一条配置写错了这么简单的事而是横跨宿主机内核、驱动、容器运行时、镜像内部四层的一次链路断点。我在给算法团队搭环境、帮朋友救现场的过程中被这个问题按在地上摩擦过十几次从以为驱动坏了重装系统到其实是少挂了一个设备节点各种离谱情况都见过。这篇东西就是把这十几回的现场记录整理成一条可复用的排查路线它是什么、卡在哪一层、用什么命令定位、怎么一次配对不返工适合刚上手容器化训练的新同学也适合已经在带环境但总被追问为什么我这边没卡的老手。1. 先给找不到卡分个类别一上来就重装驱动我见过太多人的第一反应是驱动崩了重装。这个动作的代价是半小时到半天而实际问题有相当比例只是容器启动参数少写了三个字符。所以在动手之前先把找不到 N 卡拆成几种完全不同的长相它们对应的处置路径几乎没有交集。1.1 四层结构决定了故障只有四种长相从内核往上数一张显卡要在容器里正常工作必须同时满足四件事内核里有可用驱动、设备节点存在且权限正确、容器启动时被注入了这些节点和用户态库、应用侧的 CUDA 版本能被这套驱动撑住。任何一层断掉表现出来都是没有卡但报错文本差异很大。我把常见的四种长相列在下表你可以先对照着定位自己站在哪一格现象大概率断点典型报错文本容器内nvidia-smi命令不存在镜像内没装工具 / 运行时未注入库command not foundnvidia-smi存在但报加载失败用户态库与内核驱动版本不一致Driver/library version mismatchnvidia-smi正常但框架说没设备环境变量或框架侧可见性被限制no CUDA-capable device is detected容器启动直接失败运行时未注册 / 参数拼写错误could not select device driver with capabilities: [[gpu]]最后那一行could not select device driver with capabilities: [[gpu]]是最经典的一条中间那对空引号就是在告诉你引擎根本不知道有个叫 nvidia 的运行时可以选。看到这句话别去容器里折腾了问题 100% 在宿主机引擎配置侧。1.2 一条黄金排查链路从外往里剥我固化的思路是从外往里剥顺序绝不能反。理由很简单内层依赖外层外层没通的情况下去查内层你只能看到一堆派生现象很容易被误导。顺序是这样的宿主机nvidia-smi是否稳定 → 引擎是否注册了运行时 → 用官方最小镜像验证一次 → 才进你自己的业务镜像。这四步里任何一步没过都不要往下走。中间用官方最小镜像这一步特别关键它把镜像里少装东西这个变量彻底排掉了剩下能出问题的就只有宿主机和引擎。注意不要拿自己的业务镜像当第一验证对象。业务镜像里通常还有一堆依赖、版本锁、启动脚本问题会互相掩盖你会花两倍时间在错误的方向上。1.3 最容易被误判的两种情况第一种是宿主机nvidia-smi正常所以我认定宿主机没问题。这个结论在绝大多数情况下成立但有一个例外驱动刚升级完、内核模块还没重新加载的窗口期nvidia-smi可能因为长时间运行的进程持有旧句柄而暂时显示正常新起的容器却拿不到设备。表现就是我明明刚才还能用。这时候lsmod | grep nvidia和重启相关服务比反复重装镜像管用。第二种是容器里ls /dev/nvidia*一个文件都没有但设备映射我明明写了。这里的分歧点在于有些人写的是--device /dev/nvidia0只映射了编号 0 的设备节点而nvidia-smi还需要/dev/nvidiactl和/dev/nvidia-uvm才能完成初始化。只挂一两个节点工具能起来但会报各种奇怪的初始