Ubuntu 服务器安装 Nvidia Container Toolkit 使 Docker 支持 Cuda

为了能够在 Docker 中使用 GPU 进行加速,Nvidia 开发了 nvidia-docker 对 Container 进行封装,使得 Docker 容器可以调用 GPU 进行加速。现在 nvidia-docker 已被归档,官方推荐使用 nvidia-container-toolkit

本文将介绍如何在 Linux 中安装 nvidia-container-toolkit。

注:本文所使用的显卡为 RTX4080

关系理解

在 Ubuntu 的 Docker 中使用 GPU 时,需要在 host 主机中安装两个环境:

  1. Nvidia 驱动
  2. NVIDIA Container Toolkit

其关系如下图所示:

ngidia-container-toolkit

Nvidia 驱动决定了可使用的 cuda 最大版本号,如下图右上角所示。

如图所示:

image-20231227172857700

安装 Nvidia 驱动

查看机器环境

  1. 查看发行版信息:

    lsb_release -a

  2. 查看内核版本:

    uname -r

  3. 查看默认 GCC 版本:

    gcc --version

  4. 查看 GLIBC 版本:

    ldd --version

支持的 linux 版本如下:

Native Linux Distribution Support in CUDA 12.6 Update 3

若版本不满足要求,可以按下列方式进行升级,下文将以 Ubuntu 22.04.3 为例。

注意:升级内核有风险,请谨慎操作!

升级内核

1
2
3
4
5
6
7
8
sudo apt update
apt-cache search linux-image
# 安装指定版本内核
sudo apt install linux-image-5.4.0-42-generic linux-headers-5.4.0-42-generic
# 更新 GRUB 配置
sudo update-grub
# 重启
sudo reboot

升级 gcc

1
2
3
4
5
6
7
8
9
10
11
12
# 安装 gcc12
sudo apt-get install gcc-12 g++-12
# 设置为默认版本
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 110 --slave /usr/bin/g++ g++ /usr/bin/g++-12
# 修改 gcc 的优先级
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 100
# 减小原来 gcc 的优先级
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 50
# 选择默认的 gcc
sudo update-alternatives --config gcc
# 查看版本
gcc --version

查看驱动版本

1
cat /proc/driver/nvidia/version

若提示没有该文件,则说明没有驱动。否则会显示驱动版本:

1
2
NVRM version: NVIDIA UNIX x86_64 Kernel Module  535.154.05  Thu Dec 28 15:37:48 UTC 2023
GCC version: gcc version 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04)

卸载原驱动

1
2
export DRIVER_BRANCH=535.216.01
sudo apt --purge remove "*nvidia*${DRIVER_BRANCH}*"

安装驱动

RTX 4080 不支持 server 类型的驱动

查看可安装驱动:

1
ubuntu-drivers list

输入上述命令后,可能会报错:ERROR:root:aplay command not found,安装一下 sudo apt install alsa-utils 即可,这是一个声音驱动工具包。

版本选择

使用 ubuntu-drivers list 命令后,输出结果如下:

1
2
3
4
5
6
7
8
9
➜ /home/xby ubuntu-drivers list --gpgpu
nvidia-driver-535
nvidia-driver-550
nvidia-driver-535-server
nvidia-driver-545-open
nvidia-driver-535-server-open
nvidia-driver-550-open
nvidia-driver-535-open
nvidia-driver-545
  • server

    这是一个专门为服务器设计的驱动程序,提供了针对服务器硬件和应用程序的优化

  • open

    开源版本的 NVIDIA 驱动

  • 通用的驱动

各个版本历史渊源详见 如何优雅地在ubuntu中安装nvidia驱动

