Używasz GPU z kontenera docker?

164

Szukam sposobu na użycie GPU z wnętrza kontenera dockera.

Kontener wykona dowolny kod, więc nie chcę używać trybu uprzywilejowanego.

Jakieś wskazówki?

Z poprzednich badań zrozumiałem, że run -vi / lub LXC cgroupbyło drogą do zrobienia, ale nie jestem pewien, jak dokładnie to zrobić

Regan
źródło
Zobacz stackoverflow.com/questions/17792161/…, który jest podobny do twoich potrzeb.
Nicolas Goy
1
@NicolasGoy Link był dobry, ale niezbyt przydatny, ponieważ ze względów bezpieczeństwa nie mogę używać uprzywilejowanych. Lxc-cgroups było dobrym wskaźnikiem, ale niewystarczającym. Znalazłem sposób i sam odpowiem, kiedy wszystko będzie wypolerowane.
Regan

Odpowiedzi:

132

Odpowiedź Regana jest świetna, ale jest trochę nieaktualna, ponieważ poprawnym sposobem na to jest unikanie kontekstu wykonywania lxc, ponieważ Docker porzucił LXC jako domyślny kontekst wykonywania od wersji docker 0.9.

Zamiast tego lepiej jest powiedzieć dockerowi o urządzeniach nvidia za pomocą flagi --device i po prostu użyć natywnego kontekstu wykonywania zamiast lxc.

Środowisko

Te instrukcje zostały przetestowane w następującym środowisku:

  • Ubuntu 14.04
  • CUDA 6.5
  • Instancja GPU AWS.

Zainstaluj sterownik nvidia i cuda na swoim hoście

Zobacz CUDA 6.5 w wystąpieniu GPU AWS z systemem Ubuntu 14.04, aby uzyskać konfigurację maszyny hosta.

Zainstaluj Docker

$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
$ sudo sh -c "echo deb https://get.docker.com/ubuntu docker main > /etc/apt/sources.list.d/docker.list"
$ sudo apt-get update && sudo apt-get install lxc-docker

Znajdź swoje urządzenia nvidia

ls -la /dev | grep nvidia

crw-rw-rw-  1 root root    195,   0 Oct 25 19:37 nvidia0 
crw-rw-rw-  1 root root    195, 255 Oct 25 19:37 nvidiactl
crw-rw-rw-  1 root root    251,   0 Oct 25 19:37 nvidia-uvm

Uruchom kontener Docker z preinstalowanym sterownikiem nvidia

Utworzyłem obraz Dockera z preinstalowanymi sterownikami cuda. Plik dockerfile jest dostępny na dockerhub, jeśli chcesz wiedzieć, jak ten obraz został zbudowany.

Będziesz chciał dostosować to polecenie, aby pasowało do Twoich urządzeń nvidia. Oto, co zadziałało dla mnie:

 $ sudo docker run -ti --device /dev/nvidia0:/dev/nvidia0 --device /dev/nvidiactl:/dev/nvidiactl --device /dev/nvidia-uvm:/dev/nvidia-uvm tleyden5iwx/ubuntu-cuda /bin/bash

Sprawdź, czy CUDA jest poprawnie zainstalowany

Powinno to zostać uruchomione z wnętrza właśnie uruchomionego kontenera Dockera.

Zainstaluj próbki CUDA:

$ cd /opt/nvidia_installers
$ ./cuda-samples-linux-6.5.14-18745345.run -noprompt -cudaprefix=/usr/local/cuda-6.5/

Build deviceQuery przykład:

$ cd /usr/local/cuda/samples/1_Utilities/deviceQuery
$ make
$ ./deviceQuery   

Jeśli wszystko działało, powinieneś zobaczyć następujący wynik:

deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 6.5, CUDA Runtime Version = 6.5, NumDevs =    1, Device0 = GRID K520
Result = PASS
tleyden
źródło
3
Dlaczego instalujesz lxc-docker, skoro nie potrzebujesz lxc?
MP0
4
Mam CUDA 5.5 na hoście i CUDA 6.5 w kontenerze utworzonym z twojego obrazu. CUDA pracuje na hoście, a ja przekazałem urządzenia do kontenera. Kontener widzi procesory GPU, ls -la /dev | grep nvidiaale CUDA nie może znaleźć żadnego urządzenia obsługującego CUDA: ./deviceQuery ./deviceQuery Starting... CUDA Device Query (Runtime API) version (CUDART static linking) cudaGetDeviceCount returned 38 -> no CUDA-capable device is detected Result = FAIL czy dzieje się tak z powodu niezgodności bibliotek CUDA na hoście iw kontenerze?
brunetto
1
Nie wiem, możesz zapytać na forach nvidii. Zakładając, że niezgodność wersji jest problemem, możesz wziąć ten plik Dockerfile i edytować go, aby mieć sterowniki CUDA 5.5, a następnie odbudować z niego nowy obraz dockera i użyć go.
tleyden
3
Czy możesz wyjaśnić, dlaczego obraz musi zainstalować sterownik NVIDIA? Myślałem, że tylko host instalujący sterownik nvidii (i użyj --device ...) jest wystarczający?
Helin Wang
2
Obecnie nie można tego zrobić, jeśli hostem jest system Windows.
Souradeep Nanda,
46

Pisanie zaktualizowanej odpowiedzi, ponieważ większość już obecnych odpowiedzi jest obecnie nieaktualna.

Wersje wcześniejsze niż Docker 19.03wymagały nvidia-docker2i --runtime=nvidiaflaga.

Ponieważ Docker 19.03musisz zainstalować nvidia-container-toolkitpakiet, a następnie użyć --gpus allflagi.

Oto podstawy,

Instalacja pakietu

Zainstaluj nvidia-container-toolkitpakiet zgodnie z oficjalną dokumentacją na Github .

W przypadku systemów operacyjnych opartych na Redhat wykonaj następujący zestaw poleceń:

$ 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

$ sudo yum install -y nvidia-container-toolkit
$ sudo systemctl restart docker

W przypadku systemów operacyjnych opartych na Debianie wykonaj następujący zestaw poleceń:

# Add the package repositories
$ 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

$ sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
$ sudo systemctl restart docker

Uruchamianie dockera z obsługą GPU

docker run --name my_all_gpu_container --gpus all -t nvidia/cuda

Należy pamiętać, że flaga --gpus allsłuży do przypisywania wszystkich dostępnych procesorów graficznych do kontenera Dockera.

Aby przypisać określone GPU do kontenera Dockera (w przypadku wielu GPU dostępnych na twoim komputerze)

docker run --name my_first_gpu_container --gpus device=0 nvidia/cuda

Lub

docker run --name my_first_gpu_container --gpus '"device=0"' nvidia/cuda
Rohit
źródło
5
Od 2019 roku jest to właściwy sposób korzystania z GPU z poziomu kontenerów docker.
Timur Bakeyev
1
Czy ktoś kiedykolwiek próbował tego w ramach zadania wsadowego w AWS?
medley56
1
Uważam, że jest to najbardziej istotne. Szkoda, że ​​nie znalazłem go wcześniej, chociaż musiałem dostosować instrukcje z github.com/NVIDIA/nvidia-docker do pracy z Ubuntu 20.04
VictorLegros
40

Ok, w końcu udało mi się to zrobić bez użycia trybu --privileged.

Pracuję na serwerze ubuntu 14.04 i używam najnowszego CUDA (6.0.37 dla Linuksa 13.04 64 bity).


Przygotowanie

Zainstaluj sterownik nvidia i cuda na swoim hoście. (może to być trochę trudne, więc proponuję postępować zgodnie z tym przewodnikiem /ubuntu/451672/installing-and-testing-cuda-in-ubuntu-14-04 )

UWAGA: Bardzo ważne jest, aby zachować pliki użyte do instalacji hosta cuda


Pobierz demona platformy Docker do uruchomienia przy użyciu lxc

Musimy uruchomić demona dockera przy użyciu sterownika lxc, aby móc modyfikować konfigurację i nadać kontenerowi dostęp do urządzenia.

Jednorazowe wykorzystanie:

