这篇教程解决什么问题
很多服务器在宿主机执行 `nvidia-smi` 正常,但Docker容器内看不到GPU;也有人为了运行CUDA容器,先在宿主机安装一整套CUDA Toolkit,结果驱动、运行时和框架版本互相污染。正确链路应分为三层:宿主机内核驱动负责控制GPU,NVIDIA Container Toolkit把设备和驱动库注入容器,容器镜像再提供与应用匹配的CUDA用户态运行时。
本文以Ubuntu和Docker Engine为例。执行前应确认服务器没有正在运行的重要GPU容器,因为配置运行时后需要重启Docker。
第一步:记录宿主机基线
cat /etc/os-release
uname -r
nvidia-smi
docker version
docker info | sed -n '/Runtimes/,+3p'`nvidia-smi` 若失败,先停止后面的步骤。常见原因包括驱动模块没有加载、内核升级后DKMS未重新编译、Secure Boot阻止模块加载,或GPU发生Xid错误。此时应检查:
lsmod | grep nvidia
dmesg -T | grep -Ei 'nvidia|NVRM|Xid' | tail -n 80
dkms status不要把“`nvidia-smi`显示CUDA 12.x”理解为宿主机已经安装CUDA Toolkit。这个数字表示当前驱动能够支持的最高CUDA兼容级别,并不是 `nvcc` 的版本。
第二步:添加官方软件源并安装Toolkit
先安装下载和密钥工具:
sudo apt-get update
sudo apt-get install -y --no-install-recommends ca-certificates curl gnupg2按照NVIDIA当前官方文档添加生产软件源:
```bash curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \ | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \ | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \ | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt-get update apt-cache policy nvidia-container-toolkit sudo apt-get install -y nvidia-container-toolkit nvidia-ctk --version ```
生产服务器建议在验证后锁定软件包版本,并把 `apt-cache policy` 输出保存进变更记录。不要开启experimental软件源,除非确实要验证实验功能。
第三步:配置Docker运行时
先备份已有Docker配置:
```bash sudo install -D -m 0644 /etc/docker/daemon.json \ /etc/docker/daemon.json.before-nvidia 2>/dev/null || true
sudo nvidia-ctk runtime configure --runtime=docker sudo cat /etc/docker/daemon.json sudo systemctl restart docker sudo systemctl --no-pager --full status docker docker info | sed -n '/Runtimes/,+3p' ```
`nvidia-ctk`会修改 `/etc/docker/daemon.json`,让Docker知道NVIDIA运行时。已有镜像加速、日志驱动或数据目录配置不应被删除;如果重启失败,用 `journalctl -u docker -n 100` 检查JSON格式和配置冲突。
第四步:用最小CUDA容器验收
选择镜像前先核对驱动兼容性。下面的标签只是示例,实际应使用业务已验证并固定的镜像版本:
```bash docker run --rm --gpus all \ nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi
docker run --rm --gpus '"device=0"' \ nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi -L ```
验收结果必须同时满足:容器能列出预期GPU数量;型号和UUID与宿主机一致;驱动版本一致;指定单卡时没有泄露其他GPU。八卡服务器应逐卡执行一次指定设备测试,避免只验证0号卡。
再验证PyTorch,而不是停在nvidia-smi
`nvidia-smi`只证明管理接口可用,不证明深度学习算子能运行。使用与你项目匹配的PyTorch官方镜像执行张量计算:
docker run --rm --gpus all --ipc=host pytorch/pytorch:2.5.1-cuda12.4-cudnn9-runtime \
python -c "import torch; print(torch.__version__); print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0)); x=torch.randn(4096,4096,device='cuda'); print(float((x@x).mean()))"首次运行要观察 `nvidia-smi` 中的进程和显存变化。正式使用时固定镜像摘要,而非长期使用 `latest`。
高频故障及定位顺序
could not select device driver / unknown runtime
先运行 `docker info` 查看运行时,再检查 `daemon.json` 和Docker日志。不要反复重装驱动,因为问题通常发生在容器运行时配置层。
容器提示driver/library version mismatch
多见于驱动升级后未重启,内核中仍运行旧模块。比较 `cat /proc/driver/nvidia/version` 与软件包版本,并安排受控重启。
宿主机正常,容器无权限访问设备
检查是否使用rootless Docker、cgroup配置和安全策略。rootless模式需要使用官方文档中单独的配置路径,不能照搬系统Docker命令。
systemctl daemon-reload后容器丢失GPU
NVIDIA文档提示systemd cgroup环境存在已知问题。发生后保存运行时与cgroup信息,按官方故障说明处理,并在基础设施变更中加入GPU容器回归检查。
生产交付清单
- 保存OS、内核、驱动、Toolkit、Docker和镜像摘要。
- 重启宿主机后重新完成单卡、全卡和张量计算测试。
- 监控GPU温度、功耗、显存、Xid错误和容器重启次数。
- 不把Docker TCP端口或模型API直接暴露公网。
- 升级驱动与Toolkit前保留旧软件包和配置备份。
做到这些,才算完成“容器能稳定使用GPU”的交付,而不只是偶然执行成功一次 `nvidia-smi`。