开始安装

  1. 使用推荐方式安装默认版本

    sudo ubuntu-drivers install --gpgpu

    这种方式安装的驱动不是最新版本

  2. 安装指定版本

    1
    2
    3
    4
    5
    # 下列版本二选一
    # 服务器版本
    sudo ubuntu-drivers install --gpgpu nvidia:550-server
    # 通用版本
    sudo ubuntu-drivers install --gpgpu nvidia:550
  3. 查看驱动版本

    1
    2
    3
    4
    5
    6
    7
    8
    # 查看驱动版本
    cat /proc/driver/nvidia/version

    # 若是 --gpgpu 版本,还需要根据驱动版本安装工具包,下面的 550 为主版本号
    sudo apt install nvidia-utils-550-server

    # 通过版本安装的 nvidia-smi 工具,没有后缀 -server
    sudo apt install nvidia-utils-550

    输入 nvidia-smi 来查看显卡状态,正常显示如下:

    image-20231227172857700

安装 NVIDIA Container Toolkit

  1. 宿主机更新 NVIDIA driver

    1
    2
    3
    4
    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

    请注意,该步骤会从 nvidia.github.io 上下载文件,可能需要配置代理

  2. 更新包列表

    1
    sudo apt-get update

  3. 安装 NVIDIA Container Toolkit

    1
    sudo apt-get install -y nvidia-container-toolkit

配置 Docker

  1. 通过 navidia-ctk 配置 docker 容器

    1
    sudo nvidia-ctk runtime configure --runtime=docker
  2. 重启容器

    1
    sudo systemctl restart docker

配置 Containerd

containerd 是一个开源的容器运行时,它是 Docker 的一个核心组件,负责管理容器的生命周期,包括镜像管理、容器执行、进程监控、网络管理等。

1
2
sudo nvidia-ctk runtime configure --runtime=containerd
sudo systemctl restart containerd

测试

使用下列代码测试是否可以在 docker 容器中使用 gpu

1
sudo docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi

--gpus all:表示在 docker 中使用 GPU,若容器需要使用 GPU,都需要添加这个参数

当输出如下内容时,说明安装成功了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 535.129.03 Driver Version: 535.129.03 CUDA Version: 12.2 |
|-----------------------------------------+----------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+======================+======================|
| 0 NVIDIA GeForce RTX 4080 Off | 00000000:65:00.0 Off | N/A |
| 0% 33C P8 7W / 320W | 2MiB / 16376MiB | 0% Default |
| | | N/A |
+-----------------------------------------+----------------------+----------------------+

+---------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=======================================================================================|
| No running processes found |
+---------------------------------------------------------------------------------------+

docker compose 配置 GPU

在配置中加入如下设置,允许 docker 使用 gpu

1
2
3
4
5
6
7
8
9
10
services:
ollma:
...
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1 # 使用一块 GPU
capabilities: [gpu]

测试 Docker 容器 GPU 状态

进入到容器后,执行 nvidia-smi,若成功显示 GPU 信息,则说明 docker 容器成功访问到了 GPU。

bug 排查

重启后失效

重启后,执行 nvidia-smi,发现 driver 没有启动:

1
2
3
4
5
6
7
8
9
10
11
➜  /home/xby nvidia-smi
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.
➜ /home/xby sudo ubuntu-drivers install --gpgpu nvidia:550
nvidia-headless-no-dkms-550
None
All the available drivers are already installed.
➜ /home/xby gcc --version
gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

从上面可以看出,问题出在 nvidia-headless-no-dkms-550,通过排查,怀疑是 gcc 版本问题,参考

参考

本文参考以下文章,在此致以诚挚谢意!

NVIDIA drivers installation | Ubuntu

NVIDIA/nvidia-docker: Build and run Docker containers leveraging NVIDIA GPUs (github.com)

NVIDIA/nvidia-container-toolkit: Build and run containers leveraging NVIDIA GPUs (github.com)

Installing the NVIDIA Container Toolkit — NVIDIA Container Toolkit 1.14.3 documentation

Running a Sample Workload — NVIDIA Container Toolkit 1.14.3 documentation