sudo service docker stop
sudo docker -d -e lxc

Stała konfiguracja Zmodyfikuj plik konfiguracyjny dockera znajdujący się w / etc / default / docker Zmień wiersz DOCKER_OPTS dodając '-e lxc' Oto moja linia po modyfikacji

DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4 -e lxc"

Następnie zrestartuj demona za pomocą

sudo service docker restart

Jak sprawdzić, czy demon efektywnie wykorzystuje sterownik lxc?

docker info

Linia Execution Driver powinna wyglądać następująco:

Execution Driver: lxc-1.0.5

Zbuduj swój obraz za pomocą sterowników NVIDIA i CUDA.

Oto podstawowy plik Dockerfile do tworzenia obrazu zgodnego z CUDA.

FROM ubuntu:14.04
MAINTAINER Regan <http://stackoverflow.com/questions/25185405/using-gpu-from-a-docker-container>

RUN apt-get update && apt-get install -y build-essential
RUN apt-get --purge remove -y nvidia*

ADD ./Downloads/nvidia_installers /tmp/nvidia                             > Get the install files you used to install CUDA and the NVIDIA drivers on your host
RUN /tmp/nvidia/NVIDIA-Linux-x86_64-331.62.run -s -N --no-kernel-module   > Install the driver.
RUN rm -rf /tmp/selfgz7                                                   > For some reason the driver installer left temp files when used during a docker build (i don't have any explanation why) and the CUDA installer will fail if there still there so we delete them.
RUN /tmp/nvidia/cuda-linux64-rel-6.0.37-18176142.run -noprompt            > CUDA driver installer.
RUN /tmp/nvidia/cuda-samples-linux-6.0.37-18176142.run -noprompt -cudaprefix=/usr/local/cuda-6.0   > CUDA samples comment if you don't want them.
RUN export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib64         > Add CUDA library into your PATH
RUN touch /etc/ld.so.conf.d/cuda.conf                                     > Update the ld.so.conf.d directory
RUN rm -rf /temp/*  > Delete installer files.

Uruchom swój obraz.

Najpierw musisz zidentyfikować swój główny numer powiązany z twoim urządzeniem. Najłatwiej jest wykonać następujące polecenie:

ls -la /dev | grep nvidia

Jeśli wynik jest pusty, użyj uruchomienia jednej z próbek na hoście. Wynik powinien wyglądać tak. wprowadź opis obrazu tutaj Jak widać, między grupą a datą znajduje się zestaw 2 liczb. Te dwie liczby nazywane są liczbami głównymi i pomocniczymi (zapisane w tej kolejności) i projektują urządzenie. Dla wygody użyjemy tylko głównych liczb.

Dlaczego aktywowaliśmy sterownik LXC? Aby użyć opcji lxc conf, która pozwala nam zezwolić naszemu kontenerowi na dostęp do tych urządzeń. Dostępna opcja: (zalecam użycie znaku * jako podrzędnej liczby, ponieważ zmniejsza to długość polecenia uruchomienia)

--lxc-conf = 'lxc.cgroup.devices.allow = c [główna liczba]: [pomocnicza liczba lub *] rwm'

Więc jeśli chcę uruchomić kontener (zakładając, że nazwa twojego obrazu to cuda).

docker run -ti --lxc-conf='lxc.cgroup.devices.allow = c 195:* rwm' --lxc-conf='lxc.cgroup.devices.allow = c 243:* rwm' cuda
Regan
źródło
Czy możesz udostępnić pojemnik?
ChillarAnand
1
Docker ma --deviceopcję zezwalania kontenerowi na dostęp do urządzenia hosta. Jednak próbowałem użyć, --device=/dev/nvidia0aby zezwolić kontenerowi dockerowi na uruchomienie cuda i nie udało mi się.
shiquanwang
4
Potem udało się odsłaniając wszystko /dev/nvidiao, /dev/nvidia1, /dev/nvidiactli /dev/nvidia-uvmz --device. Chociaż nie wiem dlaczego.
shiquanwang
Opcja --device nie została zaimplementowana, gdy musiałem znaleźć to rozwiązanie. Potrzebujesz przynajmniej nvidia0 lub nvidia1 (karta graficzna) i nvidiactl (ogólne urządzenie nvidia) i nvidia-uvm (United memory device).
Regan
2
Dzięki za podpowiedzi dotyczące /dev/nvidia*@Regan. Dla @ChillarAnand zrobiłem cuda -
docker
29

Właśnie udostępniliśmy eksperymentalne repozytorium GitHub, które powinno ułatwić proces używania procesorów graficznych NVIDIA w kontenerach Docker.

3XX0
źródło
4
Czy istnieje wsparcie dla systemu Windows? Wydaje się, że tak nie jest, ale może czegoś mi brakuje.
Blaze
6
Nie ma wsparcia dla systemu Windows. Uruchomienie kontenera CUDA wymaga sterowników Nvidia dla systemu Linux i dostępu do urządzeń linuksowych reprezentujących GPU, np. / Dev / nvidia0. Te urządzenia i sterowniki nie są dostępne, gdy Docker jest zainstalowany w systemie Windows i działa na maszynie wirtualnej VirtualBox.
Paweł Bylica
Nadal potrzebujesz deklaracji --device w poleceniu run? Zbudowałem kontener z nvidia / cuda i kontener działa dobrze, ale aplikacja (Wowza) nie rozpoznaje procesorów graficznych, podczas gdy działa dobrze, gdy jest uruchamiana bezpośrednio na hoście (ten host, więc wiem, że sterowniki są w porządku) . Biegnę 361,28. Host to EC2 z NVidia AMI na g2.8xlarge.
rainabba
Nie, wszystko jest obsługiwane przez nvidia-docker, powinieneś być w stanie uruchomić nvidia-smi wewnątrz kontenera i zobaczyć swoje urządzenia
3XX0
22

Ostatnie ulepszenia firmy NVIDIA zaowocowały znacznie bardziej niezawodnym sposobem na osiągnięcie tego.

Zasadniczo znaleźli sposób na uniknięcie konieczności instalowania sterownika CUDA / GPU w kontenerach i dopasowywania go do modułu jądra hosta.

Zamiast tego sterowniki znajdują się na hoście, a kontenery ich nie potrzebują. Obecnie wymaga zmodyfikowanego docker-cli.

To świetnie, ponieważ teraz kontenery są znacznie bardziej przenośne.

wprowadź opis obrazu tutaj

Szybki test na Ubuntu:

# Install nvidia-docker and nvidia-docker-plugin
wget -P /tmp https://github.com/NVIDIA/nvidia-docker/releases/download/v1.0.1/nvidia-docker_1.0.1-1_amd64.deb
sudo dpkg -i /tmp/nvidia-docker*.deb && rm /tmp/nvidia-docker*.deb

# Test nvidia-smi
nvidia-docker run --rm nvidia/cuda nvidia-smi

Aby uzyskać więcej informacji, zobacz: Kontener Dockera z obsługą GPU i: https://github.com/NVIDIA/nvidia-docker

Matt
źródło
Działa to dobrze, gdy wykonasz wszystkie kroki. Nvidia nie zapewnia tego wszystkiego w jednym miejscu, ale ten przykład daje wszystko, czego potrzebujesz, aby działał w typowym przypadku użycia.
KobeJohn,
@KobeJohn - po prostu postępowałem zgodnie z instrukcją instalacji, jak używać wiersza poleceń i upewniam się, że moje kontenery dziedziczą po kontenerach cuda. U mnie to po prostu działa.
Matt,
1
Właściwie, czy możesz podać rzeczywiste scenariusze, w których użycie nvidia-docker ma sens?
Suncatcher
@Suncatcher - używam go w klastrze, który wymaga dostępu do GPU w celu renderowania 3D. Dockeryzacja aplikacji uprościła wdrażanie i konserwację.
Matt
17

Zaktualizowano dla CUDA-8.0 na Ubuntu 16.04

Dockerfile

FROM ubuntu:16.04
MAINTAINER Jonathan Kosgei <jonathan@saharacluster.com>

# A docker container with the Nvidia kernel module and CUDA drivers installed

ENV CUDA_RUN https://developer.nvidia.com/compute/cuda/8.0/prod/local_installers/cuda_8.0.44_linux-run

RUN apt-get update && apt-get install -q -y \
  wget \
  module-init-tools \
  build-essential 

RUN cd /opt && \
  wget $CUDA_RUN && \
  chmod +x cuda_8.0.44_linux-run && \
  mkdir nvidia_installers && \
  ./cuda_8.0.44_linux-run -extract=`pwd`/nvidia_installers && \
  cd nvidia_installers && \
  ./NVIDIA-Linux-x86_64-367.48.run -s -N --no-kernel-module

RUN cd /opt/nvidia_installers && \
  ./cuda-linux64-rel-8.0.44-21122537.run -noprompt

# Ensure the CUDA libs and binaries are in the correct environment variables
ENV LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda-8.0/lib64
ENV PATH=$PATH:/usr/local/cuda-8.0/bin

RUN cd /opt/nvidia_installers &&\
    ./cuda-samples-linux-8.0.44-21122537.run -noprompt -cudaprefix=/usr/local/cuda-8.0 &&\
    cd /usr/local/cuda/samples/1_Utilities/deviceQuery &&\ 
    make

WORKDIR /usr/local/cuda/samples/1_Utilities/deviceQuery
  1. Uruchom swój kontener

sudo docker run -ti --device /dev/nvidia0:/dev/nvidia0 --device /dev/nvidiactl:/dev/nvidiactl --device /dev/nvidia-uvm:/dev/nvidia-uvm <built-image> ./deviceQuery

Powinieneś zobaczyć dane wyjściowe podobne do:

deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 8.0, CUDA Runtime Version = 8.0, NumDevs = 1, Device0 = GRID K520 Result = PASS

Jonathan
źródło
3
Otrzymuję następujące dane wyjściowe. cudaGetDeviceCount zwrócony 38 -> nie wykryto żadnego urządzenia obsługującego CUDA Wynik = FAIL
Soichi Hayashi
Późna odpowiedź, ale oznacza to, że prawdopodobnie nie masz GPU na tej maszynie
Jonathan
Czy wersja Cuda-9 byłaby prawie taka sama?
huseyin tugrul buyukisik
@huseyintugrulbuyukisik zobacz tę odpowiedź na askubuntu askubuntu.com/questions/967332/… , powiedziałbym, że możesz użyć tej odpowiedzi jako przewodnika, ale nie pracowałem z cuda 9, aby potwierdzić, że te same kroki miałyby zastosowanie
Jonathan
Nie rób tego w ten sposób. To jest stary sposób. Skorzystaj z nowego sposobu. Zobacz link do mojej odpowiedzi. Ta metoda jest pełna problemów.
Matt,
3

Aby użyć GPU z kontenera Dockera, zamiast korzystać z natywnego Dockera, użyj Nvidia-docker. Aby zainstalować docker Nvidia, użyj następujących poleceń

curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey |  sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/ubuntu16.04/amd64/nvidia-
docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update
sudo apt-get install -y nvidia-docker
sudo pkill -SIGHUP dockerd # Restart Docker Engine
sudo nvidia-docker run --rm nvidia/cuda nvidia-smi # finally run nvidia-smi in the same container
Patel Sunil
źródło
1

Użyj x11docker firmy mviereck:

https://github.com/mviereck/x11docker#hardware-acceleration mówi

Akceleracja sprzętowa

Przyspieszenie sprzętowe dla OpenGL jest możliwe za pomocą opcji -g, --gpu.

W większości przypadków zadziała to po wyjęciu z pudełka ze sterownikami open source na hoście. W przeciwnym razie spójrz na wiki: zależności funkcji. Sterowniki NVIDIA z zamkniętym źródłem wymagają pewnej konfiguracji i obsługują mniej opcji serwera x11docker X.

Ten skrypt jest naprawdę wygodny, ponieważ obsługuje całą konfigurację i instalację. Uruchamianie obrazu dockera na X przy użyciu gpu jest tak proste, jak

x11docker --gpu imagename
phil294
źródło