DockerコンテナーからGPUを使用していますか?


164

Dockerコンテナー内からGPUを使用する方法を探しています。

コンテナーは任意のコードを実行するため、特権モードを使用したくありません。

任意のヒント?

以前の調査から、run -vおよび/またはLXC cgroupが進むべき道であることがわかったが、それを正確に引き離す方法がわからない


必要に応じて、stackoverflow.com / questions / 17792161 /…を参照してください。
Nicolas Goy 2014

1
@NicolasGoyリンクは良かったが、セキュリティ上の理由で特権を使用できないため、それほど有用ではなかった。lxc-cgroupsは良いポインタでしたが、十分ではありませんでした。私は方法を見つけました、そしてすべてが磨かれるとき私は自己回答します。
リーガン2014

回答:


132

Reganの答えは素晴らしいですが、Dockerがdocker 0.9のデフォルトの実行コンテキストとしてLXC削除したため、これを行う正しい方法はlxc実行コンテキストを回避するため、少し古くなっています。

代わりに、-deviceフラグを介してnvidiaデバイスについてdockerに通知し、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をインストールするのですか?
MP0 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ライブラリの不一致が原因ですか?
ブルネット2014

1
わかりません。nvidiaフォーラムで質問してください。バージョンの不一致が問題であると想定すると、このDockerfileを取得してCUDA 5.5ドライバーを含むように編集し、それから新しいDockerイメージを再構築して使用できます。
tleyden 2014

3
イメージがnvidiaドライバーをインストールする必要がある理由を説明できますか?nvidiaドライバーをインストールするホスト(および--device ...を使用)だけで十分だと思いましたか?
Helin Wang

2
現在、Windowsをホストとして使用している場合、これを行う方法はありません。
Souradeep Nanda、

45

すでに存在する回答のほとんどは現在のところ廃止されているため、更新された回答を作成します。

Docker 19.03require nvidia-docker2および--runtime=nvidiaフラグを使用する以前のバージョン。

以降Docker 19.03nvidia-container-toolkitパッケージをインストールしてから--gpus allフラグを使用する必要があります。

だから、ここに基本があります、

パッケージのインストール

Githubの公式ドキュメントnvidia-container-toolkitに従ってパッケージをインストールします。

RedhatベースのOSの場合、次の一連のコマンドを実行します。

$ 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ベースのOSの場合、次の一連のコマンドを実行します。

# 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は、利用可能なすべてのgpusを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、

1
AWSのBatchジョブ内からこれを試したことがありますか?
medley56

1
私はこれが最も適切だと思います。Ubuntu 20.04で動作するようにgithub.com/NVIDIA/nvidia-dockerからの指示を調整する必要がありましたが、それをもっと早く見つけたかったのですが
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のインストールに使用したファイルを保持することが非常に重要です


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ドライバーを使用してイメージをビルドします。

以下は、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

結果が空白の場合は、ホストでサンプルの1つを起動して使用するとうまくいきます。結果は次のようになり ここに画像の説明を入力してください ます。ご覧のとおり、グループと日付の間に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 2014

1
Dockerには、--deviceコンテナーがホストのデバイスにアクセスすることを許可するオプションがあります。しかし、私は--device=/dev/nvidia0Dockerコンテナーがcudaを実行できるようにしようとして失敗しました。
Shiquanwang 2014年

4
私は、すべての露光で成功した/dev/nvidiao/dev/nvidia1/dev/nvidiactlおよび/dev/nvidia-uvm--device。理由はわかりませんが。
Shiquanwang 2014年

--deviceオプションは、この解決策を見つける必要があったときに実装されていませんでした。少なくともnvidia0またはnvidia1(グラフィックカード)とnvidiactl(一般的なnvidiaデバイス)およびnvidia-uvm(統合メモリデバイス)が必要です。
2014年

2
/dev/nvidia*@Reganのヒントをありがとう。@ChillarAnandのために、私はcuda-
shiquanwang 2014年

29

Dockerコンテナー内でNVIDIA GPUを使用するプロセスを容易にする、実験的なGitHubリポジトリをリリースしました。


4
Windowsのサポートはありますか?それはそうではないようですが、おそらく何かが足りません。
Blaze

6
Windowsのサポートはありません。CUDAコンテナーを実行するには、Linux用のNvidiaドライバー、および/ dev / nvidia0などのGPUを表すLinuxデバイスへのアクセスが必要です。これらのデバイスとドライバーは、DockerがWindowsにインストールされており、VirtualBox仮想マシン内で実行されている場合は使用できません。
パヴェルBylica

runコマンドで--device宣言が必要ですか?私はnvidia / cudaからコンテナーを構築しましたが、コンテナーは正常に動作しますが、アプリ(Wowza)はGPUを認識しませんが、ホスト(このホストなので、ドライバーは正常であることを知っています)で直接実行すると正常に動作します。361.28を実行しています。ホストは、g2.8xlarge上のNVidia AMIを使用するEC2です。
Rainabba 2016

すべてが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

詳細については、 GPU対応のDockerコンテナ およびhttps://github.com/NVIDIA/nvidia-dockerを参照してください。


すべてのステップを取得すると、これはうまく機能します。Nvidiaはすべてを1か所で提供するわけではありませんが、この例では、一般的なユースケースで動作させるために必要なすべてを提供します。
神戸ジョン2018

@KobeJohn-インストール手順、コマンドラインの使用方法、および私のコンテナがcudaのコンテナを継承することを確認しました。それだけでうまくいきます。
マット

1
実際、nvidia-dockerの使用が理にかなっている実際のシナリオを説明できますか?
サンキャッチャー、

@Suncatcher-3DレンダリングのためにGPUへのアクセスが必要なクラスターで使用しています。アプリをDocker化すると、展開と保守が簡単になります。
マット

17

ubuntu 16.04のcuda-8.0用に更新

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
林宗一

返信は遅くなりますが、そのマシンにGPUがない可能性があります
ジョナサン

Cuda-9バージョンはこれとほぼ同じですか?
フセイントゥグルルブキシク2017年

@huseyintugrulbuyukisik askubuntuにこの回答を参照askubuntu.com/questions/967332/...を、私はあなたがガイドとしてこの回答を使用することができます言うだろうが、私は、同じ手順が適用されることを確認するためのCUDA 9で働いていない
ジョナサン

このようにしないでください。これは古い方法です。新しい方法を使用します。私の回答へのリンクを参照してください。この方法には問題があります。
マット

3

ネイティブのDockerを使用する代わりに、DockerコンテナーからGPUを使用するには、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

1

mviereckによるx11dockerを使用します。

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

ハードウェアアクセラレーション

OpenGLのハードウェアアクセラレーションは、オプション-g、-gpuで可能です。

これは、ほとんどの場合、ホスト上のオープンソースドライバーでそのまま使用できます。それ以外の場合は、wiki:機能の依存関係をご覧ください。クローズドソースのNVIDIAドライバーは、いくつかの設定が必要で、サポートするx11docker Xサーバーオプションが少なくなります。

このスクリプトは、すべての構成とセットアップを処理するので非常に便利です。X上でgpuを使用してDockerイメージを実行するのは、

x11docker --gpu imagename
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.