安装 `nvidia-docker2` 并验证 `nvidia-smi` 在容器内输出
解读
在国内面试场景里,这道题表面考“装个包、跑条命令”,实则同时检验候选人对 GPU 容器化全链路的掌握深度与生产落地经验。
面试官期望你在 5~10 分钟内把宿主机驱动 → Docker 版本 → nvidia-docker2 仓库 → 运行时配置 → 镜像选择 → 隔离与可观测性这一整条闭环讲清楚,并给出可复现、可运维、可排障的最小步骤。
任何一句“先装驱动”却不提内核版本与驱动签名、任何一步“跑个 nvidia/cuda 镜像”却不提国内镜像源加速与多架构校验,都会被追问到哑口无言。
知识点
- 宿主机前置条件:CentOS 7/8、Ubuntu 20.04/22.04 内核 ≥4.15,官方 NVIDIA 驱动 ≥ 450.80.02,且禁用 nouveau。
- Docker 版本锁口:20.10.7 以上且低于 24.x(nvidia-docker2 官方兼容性矩阵),yum/apt 仓库优先用国内清华/中科大镜像。
- nvidia-docker2 本质:把 nvidia-container-runtime 注册为 Docker 的额外 runtime,不替换 dockerd,通过 OCI prestart hook 把宿主机 GPU 字符设备与库文件挂载进容器。
- 配置验证:
/etc/docker/daemon.json中必须出现 "runtimes": { "nvidia": { "path": "nvidia-container-runtime", "runtimeArgs": [] } },reload 后docker info | grep nvidia需回显。 - 镜像策略:官方 nvidia/cuda:11.8.0-base-ubuntu22.04 镜像国内拉不动时,先用
docker pull registry.cn-hangzhou.aliyuncs.com/nvidia/cuda:11.8.0-base-ubuntu22.04,再 retag 保持名称一致,避免 CI 脚本耦合。 - 安全加固:容器内默认 root,面试必须补充
-u 1000:1000 --group-add video以及 只读挂载 /sys 以外的敏感路径;Secrets 通过 --env-file 或 docker secret 管理,绝不硬编码 NVIDIA_VISIBLE_DEVICES。 - 排障三板斧:
nvidia-container-cli info查看驱动与设备是否匹配;docker run --rm --gpus all ubuntu:22.04 nvidia-smi报 “could not select device driver” 时,优先检查 /dev/nvidiactl 权限与 SELinux 标签;- dmesg 出现 “NVRM: GPU 0000:3b:00.0 Failed to allocate video memory” 代表宿主机驱动与容器内 CUDA 版本不匹配,需重新打标签或升级驱动。
答案
以下步骤在 CentOS 7.9 宿主机 + 官方驱动 525.60.13 + Docker 20.10.24 环境验证通过,全程使用国内源,可直接写进面试白板:
-
宿主机准备
sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://mirrors.tuna.tsinghua.edu.cn/nvidia-docker/centos7/x86_64/nvidia-docker.repo sudo yum install -y nvidia-driver-latest-dkms sudo reboot # 重启后 nvidia-smi 正常输出 -
安装 Docker 并锁定版本
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo sudo yum install -y docker-ce-20.10.24 docker-ce-cli-20.10.24 containerd.io sudo systemctl enable --now docker -
安装 nvidia-docker2
sudo yum install -y nvidia-docker2 sudo tee /etc/docker/daemon.json <<EOF { "runtimes": { "nvidia": { "path": "nvidia-container-runtime", "runtimeArgs": [] } }, "registry-mirrors": ["https://registry.docker-cn.com"] } EOF sudo systemctl restart docker -
验证运行时
docker info | grep nvidia # 应出现 runtimes: nvidia -
拉取国内加速镜像并验证 nvidia-smi
docker pull registry.cn-hangzhou.aliyuncs.com/nvidia/cuda:11.8.0-base-ubuntu22.04 docker tag registry.cn-hangzhou.aliyuncs.com/nvidia/cuda:11.8.0-base-ubuntu22.04 nvidia/cuda:11.8.0-base-ubuntu22.04 docker run --rm --gpus all nvidia/cuda:11.8.0-base-ubuntu22.04 nvidia-smi终端回显 GPU 型号、驱动版本、CUDA 版本即判定通过。
-
加分项:非 root 用户执行
docker run --rm --gpus all -u 1000:1000 --group-add video nvidia/cuda:11.8.0-base-ubuntu22.04 nvidia-smi无权限报错则证明隔离正确。
拓展思考
- 多卡调度:如果宿主机有 8 张 A100,如何通过
NVIDIA_VISIBLE_DEVICES=4,5,6,7与CUDA_VISIBLE_DEVICES的联动,让训练容器只看到后 4 卡,同时保证 metrics-exporter 采集的 GPU 序号与宿主一致? - Kubernetes 场景:nvidia-device-plugin 已经不再依赖 nvidia-docker2,而是直接调用 nvidia-container-toolkit,如何在离线机房通过
helm install gpu-operator一键完成驱动 + container-toolkit + device-plugin 的协同升级,并保证节点 NotReady 时间 <30s? - 国产化替代:在鲲鹏 + 昇腾 910B 环境,没有 nvidia-docker2,如何使用 ascend-docker-runtime 把 Ascend 驱动注入容器,并复用同一条
docker run --device /dev/davinci0语义? - 安全合规:金融客户要求容器内不能出现宿主机驱动版本信息,如何通过自定义 nvidia-container-runtime hook 把
/proc/driver/nvidia/version屏蔽,同时又不影响 CUDA 调用?