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

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

任何建议吗?

从以前的研究中,我了解到运行-v和/或LXC cgroup是要走的路,但我不确定如何把它拉下来


当前回答

要从docker容器中使用GPU,而不是使用本地docker,使用Nvidia-docker。要安装Nvidia docker,请使用以下命令

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

其他回答

要从docker容器中使用GPU,而不是使用本地docker,使用Nvidia-docker。要安装Nvidia docker,请使用以下命令

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

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

好吧,我终于设法做到没有使用——特权模式。

我在ubuntu服务器14.04上运行,我使用的是最新的cuda (6.0.37 linux 13.04 64位)。


准备

在主机上安装nvidia驱动程序和cuda。(这可能有点棘手,所以我建议你遵循这个指南https://askubuntu.com/questions/451672/installing-and-testing-cuda-in-ubuntu-14-04)

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


使用lxc让Docker Daemon运行

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

一次性利用:

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

下面是一个基本的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个数字。 这两个号码被称为主号码和副号码(按此顺序书写),并设计一个设备。 为了方便起见,我们只使用主号。

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

——lxcc -conf=' lxcc .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

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/ CUDA作为基础图像的情况下,制作一个CUDA启用的docker图像。因为我有一些自定义的木星图像,我想以此为基础。

先决条件:

主机上已经安装了nvidia驱动程序、CUDA工具包和nvidia-container-toolkit。请参考官方文件,以及Rohit的回答。

测试nvidia驱动和CUDA工具包是否正确安装:主机上的nvidia-smi,应该显示正确的“driver Version”和“CUDA Version”,并显示gpu信息。

测试nvidia-container-toolkit是否正确安装:docker run——rm——gpu all nvidia/cuda:最新的nvidia-smi

Dockerfile

我找到了我认为是nvidia/cuda的官方Dockerfile,在这里我“压平”它,将内容附加到我的Dockerfile中,并测试它工作得很好:

FROM sidazhou/scipy-notebook:latest
# FROM ubuntu:18.04 

###########################################################################
# See https://gitlab.com/nvidia/container-images/cuda/-/blob/master/dist/10.1/ubuntu18.04-x86_64/base/Dockerfile
# See https://sarus.readthedocs.io/en/stable/user/custom-cuda-images.html
###########################################################################
USER root

###########################################################################
# base
RUN apt-get update && apt-get install -y --no-install-recommends \
    gnupg2 curl ca-certificates && \
    curl -fsSL https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub | apt-key add - && \
    echo "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64 /" > /etc/apt/sources.list.d/cuda.list && \
    echo "deb https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64 /" > /etc/apt/sources.list.d/nvidia-ml.list && \
    apt-get purge --autoremove -y curl \
    && rm -rf /var/lib/apt/lists/*

ENV CUDA_VERSION 10.1.243
ENV CUDA_PKG_VERSION 10-1=$CUDA_VERSION-1

# For libraries in the cuda-compat-* package: https://docs.nvidia.com/cuda/eula/index.html#attachment-a
RUN apt-get update && apt-get install -y --no-install-recommends \
    cuda-cudart-$CUDA_PKG_VERSION \
    cuda-compat-10-1 \
    && ln -s cuda-10.1 /usr/local/cuda && \
    rm -rf /var/lib/apt/lists/*

# Required for nvidia-docker v1
RUN echo "/usr/local/nvidia/lib" >> /etc/ld.so.conf.d/nvidia.conf && \
    echo "/usr/local/nvidia/lib64" >> /etc/ld.so.conf.d/nvidia.conf

ENV PATH /usr/local/nvidia/bin:/usr/local/cuda/bin:${PATH}
ENV LD_LIBRARY_PATH /usr/local/nvidia/lib:/usr/local/nvidia/lib64


###########################################################################
#runtime next
ENV NCCL_VERSION 2.7.8

RUN apt-get update && apt-get install -y --no-install-recommends \
    cuda-libraries-$CUDA_PKG_VERSION \
    cuda-npp-$CUDA_PKG_VERSION \
    cuda-nvtx-$CUDA_PKG_VERSION \
    libcublas10=10.2.1.243-1 \
    libnccl2=$NCCL_VERSION-1+cuda10.1 \
    && apt-mark hold libnccl2 \
    && rm -rf /var/lib/apt/lists/*

# apt from auto upgrading the cublas package. See https://gitlab.com/nvidia/container-images/cuda/-/issues/88
RUN apt-mark hold libcublas10


###########################################################################
#cudnn7 (not cudnn8) next

ENV CUDNN_VERSION 7.6.5.32

RUN apt-get update && apt-get install -y --no-install-recommends \
    libcudnn7=$CUDNN_VERSION-1+cuda10.1 \
    && apt-mark hold libcudnn7 && \
    rm -rf /var/lib/apt/lists/*


ENV NVIDIA_VISIBLE_DEVICES all
ENV NVIDIA_DRIVER_CAPABILITIES all
ENV NVIDIA_REQUIRE_CUDA "cuda>=10.1"


###########################################################################
#docker build -t sidazhou/scipy-notebook-gpu:latest .

#docker run -itd -gpus all\
#  -p 8888:8888 \
#  -p 6006:6006 \
#  --user root \
#  -e NB_UID=$(id -u) \
#  -e NB_GID=$(id -g) \
#  -e GRANT_SUDO=yes \
#  -v ~/workspace:/home/jovyan/work \
#  --name sidazhou-jupyter-gpu \
#  sidazhou/scipy-notebook-gpu:latest

#docker exec sidazhou-jupyter-gpu python -c "import tensorflow as tf; print(tf.config.experimental.list_physical_devices('GPU'))"