在Docker容器中使用GPU?


164

我正在寻找一种从Docker容器内部使用GPU的方法。

容器将执行任意代码,所以我不想使用特权模式。

有小费吗?

从以前的研究中,我了解到run -v和/或LXC cgroup是可行的方法,但我不确定如何准确地实现这一目标



1
@NicolasGoy链接很好,但没那么有用,因为出于安全原因我不能使用特权。lxc-cgroups是一个很好的指针,但还不够。我找到了一种方法,当一切都完成后,我会自我回答。
Regan 2014年

Answers:


132

Regan的答案很好,但是有点过时了,因为这样做的正确方法是避免使用lxc执行上下文,因为Docker从Docker 0.9 开始将LXC删除为默认执行上下文。

相反,最好通过--device标志告诉docker有关nvidia设备的信息,只使用本机执行上下文而不是lxc。

环境

这些说明在以下环境中进行了测试:

  • Ubuntu 14.04
  • CUDA 6.5
  • AWS GPU实例。

在主机上安装nvidia驱动程序和cuda

请参阅运行Ubuntu 14.04的AWS GPU实例上的CUDA 6.5,以获取主机设置。

安装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

查找您的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

在预装nvidia驱动程序的情况下运行Docker容器

我已经创建了一个预安装了cuda驱动程序的docker 镜像。该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

这应该在刚启动的docker容器中运行。

安装CUDA示例:

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

构建deviceQuery示例:

$ 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,为什么还要安装lxc-docker?
2014年

4
我在主机上具有CUDA 5.5,并在根据您的映像创建的容器中具有CUDA 6.5。CUDA在主机上工作,我将设备传递到了容器。容器可以看到GPU,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库不匹配吗?
brunetto 2014年

1
我不知道,您可能想在nvidia论坛上提问。假设版本不匹配是一个问题,您可以将此Dockerfile进行编辑,使其具有CUDA 5.5驱动程序,然后从中重建一个新的Docker映像并使用它。
tleyden 2014年

3
您能解释为什么映像需要安装nvidia驱动程序吗?我认为仅安装nvidia驱动程序的主机(并使用--device ...)就足够了吗?
Helin Wang

2
当前,如果您将Windows作为主机,则无法执行此操作。
Souradeep Nanda

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

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

请注意,该标志--gpus all用于将所有可用gpu分配给docker容器。

要将特定的GPU分配给Docker容器(如果您的计算机中有多个GPU)

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年开始,这是从Docker容器中使用GPU的正确方法。
Timur Bakeyev '19

1
有没有人从AWS的Batch作业内部尝试过此操作?
medley56

1
我相信这是最相关的。希望我早点找到它,尽管我不得不改写github.com/NVIDIA/nvidia-docker的说明以使用Ubuntu 20.04
VictorLegros,

40

好的,我终于设法不使用--privileged模式了。

我在ubuntu服务器14.04上运行,并且正在使用最新的cuda(对于Linux 13.04 64位为6.0.37)。


制备

在主机上安装nvidia驱动程序和cuda。(这可能会有些棘手,因此我建议您遵循此指南/ubuntu/451672/installing-and-testing-cuda-in-ubuntu-14-04

注意:保留用于主机cuda安装的文件非常重要


获取Docker Daemon以使用lxc运行

我们需要使用lxc驱动程序运行docker daemon,以便能够修改配置并赋予容器访问设备的权限。

一次利用率:

sudo service docker stop
sudo docker -d -e lxc

永久配置 修改/ etc / default / docker中的docker配置文件,通过添加'-e lxc'来更改DOCKER_OPTS行这是修改后的行

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驱动程序构建映像。

这是构建CUDA兼容映像的基本Dockerfile。

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个数字。这两个数字分别称为大数和小数(按顺序写入)并设计一个设备。为了方便起见,我们将仅使用主要数字。

为什么我们激活lxc驱动程序?要使用允许我们允许容器访问那些设备的lxc conf选项。选项是:(我建议使用*作为次要数字,因为它会减少运行命令的长度)

--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 2014年

1
Docker有一个--device允许容器访问主机设备的选项。但是我试图用来--device=/dev/nvidia0允许docker容器运行cuda并失败了。
shiquanwang

4
然后我和公开所有成功/dev/nvidiao/dev/nvidia1/dev/nvidiactl/dev/nvidia-uvm--device。虽然不知道为什么。
shiquanwang 2014年

当我必须找到此解决方案时,未实现--device选项。您至少需要nvidia0或nvidia1(图形卡)和nvidiactl(通用nvidia设备)和nvidia-uvm(联合存储设备)。
Regan 2014年

2
感谢您对/dev/nvidia*@Regan 的提示。对于@ChillarAnand,我做了一个cuda-
docker

29

我们刚刚发布了一个实验性的GitHub存储库,它可以简化在Docker容器内使用NVIDIA GPU的过程。


4
有Windows支持吗?似乎不是,但也许我缺少了一些东西。
Blaze 2015年

6
没有Windows支持。运行CUDA容器需要Nvidia驱动程序用于Linux并访问代表GPU的Linux设备,例如/ dev / nvidia0。当Docker安装在Windows上并在VirtualBox虚拟机中运行时,这些设备和驱动程序不可用。
帕维尔Bylica

在运行命令中还需要--device声明吗?我已经从nvidia / cuda构建了一个容器,并且该容器运行良好,但是应用程序(Wowza)无法识别GPU,而直接在主机上运行就可以了(该主机,所以我知道驱动程序很好) 。我正在运行361.28。主机是使用g2.8xlarge上的NVidia AMI的EC2。
rainabba '16

nvidia-docker不会处理所有问题,您应该能够在容器内运行nvidia-smi并查看设备
3XX0 2016年

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

有关更多详细信息,请参阅: 启用GPU的Docker容器 和:https : //github.com/NVIDIA/nvidia-docker


一旦完成所有步骤,此方法将很好地工作。Nvidia并未在一处提供所有功能,但此示例提供了使它与一个通用用例一起使用所需的一切。
科比·约翰'18

@KobeJohn-我只是按照安装说明进行操作,如何使用命令行并确保我的容器继承自cuda容器。它对我有用。
马特

1
实际上,您能否给出使用nvidia-docker有意义的真实场景?
捕手

@Suncatcher-我在需要访问GPU进行3D渲染的群集中使用它。通过对应用程序进行Docker化,使部署和维护变得更简单。
马特

17

在Ubuntu 16.04上针对cuda-8.0进行了更新

Docker文件

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功能的设备结果=失败
Soichi Hayashi

回复较晚,但这意味着您可能在该计算机上没有GPU
Jonathan

Cuda-9版本会与此几乎一样吗?
huseyin tugrul buyukisik

@huseyintugrulbuyukisik看到askubuntu这个答案askubuntu.com/questions/967332/...,我说你可以使用这个答案为指导,但我还没有和CUDA 9合作以确认相同的步骤也适用
乔纳森

不要这样 这是老方法。使用新方法。请参阅我的答案链接。这种方法充满了问题。
马特

3

要从Docker容器中使用GPU,而不是使用本机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

使用mviereck的x11docker:

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

硬件加速

OpenGL的硬件加速可以通过-g,--gpu选项实现。

在主机上使用开源驱动程序的大多数情况下,这是开箱即用的。否则,请查看Wiki:功能依赖性。开源NVIDIA驱动程序需要一些设置,并支持更少的x11docker X服务器选项。

该脚本非常方便,因为它可以处理所有配置和设置。使用gpu在X上运行docker镜像非常简单

x11docker --gpu imagename
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.