Vous utilisez un GPU à partir d'un conteneur Docker?

164

Je recherche un moyen d'utiliser le GPU à partir d'un conteneur Docker.

Le conteneur exécutera du code arbitraire donc je ne veux pas utiliser le mode privilégié.

Des conseils?

D'après des recherches précédentes, j'ai compris que run -vet / ou LXC cgroupétait la voie à suivre, mais je ne sais pas comment y parvenir exactement

Regan
la source
Voir stackoverflow.com/questions/17792161/… qui correspond à vos besoins.
Nicolas Goy
1
@NicolasGoy Le lien était bon mais pas très utile car je ne peux pas utiliser de privilèges pour des raisons de sécurité. Le lxc-cgroups était un bon pointeur, mais pas assez. J'ai trouvé un moyen et je répondrai moi-même quand tout sera peaufiné.
Regan

Réponses:

132

La réponse de Regan est excellente, mais elle est un peu dépassée, car la bonne façon de le faire est d'éviter le contexte d'exécution lxc car Docker a supprimé LXC comme contexte d'exécution par défaut à partir de docker 0.9.

Au lieu de cela, il est préférable d'indiquer à docker les périphériques nvidia via l'indicateur --device, et d'utiliser simplement le contexte d'exécution natif plutôt que lxc.

Environnement

Ces instructions ont été testées dans l'environnement suivant:

  • Ubuntu 14.04
  • CUDA 6.5
  • Instance de GPU AWS.

Installez le pilote nvidia et cuda sur votre hôte

Consultez CUDA 6.5 sur l'instance AWS GPU exécutant Ubuntu 14.04 pour obtenir la configuration de votre machine hôte.

Installer 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

Trouvez vos appareils 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

Exécuter le conteneur Docker avec le pilote nvidia pré-installé

J'ai créé une image docker sur laquelle les pilotes cuda sont préinstallés. Le dockerfile est disponible sur dockerhub si vous souhaitez savoir comment cette image a été construite.

Vous voudrez personnaliser cette commande pour qu'elle corresponde à vos appareils nvidia. Voici ce qui a fonctionné pour moi:

 $ 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

Vérifiez que CUDA est correctement installé

Cela doit être exécuté à partir du conteneur Docker que vous venez de lancer.

Installez les exemples CUDA:

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

Build deviceQuery sample:

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

Si tout a fonctionné, vous devriez voir la sortie suivante:

deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 6.5, CUDA Runtime Version = 6.5, NumDevs =    1, Device0 = GRID K520
Result = PASS
tleyden
la source
3
Pourquoi installez-vous lxc-docker si vous n'avez pas besoin de lxc alors?
MP0 du
4
J'ai CUDA 5.5 sur l'hôte et CUDA 6.5 dans un conteneur créé à partir de votre image. CUDA travaille sur l'hôte et j'ai passé les périphériques au conteneur. Le conteneur voit les GPU à travers ls -la /dev | grep nvidiamais CUDA ne trouve aucun périphérique compatible CUDA: ./deviceQuery ./deviceQuery Starting... CUDA Device Query (Runtime API) version (CUDART static linking) cudaGetDeviceCount returned 38 -> no CUDA-capable device is detected Result = FAIL est-ce à cause de la non-concordance des bibliothèques CUDA sur l'hôte et dans le conteneur?
brunetto
1
Je ne sais pas, vous voudrez peut-être demander sur les forums nvidia. En supposant que l'incompatibilité de version est un problème, vous pouvez prendre ce Dockerfile et le modifier pour avoir les pilotes CUDA 5.5, puis reconstruire une nouvelle image Docker à partir de celui-ci et l'utiliser.
tleyden
3
Pouvez-vous expliquer pourquoi l'image doit installer le pilote nvidia? Je pensais que seul l'hôte installant le pilote nvidia (et utiliser --device ...) était suffisant?
Helin Wang
2
Actuellement, il n'y a aucun moyen de le faire si vous avez Windows comme hôte.
Souradeep Nanda
46

Rédaction d'une réponse mise à jour car la plupart des réponses déjà présentes sont désormais obsolètes.

Versions antérieures à celles Docker 19.03utilisées pour exiger nvidia-docker2et le --runtime=nvidiadrapeau.

Depuis Docker 19.03, vous devez installer le nvidia-container-toolkitpackage, puis utiliser l' --gpus allindicateur.

Alors, voici les bases,

Installation du package

Installez le nvidia-container-toolkitpackage selon la documentation officielle sur Github .

Pour les systèmes d'exploitation basés sur Redhat, exécutez l'ensemble de commandes suivant:

$ 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

Pour les systèmes d'exploitation basés sur Debian, exécutez l'ensemble de commandes suivant:

# 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

Exécuter le docker avec le support GPU

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

