Dev/DevOps, Infra

Windows 11 WSL2 및 Ubuntu 22.04에서 GPU 활용 Docker 실행 환경 세팅

HJChung 2023. 10. 26. 22:54

찾아본 대부분의 자료와 공식 문서가 영어로 되어있었기도 했고, 스위스 엔지니어에게 해당 방법을 알려줘야 했기 때문에 정리해 본 것이라 중간 중간 영어로 적힌 부분이 있다.

Environment

Ubuntu 22-04 혹은 Window WSL(Windows Subsystems for Linux)

wsl 설치 방법

$ wsl --list --online
$ wsl --install -d Ubuntu-22.04

Prerequisite

Check Hardware

아래의 모든 작업을 진행하기 전에 정말 기본적이지만 GPU 하드웨어가 있는지, 또한 사용가능한 형태로 설치되어있는지 확인해야 한다. 시스템에 어떤 그래픽 카드가 설치되어있는지 확인하려면 다음과 같은 명령어를 사용한다.

 

$ sudo lshw -C display

Installation

1. NVIDIA Driver

개념

NVIDIA driver는 NVIDIA GPU 하드웨어 리소스를 제어하고 관리하기 위한 프로그램이다. GPU와 OS(여기선 리눅스 서버)간의 통신을 중개하고, 작업을 실행하는데 필요한 라이브러리 및 도구를 제공한다. (참고)

따라서 리눅스 서버에서 NVIDIA GPU 하드웨어 리소스에 접근하기 위해서는 먼저 Driver가 설치 되어야 한다.

설치

nvidia driver installation이라고 검색하면 가장 먼저 나오는 이 자료 와 조금 다른 방법이다.

1. Find NVIDIA Drivers

Before  a driver, you need to check if it is available in the package list on the ubuntu image. You can find all packages containing the text "nvidia-driver" by running the following commands:

$ apt search nvidia-driver
# Or
$ apt-cache search nvidia-driver

These commands will help you locate any packages related to NVIDIA drivers that are available for installation.

2. Update the package list and performing security upgrades (optional):

$ sudo apt update

$ sudo apt upgrade

3. Install NVIDIA Driver

Installing the driver using the found driver name. You can install it using the apt-get command:

$ sudo apt install -y nvidia-driver-450-server[VERSION]

Replace [VERSION] with the specific version number of the driver you want to install.

4. Reboot the server in host machine

$ wsl --shutdown ## this should happen on windows powershell
# OR
$ sudo shutdown -r now
# OR
$ sudo reboot

5. Done

After the reboot is complete, you should verify if the driver has been installed successfully. You can check the installation using the nvidia-smi command:

$ nvidia-smi

이런식으로 결과가 나오면 정상 설치 된 것이다.

2. Docker

아에 아무 것도 없는 clear한 서버에서 모든 것을 실행한다는 가정으로, Docker와 docker-compose 설치까지 진행해보았다.

특히, WSL 사용시 컨테이너 내에서 GPU 리소스를 사용하기 위해서는 특히나 Docker Desktop(GUI)를 사용해서는 안 된다. 자세한 내용은 모르겠지만 아직 지원을 하지 않는 것 같다. (참고 링크)

1. Uninstall Docker Engine

Uninstall the Docker Engine, CLI, containerd, and Docker Compose packages:

$ sudo apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
# or
$ sudo apt-get remove docker docker-engine docker.io

Images, containers, volumes, or custom configuration files on your host aren't automatically removed. To delete all images, containers, and volumes:

$ sudo rm -rf /var/lib/docker
$ sudo rm -rf /var/lib/containerd
$ sudo apt-get update

You have to delete any edited configuration files manually.

 

2. Install Docker Engine

Docker-CE on Ubuntu can be setup using Docker’s official convenience script

$ curl https://get.docker.com | sh
$ sudo systemctl --now enable docker

아래 내용은 wsl Ubuntu-22.04에서 이 포스트 내용을 실행하고자 할 때 필요한 내용이다. If you met  ‘Failed to connect to bus: Host is down Error’, please update iptables.

$ sudo update-alternatives --config iptables

and choose number1 option.

3. Post-install steps for Docker Engine

After install Docker, Do Linux post-installation steps for Docker Engine

Reference linke is this post-install documentation.

Create the docker group.

$ sudo groupadd docker

Add your user to the docker group.

$ sudo usermod -aG docker $USER

Log out and log back in so that your group membership is re-evaluated.

$ newgrp docker

Verify that you can run docker commands without sudo.

$ docker run hello-world

Configure Docker to start on boot with systemd

$ sudo systemctl enable docker.service

$ sudo systemctl enable containerd.service

4. Check Docker Daemon status

check your docker daemon status.

$ sudo service docker status

If Docker is not running, please start it.

$ sudo service docker start

And check status again.

$ sudo service docker status

Docker is running. Try to run simple 'hello-world' image to check docker daemon.

$ docker run --rm -it hello-world

3. Docker Compose

$ sudo curl -L https://github.com/docker/compose/releases/download/{proper docker compose version}/docker-compose-$(uname -s)-$(uname -m) \ -o /usr/local/bin/docker-compose

