Ubuntu 22.04 LTS 上安装 NVIDIA Container Toolkit是我这几年搭深度学习环境时每次都要打交道的环节。简单说这个东西就是让 Docker 容器能直接调用宿主机 GPU 驱动、CUDA 运行时的桥梁——装好了你就可以在容器里跑 PyTorch、跑训练脚本、跑推理服务而且不用在容器里重装一遍驱动。对刚接触容器化开发的人来说最直观的体感就是docker run 命令后面加一个 --gpus all 参数GPU 就真的能被容器识别了。这篇文章我会从环境准备、实际安装、验证测试、进阶参数到问题排查把完整流程从头到尾捋一遍。适合刚给 Ubuntu 22.04 装好系统、正准备用 Docker 跑深度学习项目的朋友也适合已经在用 Docker 但容器里一直用不了 GPU、被各种报错折腾过的人。整个安装链路其实不长但有几个细节处理不好后面跑起来全是坑我尽量把能踩的都提前指出来。1. 环境准备与前置检查1.1 确认系统、驱动与 Docker 版本不管之前看过多少篇教程第一步永远是先检查环境别上来就敲安装命令。NVIDIA Container Toolkit 不是一个独立运行的软件它依赖三个前提操作系统、NVIDIA 显卡驱动、Docker Engine。这三样里任何一样不对后面装完照样用不了。先确认系统版本。Ubuntu 22.04 LTS 的系统信息可以通过下面的命令查lsb_release -a cat /etc/os-release输出里能看到 distro 描述和版本号确认是 Ubuntu 22.04.x 就没问题。如果你是从 20.04 或者 21.10 升级上来的建议先确认一下内核能否正常加载新驱动我之前遇到过升级完系统后 NVIDIA 驱动模块没跟着重建的情况表现为开机黑屏或者 nvidia-smi 命令找不到。然后是显卡驱动。驱动是否装好一条命令就能确认nvidia-smi能正常输出 GPU 型号、驱动版本、显存占用信息说明驱动层面没问题。如果提示command not found或者报错No devices were found那就要先处理驱动。Ubuntu 22.04 自带的开源驱动 Nouveau 和 NVIDIA 闭源驱动冲突的问题很常见我自己折腾过几次后发现最稳妥的还是用官方的ubuntu-drivers工具来装它能自动匹配推荐版本sudo ubuntu-drivers autoinstall安装完成后重启系统再跑一遍nvidia-smi验证。这里有个小经验驱动版本不要太新也不要太旧。Ubuntu 22.04 下我实测过470 系列以上的驱动配合 Container Toolkit 都很顺畅新买的工作站显卡可以用 535 或者 550 系列老一点的卡别硬追新版驱动稳定压倒一切。最后看 Docker Engine。docker --version确认 Docker 已安装如果没有装一下。很多教程直接用apt install docker.io但如果你打算在生产环境或者长期开发中重度使用 Docker我更推荐装 Docker 官方源的版本社区维护更活跃后续升级也方便sudo apt update sudo apt install apt-transport-https ca-certificates curl software-properties-common curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo deb [arch$(dpkg --print-architecture) signed-by/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null sudo apt update sudo apt install docker-ceDocker 装完建议顺手把当前用户加进 docker 组否则每次执行 docker 命令都要加 sudo操作起来很别扭sudo usermod -aG docker $USER newgrp docker如果你是在远程服务器上操作session 重连一次就能生效。1.2 理解 Container Toolkit 在整条链路里的位置好多人对 NVIDIA Container Toolkit 有误解以为装上它之后容器里就自带 CUDA 了。不是这么回事。打个比方宿主机上的 NVIDIA 驱动就像是发电厂Container Toolkit 只是把电输送到容器这座工厂里的输电线。它本身不发电也就是不包含 CUDA 库和 cuDNN 这些计算库这些库是你选的镜像里自带的。比如nvidia/cuda:11.8.0-base-ubuntu22.04这个镜像里面就封装好了 CUDA 运行环境然后 Container Toolkit 负责在容器启动时把宿主机的 GPU 设备和驱动文件安全地映射进去。这个设计的好处很明显第一宿主机驱动只需要一份不需要在每个容器里重复安装第二容器镜像可以做得相对小更换 CUDA 版本时不需要动宿主机驱动第三多个容器可以共享同一块 GPU互不干扰。理解了这一点后面遇到“进去容器发现 nvidia-smi 能用但 CUDA 版本不对”这类问题时就心里有数了——那不是 toolkit 的问题是镜像选错了。还有一个小点得提醒NVIDIA Container Toolkit 对 Docker 的最低版本要求是 19.03因为 19.03 开始 Docker 才原生支持 GPU 设备注入。Ubuntu 22.04 仓库里的 docker.io 版本可能比较老如果你之前是直接 apt 装的建议升级到最新版再用。2. 安装 NVIDIA Container Toolkit 的完整流程2.1 添加 NVIDIA 官方 apt 源NVIDIA 为 Container Toolkit 提供了独立 apt 源这一步的目的就是让系统能通过常规的apt install方式安装和后续更新。配置过程其实就四行命令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 /dev/null我见过有人在配置 apt 源时跳过 GPG key 签名验证直接把源地址写进去结果 apt update 的时候报The following signatures couldnt be verified because the public key is not available。别看它只是 warning在某些系统配置下会直接导致软件包安装失败。所以上面这两条命令一步都不能省它把 NVIDIA 的 GPG 公钥单独导出到 keyring 文件里然后在源列表里用signed-by指定了这个公钥相当于给 apt 加了一道验签机制。如果你在 curl 下载 gpgkey 时遇到网络连接问题可以手动把 https://nvidia.github.io/libnvidia-container/gpgkey 这个地址在浏览器里打开复制内容存到本地的 keyring 文件里。路径不要随意改动因为后面 toolkit 的 .list 文件里写的就是这个路径。接下来刷新软件源缓存sudo apt update正常状态下apt 输出里能看到 nvidia-container-toolkit 相关的索引信息。要是这一步报错大概率是源地址中的系统版本代号和实际版本不匹配。Ubuntu 22.04 的代号是 jammy你可以打开 /etc/apt/sources.list.d/nvidia-container-toolkit.list 确认里面确实写的是 jammy别是 impish 或者 focal我记得早期版本的 NVIDIA 源默认服务旧系统手动改过才好用的。2.2 安装 toolkit 与 nvidia-docker2 的选择这里有一个容易让新手困惑的点网上教程有的让你装nvidia-docker2有的让你装nvidia-container-toolkit到底装哪个我的建议是直接装nvidia-container-toolkit。nvidia-docker2 是 NVIDIA 早期的 Docker 集成方案它本质上是个 meta 包会依赖底层的 nvidia-container-toolkit但在 Docker 配置管理方面封装了一套旧逻辑。自 Docker 19.03 以来Docker 原生通过--gpus选项来暴露 GPU 设备nvidia-container-toolkit 已经能完整实现所有功能安装一个即可sudo apt install -y nvidia-container-toolkit装好之后会多出几个关键组件最核心的是/usr/bin/nvidia-container-toolkit它是实际的运行时接口程序另外还有/usr/bin/nvidia-container-runtime它是一个 shim 层负责在 Docker 调用 runc 时拦截处理 GPU 相关的配置。如果之前装过 nvidia-docker 或者旧版 nvidia-container-runtime建议先彻底卸载避免和新版冲突sudo apt remove --purge -y nvidia-docker2 nvidia-container-runtime卸载完之后确认一下/etc/docker/daemon.json里没有残留的旧配置最稳妥的做法是清掉重写这一步我在下一节细说。2.3 配置 Docker runtime 并重启生效安装完 toolkit 之后还需要告诉 Docker“你以后碰到 GPU 请求要用 nvidia 这个运行时来处理”。Docker 的运行时配置写在/etc/docker/daemon.json里。不过 NVIDIA 提供了一个自动配置工具省得我们手改sudo nvidia-ctk runtime configure --runtimedocker这条命令会自动读取当前 Docker 的 daemon 配置文件把 nvidia runtime 的信息合并进去。执行完之后你可以打开 /etc/docker/daemon.json 看效果正常情况下会多这么一段{ runtimes: { nvidia: { args: [], path: nvidia-container-runtime } } }如果你之前从来没配置过 daemon.json命令会直接创建一个新文件。如果你已经有其他配置项比如 registry-mirrors、log-driver 之类的nvidia-ctk 会把原有内容保留并追加 nvidia runtime 段所以不用担心覆盖问题。然后重启 Docker 让配置生效sudo systemctl restart docker注意如果重启 Docker 时报错了先别急用journalctl -u docker -n 50看一下日志最常见的问题是 daemon.json 的 JSON 格式写错比如多加了一个逗号或者引号不成对。用python3 -m json.tool /etc/docker/daemon.json可以快速校验格式。到这里Container Toolkit 的安装和配置环节就算完成了。整个安装过程没有特别复杂的地方真正的考验在验证环节我遇到太多“装完以后一跑就报错”的情况了。3. 验证安装与跑通 GPU 容器3.1 用 nvidia/cuda 基础镜像快速验证安装是否成功不需要写任何应用代码直接用官方提供的基础镜像验证最省事。拉取一个带 CUDA 的基础镜像在容器里跑 nvidia-smi能正常显示 GPU 信息就算通了docker run --rm --gpus all nvidia/cuda:11.8.0-base-ubuntu22.04 nvidia-smi命令拆开解释一下--rm表示容器退出后自动删除验证用足够了不会留垃圾--gpus all是让 Docker 把宿主机上所有 GPU 都暴露给容器后面跟的镜像名和命令就是要做的事。第一次跑的时候会先拉取镜像镜像大概几百 MB等一会自然就好。如果一切正常你会看到类似下面的输出----------------------------------------------------------------------------- | NVIDIA-SMI 550.54.15 Driver Version: 550.54.15 CUDA Version: 12.4 | |---------------------------------------------------------------------------看到这个输出就说明整条链路已经通了。容器里的 nvidia-smi 和宿主机上看到的驱动版本、CUDA 版本应该是一致的这正好验证了前面说的驱动在宿主机上容器只是借用的。3.2 验证镜像的 CUDA 版本与宿主机驱动是否匹配上面的基础镜像拉取之后还可以顺手验证一下容器内 CUDA 的可用性docker run --rm --gpus all nvidia/cuda:11.8.0-base-ubuntu22.04 nvcc --versionnvcc 是 CUDA 的编译器能输出版本就说明镜像里带的是完整可用的 CUDA 环境。但这里有一个特别普遍的认知误区也是我被同事问过最多的问题为什么容器里 nvidia-smi 显示 CUDA 12.4而 nvcc 显示的是 11.8这两者其实不是一回事。nvidia-smi 里显示的 CUDA Version 是指当前显卡驱动所支持的最高 CUDA 版本它是一个兼容性指标说明你的驱动能跑这个版本的 CUDA 或者更低的而 nvcc 的版本号才是镜像里真实安装的 CUDA 工具包版本。驱动支持的最高 CUDA 版本必须大于等于容器内的 CUDA 版本否则会出现 “CUDA driver version is insufficient for CUDA runtime version” 的错误。这就是为什么 nvidia/cuda 镜像会按不同的 Ubuntu 版本和 CUDA 版本分发你得根据宿主机驱动支持范围来选择镜像标签。比如驱动是 550.54.15它支持的最高 CUDA 版本是 12.4你就可以放心用 12.x、11.x 甚至更低版本的 CUDA 镜像。反过来如果驱动是 470 系列的最多支持到 CUDA 11.4硬跑 12.x 的镜像就会报错了。3.3 在真实项目容器里测试 GPU 算力官方基础镜像验证只是第一步我更建议你用自己的实际项目镜像测一下 GPU 算力是否真的能被调用。比如你在用 PyTorch可以启动一个 PyTorch 镜像在容器里跑一段简单的 GPU 张量计算docker run --rm --gpus all -it pytorch/pytorch:2.0.0-cuda11.8-cudnn8-runtime bash进入容器后执行python -c import torch; print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0))如果输出True NVIDIA GeForce RTX 4090说明 PyTorch 已经能正常使用 GPU。这一步很有必要因为有些镜像虽然能跑 nvidia-smi但缺少 PyTorch 运行时对应的 CUDA 依赖库真跑训练脚本时还是会报错。用真实项目镜像测试能提前暴露这类问题。4. 进阶参数与容器 GPU 能力控制4.1 按需指定 GPU 设备而非全量分配--gpus all 是最直接的用法开发环境无所谓但生产环境或者多人共用的服务器上我更推荐指定具体的 GPU 编号避免别人跑任务时你把整机的显存都占了。查看 GPU 编号用nvidia-smi -L它会按物理顺序列出所有显卡一般从 0 开始编号。然后指定用第 0 号和第 2 号卡docker run --rm --gpus device0,2 nvidia/cuda:11.8.0-base-ubuntu22.04 nvidia-smiDocker 还支持按 UUID 指定理论上更通用但实际使用中 device 编号更直观。还有一种常见的需求是只让容器看到两张卡中的一张比如 A 任务跑 0 号卡B 任务跑 1 号卡每个容器各用各的互不干扰。这种隔离方式在共享服务器上非常管用能有效避免大家挤在同一块卡上把显存打爆。如果你用 Docker Compose 管理服务写法也就多一个字段services: train: image: pytorch/pytorch:2.0.0-cuda11.8-cudnn8-runtime deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu]这里的 count 可以写成 all 或者具体数量capabilities 必须写 gpu否则不会被识别。4.2 理解 capabilities 参数的五个能力域--gpus 参数背后其实隐藏着一组更细的控件就是 NVIDIA_DRIVER_CAPABILITIES 环境变量。这可以说是进阶使用中最关键、也最容易被忽略的一个配置。它控制着容器内挂载哪些 GPU 功能模块取值包括能力值作用典型场景utilitynvidia-smi 和显卡管理工具基础监控与查询computeCUDA 和 OpenCL 计算深度学习训练、科学计算graphicsOpenGL 和 Vulkan 图形接口图形渲染、远程桌面video视频编码解码硬件加速FFmpeg 转码、视频服务display显示输出支持X11 图形输出默认情况下 Containerd 和 Docker 的 --gpus 注入会给容器带上 utility 和 compute 两个能力这也解释了为什么很多容器里能跑 nvidia-smi 也能做 CUDA 计算。但如果你要在容器里做视频硬解比如用 FFmpeg 调用 NVENC就得在容器里设置docker run --rm -it --gpus all \ -e NVIDIA_DRIVER_CAPABILITIESvideo,compute,utility \ nvidia/cuda:11.8.0-base-ubuntu22.04 bash忘了加 video 能力进去容器后 FFmpeg 会很奇怪地找不到编码器或者调用硬件编码时直接报Cannot load nvcuvid shared library。这个问题折磨了我挺久后来才发现是 capabilities 少配置了根本不是 FFmpeg 或者驱动的问题。还有一个 NVIDIA_VISIBLE_DEVICES 环境变量它和 --gpus 的 device 参数作用类似但更适合在 Dockerfile 或者 Compose 文件里统一管理。比如你希望默认只暴露第 1 块卡可以在 Dockerfile 里写ENV NVIDIA_VISIBLE_DEVICES1这样即使外部启动容器时用了 --gpus all容器里也只会看到编号为 1 的显卡。这在封装团队镜像时是个很实用的控制手段能避免使用者不小心申请了过多 GPU 资源。4.3 解决容器内共享内存不足与 CUDA 初始化失败深度学习训练还有一个高频坑和 GPU 本身无关但经常表现成 GPU 相关错误——容器默认共享内存太小。PyTorch 的 DataLoader 多进程加载数据时如果 /dev/shm 空间不足会报出ERROR: Unexpected bus error encountered in worker. This might be caused by insufficient shared memory (shm)的错误。我见过不少人在这个问题上卡了很久以为是 GPU 资源分配不够实际问题是容器内共享内存只有默认的 64MB。解决办法是在 docker run 时加一个参数docker run --rm --gpus all -it --shm-size16g pytorch/pytorch:2.0.0-cuda11.8-cudnn8-runtime bash--shm-size 设置的是容器内 /dev/shm 的大小调成 16GB 或者宿主机物理内存的一半都行。如果你用 Docker Compose对应配置是services: train: image: pytorch/pytorch:2.0.0-cuda11.8-cudnn8-runtime shm_size: 16g这个问题在镜像里没法提前解决属于运行时配置所以每次开容器都得带上。为了避免遗漏建议把运行参数整理成固定的启动脚本或者 Compose 文件别每次手动敲。5. 常见问题与排查技巧实录5.1 典型报错速查表我在不同机器上反复装过十几次 NVIDIA Container Toolkit也帮不少朋友排查过问题。下面这些坑出现频率最高我按症状、原因、解决方案整理成了一张表方便你直接对照现象可能原因解决方式docker run 时提示 unknown runtime nvidiadaemon.json 里没有正确配置 nvidia runtime重新执行 nvidia-ctk runtime configure --runtimedocker 并重启 Dockerdocker: Error response from daemon: could not select device driver nvidiaDocker 不认识 --gpus 参数通常是版本低于 19.03升级 Docker 到最新版建议从官方仓库安装容器内 nvidia-smi 报 Failed to initialize NVML容器 runtime 未生效或者 toolkit 与驱动版本不匹配检查 docker run 是否加了 --gpus all运行 nvidia-container-cli info 检查 toolkit 状态容器内 CUDA 程序报 driver version is insufficient容器内 CUDA 版本太高宿主机驱动支持不了换用更低版本的 CUDA 镜像或者升级宿主机 NVIDIA 驱动容器内找不到 nvidia-smi镜像的基础系统没装 NVIDIA 工具使用 nvidia/cuda 官方基础镜像或者在 Dockerfile 里安装 nvidia-utilsDoker 重启后 daemon.json 报 JSON 解析错误手动编辑时格式写坏或多加逗号用 python3 -m json.tool 校验 JSON修正后重启容器启动成功但 GPU 显示 0 显存或不可计算宿主机 GPU 被其他进程占用或 cgroup 限制用 nvidia-smi 查实际占用确认 --gpus 参数是否正确这张表不是理论推导每一行都是我或者身边同事实际碰到过的。尤其是“unknown runtime nvidia”这个报错十个里至少有四个是修改 daemon.json 后忘了重启 Docker另外四个是修改时 JSON 多一个逗号导致 Docker 没加载配置。遇到 Doker 相关报错先看进程状态然后看日志比自己瞎猜效率高得多sudo systemctl status docker journalctl -u docker -n 305.2 容器能跑 nvidia-smi 但训练报错的处理思路有一种很隐蔽的情况容器里 nvidia-smi 正常显示 GPU 信息但一跑训练就报错。这个时候要冷静先判断报错的性质是 CUDA 依赖问题、还是显存不足问题、还是驱动接口问题。如果是 CUDA 相关报错比如undefined symbol或者libcudart.so.xx not found多半是镜像里的 CUDA 运行库和编译时的版本不一致。用ldconfig -p | grep cuda看看容器内部实际链接了哪些库判断版本是否对得上。我之前遇到过镜像里存在多个 CUDA 版本残留LD_LIBRARY_PATH 指向了错误版本的情况清理环境变量后问题就解决了。如果是显存不足报错比如CUDA error: out of memory先用nvidia-smi查一下是宿主机显存被其他进程占满还是容器自身的显存限制。容器默认不做显存限制除非你在 docker run 时额外指定了--device-cgroup-rule或者通过容器编排平台设置了显存配额。如果是驱动接口层面崩溃比如CUDA error: an illegal memory access was encountered这类问题要么是代码本身的越界访问要么是驱动和 CUDA 版本配合不佳。建议先升级驱动再把镜像换成和宿主机驱动匹配的 CUDA 版本比如驱动 550 可以尝试 CUDA 12.x 的镜像。5.3 宿主机重启后容器无法使用 GPU这个问题很经典服务器重启之后别人告诉你 “docker 起不来了容器都进不去”。其实 docker 起来了容器也起来了只是容器里访问不了 GPU。原因无非是重启之后 NVIDIA 驱动模块没有正确加载或者 nvidia-container-runtime 没有重新注入设备节点。先检查宿主机状态nvidia-smi如果 nvidia-smi 都失败那就不是 Docker 的问题是驱动没加载好。你可以查看内核模块状态lsmod | grep nvidia如果没有输出说明 nvidia 模块没加载执行sudo modprobe nvidia试试。如果报错很可能是安全启动Secure Boot在作祟——Ubuntu 22.04 默认开启 Secure Boot 后第三方内核模块签名验证不通过驱动就加载不了。最简单的解决办法是在 BIOS 里关闭 Secure Boot或者给驱动模块签名。我自己更推荐直接关掉个人开发机器上 Secure Boot 带来的麻烦远多于收益。宿主机驱动正常后再启动容器基本就没问题了。如果你用的是 containerd 而不是 Docker比如 K3s、K8s 环境还要确认 containerd 的 runtime 配置是否做过同样的 nvidia-ctk 配置这一类容器运行时不会自动继承 Docker 的 daemon.json。6. 实操经验与日常运维建议6.1 把 GPU 容器固化进日常开发流程NVIDIA Container Toolkit 装好之后我强烈建议你做两件小事。第一件把验证命令保存成一个脚本或者直接写进开发文档以后新机器初始化环境时能少踩一半的坑。我自己用的是这样一组命令# 验证驱动 nvidia-smi # 验证 toolkit nvidia-container-cli info # 验证 Docker runtime 配置 docker info | grep -i runtime # 端到端验证拉取轻量镜像并运行 docker run --rm --gpus all nvidia/cuda:11.8.0-base-ubuntu22.04 nvidia-smi其中nvidia-container-cli info这个命令特别有用它会输出 toolkit 的运行状态、驱动的加载路径、NVIDIA 设备节点信息比 docker 层更容易看出问题源头。第二件小事把常用启动参数封装成 Compose 文件。直接敲 docker run 命令一时爽但参数一多就乱了而且换个项目又要重新敲。我建议把 GPU 容量、shm-size、环境变量、数据卷挂载、端口映射都写进 docker-compose.yml该项目一启动就是完备的环境。6.2 定期更新 toolkit 与 Docker 之间的配合NVIDIA Container Toolkit 和 Docker 都在持续迭代版本之间的兼容性总体来说做得还行但偶尔也会有一些调整。建议每隔一段时间刷一次源、看一眼更新情况sudo apt update sudo apt upgrade nvidia-container-toolkit更新完后同样要重启 Docker。还有一个细节docker run 的 --gpus 参数在 Docker 19.03 引入后来在 23.0 系列中Docker CLI 对 device 参数的语法做了调整老写法的兼容性虽然保留了但新项目还是建议直接用规范写法。定期更新可以避免遇到“照着老教程写的命令跑不通”的尴尬。另外提醒一点不要在生产环境手痒就升级驱动除非你确定新驱动对当前 GPU 型号和 CUDA 容器都兼容。生产环境的通用做法是“驱动不动、工具链升级”也就是保持一个经过充分验证的驱动版本和 CUDA 版本组合只更新 Container Toolkit 和 Docker 的补丁版本。这个原则帮我省掉了很多“昨天还能跑今天突然废了”的麻烦。6.3 个人最推荐的国内镜像源配置思路这里额外分享一个不算冷门但很容易踩坑的点拉取 nvidia/cuda 这类大镜像时在某些网络环境下确实很慢甚至超时失败。我建议在 daemon.json 里把镜像源配置好而不是每次拉镜像都干等。daemon.json 里加上 registry-mirrors 字段{ registry-mirrors: [https://docker.m.daocloud.io], runtimes: { nvidia: { args: [], path: nvidia-container-runtime } } }选择哪个镜像地址可以根据你所在网络环境的实际可用性来调整。我自己用下来daocloud 的可用性相对稳一些速度和成功率都不错。配置完重启 Docker再拉镜像试试如果还慢另一个思路是在别的机器上把镜像 save 成 tar 包再 load 到目标机器上docker save nvidia/cuda:11.8.0-base-ubuntu22.04 | gzip cuda118.tar.gz # 在目标机器上 docker load cuda118.tar.gz这个方法尤其适合内网环境绕过公网拉取的所有问题。6.4 最后再分享一个实用小技巧在第六部分快结束时我分享一个很多人不知道的小技巧如果你在宿主机上装的是多张显卡而你想在容器里固定使用其中一张除了前面的 --gpus device0,2 参数之外还可以直接在容器里面设置 CUDA_VISIBLE_DEVICES 环境变量。这个变量的优先级其实比 Docker 的设备映射更直观docker run --rm --gpus all -it -e CUDA_VISIBLE_DEVICES1 nvidia/cuda:11.8.0-base-ubuntu22.04 bash进入容器后nvidia-smi 里只会看到一张卡也就是宿主机上编号为 1 的那张。这个变量的好处是即使你的代码里写了 cuda:0 或者 cuda:1也能被重映射到物理显卡上不需要改代码逻辑。多卡机器上用起来特别方便相当于在环境变量这一层把设备分配和代码解耦了。另外如果你想在容器启动时自动加载一些工具或者初始化脚本可以搭配 --entrypoint 参数定制容器入口比如自动执行 nvidia-smi 检查 GPU 状态再进入应用进程。这些细节组合起来能让你的 GPU 容器体验比默认配置顺畅不少。