Kontenery docker’a ze natywną obsługą GPU Nvidia na CentOS 8, CentOS 7

Przed wersją Docker Comunity Edition 19.3 wykorzystanie akceleratorów GPU z kontenera doker’a możliwe było za pomocą nvidia-docker w połączaniu z Docker CE. Obecnie od wersji 19.3 Docker CE natywnie wspiera obsługę akceleratorów GPU, jednak dalej konieczne jest zainstalowanie dodatku nvidia-container-toolkit. Opcja --gpus pozwala określić do których akceleratorów GPU z pośród dostępnych dla systemu operacyjnego ma mieć dostęp uruchamiany kontener.

Dystrybucje „RedHat’a” – RHEL 7 oraz CentOS 7 zawierają w sobie RedHat’owy fork docker’a w wersji 1.13.1 (w momencie pisania tego artykułu). Należy zaznaczyć, że numeracja wersji RedHat’a i Docker inc. jest różna i nie ma między nimi prostego przełożenia. Niemniej jednak chwilę obecną fork RedHata dostępny w repozytorium dla CentOS7 nie zawiera opcji –gpus.

Natomiast w RHEL 8 / CentoOS 8 i Fedora 31 narzędzie/klient docker’a został zastąpiony narzędziem podman. Niestety podman nie mamy opcji –gpus, która umożliwia wykorzystanie GPU z poziomu kontenera.

Dostęp do GPU Nvidia z kontenerów docker’a pod CentOS 7/8 bez root’a/sudo

Ab móc korzystać z GPU z pozziomu kontenera docker pod wymienionymi OSami należy wykonać nast nastepujace kroki;

  • Jeśli jest zainstalowany to odinstalować RedHat’owy fork docker‚a.
  • Zainstalować Docker’a CE
  • Zainstalować NVIDIA Container Toolkit
  • Na koniec należy dodać użytkowników którzy mają uruchamiać kontener bez sudo do systemowej grupy docker.

Odinstalowujemy RedHat’owego docker’a

Zaczynamy od odinstalowania silnika i klienta dockera zainstalowane z repozytoriów CentOS 7, z konsoli:

sudo yum remove docker \
                docker-client \
                docker-client-latest \
                docker-common \
                docker-latest \
                docker-latest-logrotate \
                docker-logrotate \
                docker-engine

W repo RHEL/CentOS’a 8 i Fedory 31 fork RedHat dockera został zastąpiony podman’em.

Instalujemy Docker Community Edition na RHEL / CentOS 7 i CentOS 8

Najpierw należy dodać repozytorium Docker CE od Docker inc. Możemy to zrobić za pomocą yum-utils:

sudo yum install yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

Teraz możemy zainstalować Docker CE poleceniem:

sudo yum install docker-ce docker-ce-cli containerd.io

Następnie uruchamiany demona dockera:

sudo systemctl start docker

I testujemy czy wszystko poszło ok:

docker -v
Docker version 19.03.*, build *********

Powinniśmy dostać wersję docker’a min. 19.03.1, jeśli tak jest sprzwdzamy jeszcze dokerowe „Hello world” wywołując z konsoli:

sudo docker run --rm hello-world

Polecenie run sprawdzi czy mamy już pobrany obraz hello-world, w razie potrzeby pobierze go, a następnie uruchomi jego instancje. Opcja --rm odpowiada za usunięcie/zamknięcie instancji obrazu zaraz po wykoaniu wszystkich poleceń. W naszym wypadku żadnych poleceń nie przekazujemy więc instancja zostanie usunięta/zamknięta natychmiast po uruchomieniu. Jeśli wszystko poszło ok to uruchomiona instancja kontenera hello-world powinna przed zamknięciem zwrócić output jak ten widoczny poniżej.

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

Jeśli tak jest możemy przejść dalej.

Instalacja NVIDIA Container Toolkit

Zaczynamy od dodania repozytorium NVIDIA Container Toolkit:

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

Następnie instalujemy nvidia-container-toolkit:

sudo yum install nvidia-container-toolkit

Restartujemy dockera’a:

service docker restart

I sprawdzamy czy Hello world działa:

docker run --rm hello-world

Wynik powinien być taki sam jak poprzednio.

Jeżeli działa sprawdzamy czy GPU jest widoczne z instrancji docker’a. W tym cely uruchamiamy jakiś obraz zawierajacy np. CUDE z hub.docker.com i polecenie nvidia-smi i wykonujemy w nim to polecenie:

docker run --gpus all --rm nvidia/cuda nvidia-smi

--gpus all oznacza że chcemy dać obrazowi dostęp do wszystkich GPU dostępnych w systemie.
Jeżeli wszystko poszło sprawnie powinniście dostać output podobny do tego poniżej:

Sun May 24 19:07:34 2020 
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 410.79       Driver Version: 410.79       CUDA Version: 10.1     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla V100-PCIE...  Off  | 00000000:18:00.0 Off |                    0 |
| N/A   40C    P0    39W / 250W |  31194MiB / 32480MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  Tesla V100-PCIE...  Off  | 00000000:3B:00.0 Off |                    0 |
| N/A   40C    P0    36W / 250W |  30884MiB / 32480MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   2  Tesla V100-PCIE...  Off  | 00000000:86:00.0 Off |                    0 |
| N/A   41C    P0    39W / 250W |  30884MiB / 32480MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   3  Tesla V100-PCIE...  Off  | 00000000:AF:00.0 Off |                    0 |
| N/A   39C    P0    37W / 250W |  30884MiB / 32480MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
+-----------------------------------------------------------------------------+

W tym wypadku widzimy że kontener ma dostęp do 4 akceleratorów Tesla V100.

Powodzenia!