Veuillez noter que l'indicateur --gpus allest utilisé pour attribuer tous les gpus disponibles au conteneur du docker.

Pour attribuer un GPU spécifique au conteneur Docker (en cas de plusieurs GPU disponibles sur votre machine)

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

Ou

docker run --name my_first_gpu_container --gpus '"device=0"' nvidia/cuda
Rohit
la source
5
À partir de 2019, c'est la bonne façon d'utiliser le GPU à partir de conteneurs Docker.
Timur Bakeyev
1
Quelqu'un a-t-il déjà essayé cela depuis un travail par lots sur AWS?
medley56
1
Je pense que c'est le plus pertinent. J'aurais aimé l' avoir trouvé plus tôt, même si j'ai dû adapter les instructions de github.com/NVIDIA/nvidia-docker pour travailler avec Ubuntu 20.04
VictorLegros
40

Ok, j'ai finalement réussi à le faire sans utiliser le mode --privileged.

Je cours sur le serveur ubuntu 14.04 et j'utilise le dernier cuda (6.0.37 pour linux 13.04 64 bits).


Préparation

Installez le pilote nvidia et cuda sur votre hôte. (cela peut être un peu délicat donc je vous suggère de suivre ce guide /ubuntu/451672/installing-and-testing-cuda-in-ubuntu-14-04 )

ATTENTION: il est très important de conserver les fichiers que vous avez utilisés pour l'installation de l'hôte cuda


Lancez le démon Docker à l'aide de lxc

Nous devons exécuter le démon docker à l'aide du pilote lxc pour pouvoir modifier la configuration et donner au conteneur l'accès au périphérique.

Utilisation unique:

sudo service docker stop
sudo docker -d -e lxc

Configuration permanente Modifiez votre fichier de configuration docker situé dans / etc / default / docker Changez la ligne DOCKER_OPTS en ajoutant '-e lxc' Voici ma ligne après modification

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

Puis redémarrez le démon en utilisant

sudo service docker restart

Comment vérifier si le démon utilise efficacement le pilote lxc?

docker info

La ligne Execution Driver devrait ressembler à ceci:

Execution Driver: lxc-1.0.5

Créez votre image avec les pilotes NVIDIA et CUDA.

Voici un Dockerfile de base pour créer une image compatible 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.

Exécutez votre image.

Vous devez d'abord identifier votre numéro principal associé à votre appareil. Le moyen le plus simple consiste à exécuter la commande suivante:

ls -la /dev | grep nvidia

Si le résultat est vide, utilisez le lancement de l'un des échantillons sur l'hôte devrait faire l'affaire. Le résultat devrait ressembler à ça entrez la description de l'image ici Comme vous pouvez le voir, il y a un ensemble de 2 nombres entre le groupe et la date. Ces 2 nombres sont appelés nombres majeurs et mineurs (écrits dans cet ordre) et désignent un appareil. Nous n'utiliserons que les chiffres majeurs pour plus de commodité.

Pourquoi avons-nous activé le pilote lxc? Pour utiliser l'option lxc conf qui nous permet d'autoriser notre conteneur à accéder à ces périphériques. L'option est: (je recommande d'utiliser * pour le nombre mineur car il réduit la longueur de la commande d'exécution)

--lxc-conf = 'lxc.cgroup.devices.allow = c [nombre majeur]: [nombre mineur ou *] rwm'

Donc, si je veux lancer un conteneur (en supposant que le nom de votre image soit cuda).

docker run -ti --lxc-conf='lxc.cgroup.devices.allow = c 195:* rwm' --lxc-conf='lxc.cgroup.devices.allow = c 243:* rwm' cuda
Regan
la source
Pouvez-vous partager le conteneur?
ChillarAnand
1
Docker a une --deviceoption pour permettre au conteneur d'accéder au périphérique de l'hôte. Cependant, j'ai essayé d'utiliser --device=/dev/nvidia0pour permettre au conteneur docker d'exécuter cuda et j'ai échoué.
shiquanwang
4
Je puis réussi à exposer tous /dev/nvidiao, /dev/nvidia1, /dev/nvidiactlet /dev/nvidia-uvmavec --device. Mais je ne sais pas pourquoi.
shiquanwang
L'option --device n'a pas été implémentée lorsque j'ai dû trouver cette solution. Vous avez besoin d'au moins nvidia0 ou nvidia1 (carte graphique) et nvidiactl (périphérique nvidia général) et nvidia-uvm (périphérique mémoire United).
Regan
2
Merci pour vos conseils sur /dev/nvidia*@Regan. Pour @ChillarAnand j'ai fait un cuda-docker
shiquanwang
29

Nous venons de publier un référentiel GitHub expérimental qui devrait faciliter le processus d'utilisation des GPU NVIDIA dans les conteneurs Docker.

