Docker 容器内使用宿主机的 GPU

FreeGuideOnline 最新 2026-07-06

为什么需要在 Docker 容器里使用 GPU?

在深度学习、科学计算等场景中,GPU 的并行计算能力至关重要。Docker 提供了轻量级隔离环境,将 GPU 暴露给容器可以让你:

  • 隔离实验环境,避免宿主机驱动冲突
  • 快速复现模型训练或推理结果
  • 在 CI/CD 流程中无缝执行 GPU 任务

本教程将带你一步步实现从宿主机调用 GPU 到 Docker 容器。

前提条件

在开始之前,请确保你的宿主机满足以下要求:

  • 物理机或虚拟机已正确安装 NVIDIA 显卡
  • 宿主机已安装 NVIDIA GPU 驱动程序(版本 ≥ 450.80.02)
  • 已安装 Docker(版本 ≥ 19.03)
  • 推荐使用 Docker Compose (可选,方便管理多容器应用)

验证宿主机 GPU 状态

在宿主机终端执行以下命令,确认驱动和 GPU 可用:

nvidia-smi

如果输出显示 GPU 信息(型号、驱动版本、CUDA 版本等),说明驱动安装正确。

安装 NVIDIA Container Toolkit

原生的 Docker 不支持将 GPU 直接传递给容器,需要借助 NVIDIA Container Toolkit。该工具扩展了 Docker 的运行时,使容器可以调用宿主机 GPU。

步骤一:设置软件包仓库

Ubuntu/Debian 系统执行:

distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \
  sudo tee /etc/apt/sources.list.d/nvidia-docker.list

CentOS/RHEL 系统执行:

distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.repo | \
  sudo tee /etc/yum.repos.d/nvidia-docker.repo

步骤二:安装 nvidia-docker2 及运行时

更新软件包索引并安装:

sudo apt-get update
sudo apt-get install -y nvidia-docker2

或使用 yum:

sudo yum install -y nvidia-docker2

步骤三:重启 Docker 服务

sudo systemctl restart docker

步骤四:验证安装

运行以下测试容器,若能正确输出 nvidia-smi 结果则表示安装成功:

docker run --rm --gpus all nvidia/cuda:11.0-base nvidia-smi

运行带有 GPU 访问权限的容器

NVIDIA Container Toolkit 安装完成后,Docker 命令中通过 --gpus 参数指定 GPU 使用方式。

基础用法:将所有 GPU 分配给容器

docker run --rm --gpus all nvidia/cuda:12.3.1-base-ubuntu22.04 nvidia-smi
  • --gpus all:将宿主机所有可用 GPU 暴露给容器。
  • nvidia/cuda:12.3.1-base-ubuntu22.04:包含 CUDA 运行时的基础镜像,你也可以使用其他支持 CUDA 的镜像。
  • nvidia-smi:容器启动后执行的命令,用来验证 GPU 是否可见。

指定特定 GPU

如果你有多张显卡,只希望容器使用其中一部分,可以用设备索引或 UUID 指定:

# 使用索引(0 代表第一张 GPU)
docker run --rm --gpus '"device=0"' nvidia/cuda:12.3.1-base-ubuntu22.04 nvidia-smi

# 使用 GPU 的 UUID(通过 nvidia-smi 查询)
docker run --rm --gpus '"device=GPU-<你的UUID>"' nvidia/cuda:12.3.1-base-ubuntu22.04 nvidia-smi

# 指定多张 GPU,用逗号分隔
docker run --rm --gpus '"device=0,2"' nvidia/cuda:12.3.1-base-ubuntu22.04 nvidia-smi

使用环境变量控制可见 GPU

也可以通过 NVIDIA_VISIBLE_DEVICES 环境变量控制 GPU 访问:

docker run --rm --env NVIDIA_VISIBLE_DEVICES=0,1 nvidia/cuda:12.3.1-base-ubuntu22.04 nvidia-smi

在容器内运行深度学习框架示例

