Используете GPU из Docker-контейнера?


164

Я ищу способ использовать графический процессор из док-контейнера.

Контейнер выполнит произвольный код, поэтому я не хочу использовать привилегированный режим.

Какие-нибудь советы?

Из предыдущего исследования я понял, что run -vи / или LXC cgroup- это путь, но я не уверен, как именно это осуществить.


См. Stackoverflow.com/questions/17792161/… который похож на вашу потребность.
Николас Гой

1
@NicolasGoy Ссылка была хорошей, но не очень полезной, так как я не могу использовать привилегированные по соображениям безопасности. Lxc-cgroups был хорошим указателем, но этого недостаточно. Я нашел способ, и я сам отвечу, когда все будет отполировано.
Regan

Ответы:


132

Ответ Регана великолепен, но он немного устарел, поскольку правильный способ сделать это - избежать контекста выполнения lxc, так как Docker отбросил LXC в качестве контекста выполнения по умолчанию с docker 0.9.

Вместо этого лучше сообщить докеру об устройствах nvidia через флаг --device и просто использовать собственный контекст выполнения, а не lxc.

Окружающая среда

Эти инструкции были протестированы в следующей среде:

  • Убунту 14.04
  • CUDA 6.5
  • Экземпляр AWS GPU.

Установите драйвер nvidia и cuda на свой хост

См. CUDA 6.5 для экземпляра графического процессора AWS, на котором запущена Ubuntu 14.04, чтобы получить настройки своего хост-компьютера.

Установить докер

$ 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

Найдите свои устройства 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

Запустите Docker контейнер с предустановленным драйвером nvidia

Я создал образ докера с предустановленными драйверами cuda. Dockerfile доступно на dockerhub , если вы хотите знать , как был построен этот образ.

Вы захотите настроить эту команду в соответствии с вашими устройствами nvidia. Вот что сработало для меня:

 $ 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

Убедитесь, что CUDA правильно установлен

Это должно быть запущено из док-контейнера, который вы только что запустили.

Установите образцы CUDA:

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

Сборка устройства. Пример запроса:

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

Если все работает, вы должны увидеть следующий вывод:

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

3
Зачем вам устанавливать lxc-docker, если вам тогда не нужен lxc?
MP0

4
У меня CUDA 5.5 на хосте и CUDA 6.5 в контейнере, созданном из вашего образа. CUDA работает на хосте, и я передал устройства в контейнер. Контейнер просматривает графические процессоры, ls -la /dev | grep nvidiaно CUDA не может найти ни одно устройство с поддержкой CUDA: ./deviceQuery ./deviceQuery Starting... CUDA Device Query (Runtime API) version (CUDART static linking) cudaGetDeviceCount returned 38 -> no CUDA-capable device is detected Result = FAIL это из-за несовпадения библиотек CUDA на хосте и в контейнере?
Брюнетто

1
Я не знаю, вы можете спросить на форумах nvidia. Предполагая, что несовпадение версий является проблемой, вы можете взять этот Dockerfile и отредактировать его, чтобы иметь драйверы CUDA 5.5, а затем пересоздать из него новый образ докера и использовать его.
tleyden

3
Можете ли вы объяснить, почему образ должен установить драйвер nvidia? Я думал, что только хост установки драйвера nvidia (и использовать --device ...) достаточно?
Хелин Ван

2
В настоящее время нет способа сделать это, если вы используете Windows в качестве хоста.
Сурадип Нанда

46

Написание обновленного ответа, так как большинство уже существующих ответов устарели на данный момент.

Версии раньше чем Docker 19.03раньше требовали nvidia-docker2и --runtime=nvidiaфлаг.

Так как Docker 19.03вам нужно установить nvidia-container-toolkitпакет, а затем использовать --gpus allфлаг.

Итак, вот основы,

Установка пакета

Установите nvidia-container-toolkitпакет согласно официальной документации на Github .

Для ОС на базе Redhat выполните следующий набор команд:

$ 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

Для ОС на основе Debian выполните следующий набор команд:

# 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

Запуск докера с поддержкой GPU

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

Обратите внимание, флаг --gpus allиспользуется для назначения всех доступных графических процессоров в контейнер докера.