3XX0
la source
4
Existe-t-il un support Windows? Cela ne semble pas l'être, mais il me manque peut-être quelque chose.
Blaze
6
Il n'y a pas de support Windows. L'exécution du conteneur CUDA nécessite des pilotes Nvidia pour Linux et un accès aux périphériques Linux représentant le GPU, par exemple / dev / nvidia0. Ces périphériques et pilotes ne sont pas disponibles lorsque Docker est installé sur Windows et s'exécute dans la machine virtuelle VirtualBox.
Paweł Bylica
Vous avez toujours besoin des déclarations --device dans la commande run? J'ai construit un conteneur à partir de nvidia / cuda et le conteneur fonctionne correctement, mais l'application (Wowza) ne reconnaît pas les GPU alors qu'elle fonctionne très bien lorsqu'elle est exécutée directement sur l'hôte (cet hôte, donc je sais que les pilotes sont bons) . J'utilise 361.28. L'hôte est EC2 utilisant l'AMI NVidia sur g2.8xlarge.
rainabba
Tout n'est pas pris en charge par nvidia-docker, vous devriez pouvoir exécuter nvidia-smi à l'intérieur du conteneur et voir vos appareils
3XX0
22

Les récentes améliorations apportées par NVIDIA ont produit un moyen beaucoup plus robuste de le faire.

Essentiellement, ils ont trouvé un moyen d'éviter d'avoir à installer le pilote CUDA / GPU à l'intérieur des conteneurs et de le faire correspondre au module du noyau hôte.

Au lieu de cela, les pilotes sont sur l'hôte et les conteneurs n'en ont pas besoin. Il nécessite un docker-cli modifié pour le moment.

C'est génial, car maintenant les conteneurs sont beaucoup plus portables.

entrez la description de l'image ici

Un test rapide sur 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

Pour plus de détails, voir: Conteneur Docker compatible GPU et: https://github.com/NVIDIA/nvidia-docker

Mat
la source
Cela fonctionne bien une fois que vous avez toutes les étapes. Nvidia ne fournit pas tout cela au même endroit, mais cet exemple donne tout ce dont vous avez besoin pour le faire fonctionner avec un cas d'utilisation courant.
KobeJohn
@KobeJohn - J'ai juste suivi les instructions d'installation, comment utiliser la ligne de commande et m'assurer que mes conteneurs héritent de ceux de cuda. Cela fonctionne juste pour moi.
Matt
1
En fait, pouvez-vous donner des scénarios réels où l'utilisation de nvidia-docker a du sens?
Suncatcher
@Suncatcher - Je l'utilise dans un cluster qui nécessite un accès au GPU pour le rendu 3D. L'ancrage des applications a simplifié le déploiement et la maintenance.
Matt
17

Mis à jour pour cuda-8.0 sur 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. Exécutez votre conteneur

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

Vous devriez voir une sortie similaire à:

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

Jonathan
la source
3
Je reçois la sortie suivante. cudaGetDeviceCount a renvoyé 38 -> aucun périphérique compatible CUDA n'est détecté Result = FAIL
Soichi Hayashi
Réponse tardive, mais cela signifie que vous n'avez probablement pas de GPU sur cette machine
Jonathan
Une version Cuda-9 serait-elle presque la même que celle-ci?
huseyin tugrul buyukisik
@huseyintugrulbuyukisik voir cette réponse sur askubuntu askubuntu.com/questions/967332/… , je dirais que vous pouvez utiliser cette réponse comme guide mais je n'ai pas travaillé avec cuda 9 pour confirmer que les mêmes étapes s'appliqueraient
Jonathan
Ne fais pas ça de cette façon. C'est la vieille méthode. Utilisez la nouvelle méthode. Voir le lien vers ma réponse. Cette méthode est pleine de problèmes.
Matt
3

Pour utiliser le GPU à partir du conteneur Docker, au lieu d'utiliser Docker natif, utilisez Nvidia-docker. Pour installer le docker Nvidia, utilisez les commandes suivantes

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
la source
1

Utilisez x11docker de mviereck:

https://github.com/mviereck/x11docker#hardware-acceleration dit

Accélération matérielle

L'accélération matérielle pour OpenGL est possible avec l'option -g, --gpu.

Cela fonctionnera dans la plupart des cas avec des pilotes open source sur l'hôte. Sinon, jetez un œil à wiki: les dépendances des fonctionnalités. Les pilotes NVIDIA à source fermée nécessitent une configuration et prennent en charge moins d'options de serveur x11docker X.

Ce script est vraiment pratique car il gère toute la configuration et l'installation. Exécuter une image docker sur X avec gpu est aussi simple que

x11docker --gpu imagename
phil294
la source