以 TensorFlow 和 PyTorch 为例,展示如何在 GPU 加速容器中执行代码。

TensorFlow 示例

创建并运行一个临时 GPU 容器,并运行 Python 检测 GPU:

docker run --rm --gpus all -it tensorflow/tensorflow:latest-gpu bash

进入容器后执行:

python -c "import tensorflow as tf; print(tf.config.list_physical_devices('GPU'))"

如果成功输出 [PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')],说明 TensorFlow 已识别到 GPU。

PyTorch 示例

官方 PyTorch 镜像已内置 CUDA,直接运行:

docker run --rm --gpus all -it pytorch/pytorch:latest bash

在容器中执行:

python -c "import torch; print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0))"

返回 True 和 GPU 型号即表示成功。

Docker Compose 中启用 GPU

如果你使用 Compose 管理服务,可在 compose.yml 中通过 deploy 资源来声明 GPU。

Compose file 版本要求

确保使用 Compose file format 2.3 或更高版本,且 Docker Compose 版本 ≥ 1.28.0 才原生支持 --gpus

version: '3.8'

services:
  gpu-test:
    image: nvidia/cuda:12.3.1-base-ubuntu22.04
    command: nvidia-smi
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1              # 使用 1 张 GPU
              capabilities: [gpu]   # 可添加 compute, utility 等

启动服务:

docker compose up

如果你需要指定 GPU 设备索引,可以添加 device_ids

deploy:
  resources:
    reservations:
      devices:
        - driver: nvidia
          device_ids: ['0', '1']
          capabilities: [gpu]

检查容器内的 CUDA 版本与驱动兼容性

容器的 CUDA 工具包版本必须与宿主机驱动的最低支持版本兼容。你可以在容器内运行 nvidia-smi 查看驱动版本和最大支持 CUDA 版本。若容器内的 CUDA 版本过高,可能导致运行时错误。

最简单的方案是:选择与宿主机驱动匹配的 CUDA 基础镜像(如 nvidia/cuda:11.8-base)。宿主机驱动支持情况可通过 nvidia-smi 右上角的 “CUDA Version” 查看,它代表该驱动最高支持的 CUDA 版本。

排除故障

问题 1:docker run 提示 Unknown runtime specified nvidia

原因:Docker 守护进程没有加载 nvidia runtime。

解决:编辑 /etc/docker/daemon.json,确保 runtime 配置正确:

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

之后重启 Docker:

sudo systemctl restart docker

问题 2:在容器内 nvidia-smi 输出 Failed to initialize NVML: Unknown Error

原因:宿主机驱动与 Container Toolkit 版本不兼容,或容器使用的 CUDA 镜像版本过高。

解决

  • 更新宿主机驱动至最新稳定版。
  • 使用与驱动匹配的较低 CUDA 版本镜像尝试。

问题 3:容器使用 --gpus all 后,训练仍只用到 CPU

原因:代码中可能没有指定 tf.device('/GPU:0')torch.device('cuda'),默认使用 CPU。

解决:在代码中明确将张量或模型移动到 GPU 设备。

进阶:多容器共享 GPU 与 GPU 虚拟化

Kubernetes 或 Docker Swarm 等编排平台支持更细粒度的 GPU 共享。NVIDIA 提供了 GPU Operator 和 MIG(多实例 GPU)技术(仅部分专业卡支持),可以将一张 GPU 划分为多个独立实例。这超出了本教程范围,但你可以在掌握基础用法后进一步探索。

总结

通过 NVIDIA Container Toolkit,你可以轻松地将宿主机 GPU 共享给 Docker 容器,从而在隔离环境中运行 CUDA 应用。关键步骤总结:

  1. 宿主机安装 NVIDIA 驱动
  2. 安装 NVIDIA Container Toolkit
  3. 使用 docker run --gpus 或 Compose file 指定 GPU
  4. 验证容器内 GPU 可见性

现在,你可以将模型训练、推理等任务封装进可移植的 GPU 容器,让开发与部署更加一致、高效。