Docker 容器 GPU 访问配置完整指南

在这里插入图片描述

背景

在使用 Docker 容器进行深度学习开发时,经常需要在容器内访问宿主机的 NVIDIA GPU。本文记录了一次完整的 Docker GPU 配置过程,包括问题诊断、解决方案和验证步骤。

环境信息

  • 操作系统: Ubuntu 22.04
  • GPU: NVIDIA Quadro RTX 3800
  • Docker: Docker Engine
  • NVIDIA 驱动: 535.274.02
  • CUDA 版本: 12.2

问题现象

1. 初始错误:无法选择 GPU 设备驱动

启动 Docker 容器时遇到以下错误:

docker: Error response from daemon: could not select device driver "" with capabilities: [[gpu]]

原因分析:系统缺少 NVIDIA Container Toolkit,Docker 无法识别和使用 GPU 设备。

2. 容器内 GPU 不可用

即使容器启动成功,在运行深度学习框架时出现 CUDA 错误:

[E:onnxruntime:Default, cuda_call.cc:118 CudaCall] CUDA failure 100: 
no CUDA-capable device is detected

在容器内运行 nvidia-smi 返回:

Failed to initialize NVML: Unknown Error

原因分析:Docker daemon 配置不完整,容器无法访问 GPU 的 NVML 库。

解决方案

步骤 1:检查宿主机 GPU 状态

首先确认宿主机能够正常识别 GPU:

nvidia-smi

应该能看到 GPU 信息和驱动版本。

步骤 2:安装 NVIDIA Container Toolkit

如果尚未安装 NVIDIA Container Toolkit,执行以下命令:

# 添加 NVIDIA Container Toolkit 仓库
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
sudo apt-get install -y nvidia-container-toolkit

步骤 3:配置 Docker Runtime

安装完成后,需要配置 Docker 使用 NVIDIA runtime:

# 配置 Docker 使用 NVIDIA runtime 并设置为默认
sudo nvidia-ctk runtime configure --runtime=docker --set-as-default

# 重启 Docker 服务使配置生效
sudo systemctl restart docker

步骤 4:验证配置

检查 Docker daemon 配置文件:

cat /etc/docker/daemon.json

应该包含以下内容:

{
    "default-runtime": "nvidia",
    "runtimes": {
        "nvidia": {
            "args": [],
            "path": "nvidia-container-runtime"
        }
    }
}

关键配置说明

  • "default-runtime": "nvidia" - 将 NVIDIA runtime 设置为默认(重要!)
  • "runtimes" - 定义可用的 runtime

步骤 5:启动支持 GPU 的容器

有两种方式启动支持 GPU 的 Docker 容器:

方式 1:使用 --gpus 参数(推荐)
docker run -it --rm \
  --gpus all \
  --name my_gpu_container \
  my_image:tag \
  bash
方式 2:使用 --runtime 参数
docker run -it --rm \
  --runtime=nvidia \
  --name my_gpu_container \
  my_image:tag \
  bash

完整启动脚本示例

#!/bin/bash
dataset_path=$1
run_type=$2
version=v1.0.0
container_name=$(whoami)_GPU_Container

if [ -z "$dataset_path" ]; then
  echo "Please specify the dataset path"
  exit 1
fi

dataset_path=$(readlink -f "$dataset_path")
workspace_path=$(readlink -f "$(dirname "$0")")

echo "Starting Docker container in GPU mode..."
docker run -it --rm \
  --network host \
  --hostname "GPU-Container-${version}" \
  --name $container_name \
  --gpus all \
  --shm-size="15g" \
  -v "$workspace_path":/workspace \
  -v "$dataset_path":/data \
  my_image:$version \
  bash

步骤 6:验证 GPU 在容器内可用

进入容器后,运行以下命令验证:

验证 1:nvidia-smi
nvidia-smi

应该显示完整的 GPU 信息,包括驱动版本、CUDA 版本、GPU 使用情况等。

验证 2:CUDA 设备数量
python3 -c "import torch; print(f'CUDA available: {torch.cuda.is_available()}'); \
            print(f'Device count: {torch.cuda.device_count()}')"
验证 3:ONNX Runtime GPU 支持
python3 -c "import onnxruntime as ort; \
            print('Available providers:', ort.get_available_providers())"

应该看到包含 CUDAExecutionProviderTensorrtExecutionProvider

常见问题排查

问题 1:容器启动失败 - “no command specified”

错误信息

docker: Error response from daemon: no command specified

解决方案:在 docker run 命令末尾添加启动命令(如 bash):

docker run -it --rm --gpus all my_image:tag bash

问题 2:权限被拒绝

错误信息

docker: permission denied while trying to connect to the Docker daemon socket

解决方案

# 将当前用户添加到 docker 组
sudo usermod -aG docker $USER

# 重新登录或运行
newgrp docker

问题 3:旧容器无法访问 GPU

如果之前启动的容器在配置更新后仍无法访问 GPU:

# 停止并删除旧容器
docker stop <container_name>
docker rm <container_name>

# 重新启动新容器
docker run --gpus all ...

最佳实践

1. 资源限制

为容器设置适当的资源限制:

docker run -it --rm \
  --gpus all \
  --shm-size="16g" \              # 共享内存大小
  --memory="32g" \                # 内存限制
  --cpus="8" \                    # CPU 核心数
  my_image:tag

2. 指定特定 GPU

如果系统有多个 GPU,可以指定使用哪些:

# 使用所有 GPU
--gpus all

# 使用特定 GPU(按 ID)
--gpus '"device=0,1"'

# 使用特定数量的 GPU
--gpus 2

3. 环境变量

设置 CUDA 相关环境变量:

docker run -it --rm \
  --gpus all \
  -e CUDA_VISIBLE_DEVICES=0 \
  -e NVIDIA_VISIBLE_DEVICES=all \
  my_image:tag

4. 持久化配置

将 Docker 配置纳入版本控制:

# 备份配置
sudo cp /etc/docker/daemon.json /etc/docker/daemon.json.backup

# 使用配置文件管理工具(如 Ansible)部署配置

验证清单

在生产环境部署前,建议完成以下验证:

  • 宿主机 nvidia-smi 正常工作
  • NVIDIA Container Toolkit 已安装
  • /etc/docker/daemon.json 配置正确
  • Docker daemon 已重启
  • 容器内 nvidia-smi 正常工作
  • 深度学习框架能检测到 GPU
  • 简单的 GPU 运算测试通过

参考资源

总结

正确配置 Docker GPU 访问需要:

  1. 安装 NVIDIA Container Toolkit
  2. 配置 Docker daemon 使用 NVIDIA runtime 作为默认
  3. 重启 Docker 服务
  4. 使用 --gpus all 参数启动容器

关键是确保 daemon.json 中设置了 "default-runtime": "nvidia",这样容器才能正确访问 GPU 的 NVML 库。配置完成后,容器内的深度学习应用就能正常使用 GPU 加速了。


最后更新:2026年1月

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