$ sudo chmod +x /usr/local/bin/docker-compose

$ docker-compose --version

4. NVIDIA Container Toolkit for Docker

개념

NVIDIA 컨테이너 스택은 NVIDIA GPU를 사용하는 Docker 컨테이너를 관리하기 위한 여러 구성 요소로 구성된다. 필수 구성 요소는 NVIDIA 드라이버, NVIDIA Container Toolkit, NVIDIA Container Runtime, NVIDIA Container Runtime Hook, 그리고 NVIDIA Container Library 및 CLI이다.

The main packages of the NVIDIA Container Toolkit are:

  • nvidia-container-toolkit
  • nvidia-cotnainer-toolkit-base
  • libnvidia-container-tools
  • libnvidia-container1

이러한 구성 요소를 올바르게 설치하고 설정하면 GPU를 사용하는 컨테이너를 실행할 수 있다.

  1. NVIDIA Container Toolkit: NVIDIA 컨테이너 스택의 핵심 패키지 중 하나로, 다양한 구성 요소와 함께 패키징됩니다. 이 패키지는 NVIDIA GPU를 사용하는 컨테이너를 설정하고 관리하는 데 사용됩니다.
  2. NVIDIA Container Runtime (nvidia-container-runtime): NVIDIA 컨테이너 스택의 중요한 구성 요소 중 하나로, 이 구성 요소는 OCI(Open Container Initiative)-호환 런타임으로 Docker나 Containerd와 통합됩니다. 이 런타임은 컨테이너 생성 및 실행 중 NVIDIA GPU 지원을 적용합니다.
  3. NVIDIA Container Runtime Hook (nvidia-container-toolkit / nvidia-container-runtime-hook): NVIDIA 컨테이너 스택에서 컨테이너에 GPU를 주입하는 작업을 담당합니다. 이 훅은 컨테이너가 생성되고 시작되기 전에 실행되며, 컨테이너의 설정 정보를 기반으로 필요한 GPU 디바이스를 식별합니다.
  4. NVIDIA Container Library and CLI (libnvidia-container1, nvidia-container-cli): 이 구성 요소들은 라이브러리와 간단한 CLI 도구로, GNU/Linux 컨테이너를 NVIDIA GPU와 자동으로 구성하는 데 사용됩니다. 라이브러리는 컨테이너 런타임과 독립적으로 동작하며, 컨테이너 런타임에 NVIDIA GPU 지원을 주입하기 위해 호출되는 API를 제공합니다.
    1. 이 NVIDIA Container Library and CLI 패키지는 libnvidia-container-tools and libnvidia-container1 packages들로 구성되어 이를 패키징 한 것이다.

How these components are used depends on the container runtime being used.

더 자세한 내용은 https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/1.14.3/index.html 여기를 확인 하면 된다.

추가로 

- https://github.com/NVIDIA/nvidia-docker/issues/1268

- nvidia-docker 와 nvidia container runtime의 차이

두 글도 참고하기 좋다. 

 

설치

1. Setup the package repository and the GPG key

$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \\
      && 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/$distribution/libnvidia-container.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

2. Install the nvidia-container-toolkit package (and dependencies) after updating the package listing:

$ sudo apt-get update

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

3. Add the NVIDIA Runtime in Docker

The NVIDIA Container Toolkit provides different options for enumerating GPUs and the capabilities that are supported for CUDA containers. This user guide demonstrates the following features of the NVIDIA Container Toolkit:

  • Registering the NVIDIA runtime as a custom runtime to Docker
  • Using environment variables to enable the following:
    • Enumerating GPUs and controlling which GPUs are visible to the container
    • Controlling which features of the driver are visible to the container using capabilities
    • Controlling the behavior of the runtime using constraints

방법 1) Daemon configuration file

The nvidia runtime can also be registered with Docker using the daemon.json configuration file. The NVIDIA Container Toolkit provides a utility to apply this configuration:

$ sudo nvidia-ctk runtime configure --runtime=docker

You can optionally set the nvidia runtime as the default runtime by specifying the --set-as-default flag:

$ sudo nvidia-ctk runtime configure --runtime=docker --set-as-default

And a --dry-run flag is also available to preview the changes before applying them.

To apply the new configuration, restart the docker daemon:

$ sudo systemctl restart docker
# or
$ sudo service docker restart
# and check docker status
$ sudo service docker status

 

방법 2) Command Line

Use dockerd to add the nvidia runtime:

$ sudo dockerd --add-runtime=nvidia=/usr/bin/nvidia-container-runtime

 

4. 끝이다.  Windows 11 WSL2 및 Ubuntu 22.04에서 GPU 활용 Docker 실행 환경 세팅을 마쳤다. 

잘 실행이 되는지 --runtime=nvidia 옵션을 준 nvidia/cuda:11.8.0-cudnn8-runtime-ubuntu22.04 Docker image를 사용하여 그 컨테이너를 실행한 환경에서 nvidia-smi 명령어를 실행해 보자. 

$ docker run --rm --runtime=nvidia nvidia/cuda:11.8.0-cudnn8-runtime-ubuntu22.04 nvidia-smi

아래와 같은 결과가 나온다면 정상적으로 마친 것이다.