Чтобы назначить конкретный графический процессор док-контейнеру (если на вашем компьютере доступно несколько графических процессоров)

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

Или

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

5
Начиная с 2019 года, это правильный способ использования графического процессора из док-контейнеров.
Тимур

1
Кто-нибудь когда-нибудь пробовал это из пакетной работы на AWS?
medley56

1
Я считаю, что это наиболее актуально. Жаль, что я нашел это раньше, хотя мне пришлось адаптировать инструкции от github.com/NVIDIA/nvidia-docker для работы с Ubuntu 20.04
VictorLegros

40

Хорошо, мне наконец-то удалось это сделать без использования режима --privileged.

Я использую Ubuntu Server 14.04 и использую последнюю версию CUDA (6.0.37 для Linux 13.04 64 бит).


подготовка

Установите драйвер nvidia и cuda на свой хост. (это может быть немного сложно, поэтому я предлагаю вам следовать этому руководству /ubuntu/451672/install-and-testing-cuda-in-ubuntu-14-04 )

ВНИМАНИЕ: Очень важно сохранить файлы, которые вы использовали для установки хоста cuda.


Получить Docker Daemon для запуска с помощью lxc

Нам нужно запустить демон docker, используя драйвер lxc, чтобы иметь возможность изменять конфигурацию и предоставлять контейнеру доступ к устройству.

Одноразовое использование:

sudo service docker stop
sudo docker -d -e lxc

Постоянная конфигурация. Измените свой файл конфигурации докера, расположенный в / etc / default / docker. Измените строку DOCKER_OPTS, добавив '-e lxc'. Вот моя строка после модификации.

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

Затем перезапустите демон, используя

sudo service docker restart

Как проверить, эффективно ли демон использует драйвер lxc?

docker info

Строка «Драйвер выполнения» должна выглядеть так:

Execution Driver: lxc-1.0.5

Создайте свой образ с помощью драйверов NVIDIA и CUDA.

Вот основной Dockerfile для создания 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.

Запустите ваше изображение.

Сначала вам нужно определить свой основной номер, связанный с вашим устройством. Самый простой способ - выполнить следующую команду:

ls -la /dev | grep nvidia

Если результат пустой, используйте запуск одного из примеров на хосте, чтобы добиться цели. Результат должен выглядеть следующим образом. введите описание изображения здесь Как видите, между группой и датой есть набор из 2 чисел. Эти 2 числа называются старшими и младшими (написаны в таком порядке) и предназначены для устройства. Мы просто будем использовать основные номера для удобства.

Почему мы активировали драйвер LXC? Использовать опцию lxc conf, которая позволяет нам разрешать нашему контейнеру доступ к этим устройствам. Опция: (я рекомендую использовать * для младшего номера, потому что это уменьшает длину команды run)

--lxc-conf = 'lxc.cgroup.devices.allow = c [старший номер]: [младший номер или *] rwm'

Так что, если я хочу запустить контейнер (Предположим, ваше изображение называется CUDA).

docker run -ti --lxc-conf='lxc.cgroup.devices.allow = c 195:* rwm' --lxc-conf='lxc.cgroup.devices.allow = c 243:* rwm' cuda

Можете ли вы поделиться контейнером?
ChillarAnand

1
Docker имеет --deviceвозможность разрешить контейнеру доступ к устройству хоста. Однако я попытался использовать, --device=/dev/nvidia0чтобы позволить Docker-контейнеру запускать CUDA, и потерпел неудачу.
Shiquanwang

4
Я тогда удалось с обнажая все /dev/nvidiao, /dev/nvidia1, /dev/nvidiactlи /dev/nvidia-uvmс --device. Хотя не знаю почему.
shiquanwang

Опция --device не была реализована, когда мне нужно было найти это решение. Вам нужны как минимум nvidia0 или nvidia1 (графическая карта) и nvidiactl (общее устройство nvidia) и nvidia-uvm (объединенное устройство памяти).
Реган

2
Спасибо за ваши подсказки на /dev/nvidia*@Regan. Для @ChillarAnand я сделал cuda-docker
shiquanwang

29

Мы только что выпустили экспериментальный репозиторий GitHub, который должен облегчить процесс использования графических процессоров NVIDIA внутри контейнеров Docker.


4
Есть ли поддержка Windows? Кажется, что нет, но, возможно, я что-то упустил.
Blaze

6
Нет поддержки Windows. Для запуска контейнера CUDA требуются драйверы Nvidia для Linux и доступ к устройствам Linux, представляющим GPU, например / dev / nvidia0. Эти устройства и драйверы недоступны, если Docker установлен в Windows и работает на виртуальной машине VirtualBox.
Павел Былич

Все еще нужны объявления --device в команде run? Я построил контейнер ОТ nvidia / cuda, и контейнер работает нормально, но приложение (Wowza) не распознает графические процессоры, хотя прекрасно работает при запуске непосредственно на хосте (этот хост, так что я знаю, что драйверы в порядке) , Я бегу 361,28. Хост - EC2, использующий NVidia AMI на g2.8xlarge.
rainabba

Nvidia-docker не заботится обо всем, вы должны иметь возможность запускать nvidia-smi внутри контейнера и видеть ваши устройства
3XX0

22

Недавние усовершенствования NVIDIA создали гораздо более надежный способ сделать это.

По сути, они нашли способ избежать необходимости устанавливать драйвер CUDA / GPU внутри контейнеров и обеспечивать его соответствие модулю ядра хоста.

Вместо этого драйверы находятся на хосте, и контейнеры не нуждаются в них. Это требует модифицированного docker-cli прямо сейчас.

Это здорово, потому что теперь контейнеры стали намного более переносимыми.

введите описание изображения здесь

Быстрый тест на 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

Для получения дополнительной информации см .: Контейнер Docker с поддержкой графического процессора и: https://github.com/NVIDIA/nvidia-docker


Это хорошо работает, как только вы пройдете все этапы. Nvidia не предоставляет все это в одном месте, но этот пример дает все необходимое, чтобы заставить его работать с обычным вариантом использования.
КобеДжон

@KobeJohn - Я просто следовал инструкциям по установке, тому, как использовать командную строку, и убедился, что мои контейнеры наследуются от контейнеров cuda. Это просто работает для меня.
Мэтт

1
На самом деле, вы можете привести реальные сценарии, в которых использование nvidia-docker имеет смысл?
Suncatcher

@Suncatcher - я использую его в кластере, который требует доступа к графическому процессору для 3D-рендеринга. Докеризация приложений упростила процесс развертывания и поддержки.
Мэтт

17

Обновлен для cuda-8.0 в 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. Запустите свой контейнер

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

Вы должны увидеть вывод, похожий на:

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


3
Я получаю следующий вывод. cudaGetDeviceCount вернул 38 -> устройство с поддержкой CUDA не обнаружено Результат = FAIL
Соичи Хаяси

Поздний ответ, но это означает, что у вас, вероятно, нет графического процессора на этой машине
Джонатан

Будет ли версия Cuda-9 почти такой же, как эта?
хусейн тугрул буюкисик

@huseyintugrulbuyukisik смотрите этот ответ на askubuntu askubuntu.com/questions/967332/… , я бы сказал, что вы можете использовать этот ответ в качестве руководства, но я не работал с cuda 9, чтобы подтвердить, что будут применены те же шаги
Джонатан

Не делай так. Это старый способ. Используйте новый способ. Смотрите ссылку на мой ответ. Этот метод чреват проблемами.
Мэтт

3

Чтобы использовать графический процессор из Docker-контейнера, вместо использования родного Docker, используйте Nvidia-Docker. Для установки докера Nvidia используйте следующие команды

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

1

Используйте x11docker от mviereck:

https://github.com/mviereck/x11docker#hardware-acceleration говорит

Аппаратное ускорение

Аппаратное ускорение для OpenGL возможно с опциями -g, --gpu.

В большинстве случаев это будет работать из коробки с драйверами с открытым исходным кодом на хосте. В противном случае взгляните на вики: функциональные зависимости. Драйверы NVIDIA с закрытым исходным кодом нуждаются в некоторой настройке и поддерживают меньше возможностей X-сервера X11docker.

Этот скрипт действительно удобен, так как обрабатывает все настройки и настройки. Запуск образа докера на X с помощью gpu так же прост, как

x11docker --gpu imagename
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.