nvidia-docker2を試してみる


nvidia-dockerが正式にリリースされたのは2017年1月。コンテナにGPUを簡単に利用できるのはその利点の一つ。もう一つはホストに複数のGPUを搭載した際に、特定数または単独なGPUをコンテナ内に利用可能となります。しかしこのplug-inとdocker daemonは別々に取り組む、使用上に少々制限されてる。
2017年の年末に近い11月、nvidia-docker2がついにリリースされました。
説明によると、要点が三つがあると思う。
1. dockerにnvidia-dockerを組み込んた、別々のdaemonは必要ない。
2. 従来バージョンとの互換性。
3. イメージはCUDA無くとも、コンテナ内にGPUも利用できます。

とりあえず設置の流れをメモして、加えて気になる機能を試してみましょう。

システム配置

  • ubuntu 16.04
  • dockerインストール済
  • nvidiaドライバインストール済

nvidia-docker2を導入

レポジトリ追加

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

nvidia-docker2をインストール

nvidia-docker2は現時点でまたすべてのdockerバージョンにサポートされていないため、nvidia-docker2をインストールする前に、まずdockerバージョンを確認して、必要であれば対応バージョンに更新する。

dockerバージョン確認
ishouyou@emerald:~$ docker --version
Docker version 1.12.5, build 7392c3b
サーポートバージョン確認
ishouyou@emerald:~$ sudo apt-cache madison nvidia-docker2 nvidia-container-runtime
...
nvidia-docker2 | 2.0.1+docker1.12.6-1 | https://nvidia.github.io/nvidia-docker/ubuntu16.04/amd64  Packages
...
nvidia-container-runtime | 1.1.0+docker1.12.6-1 | https://nvidia.github.io/nvidia-container-runtime/ubuntu16.04/amd64  Packages
...
対応dockerバージョンに更新
ishouyou@emerald:~$ sudo apt-cache madison docker-engine
ishouyou@emerald:~$ sudo apt-get install docker-engine=1.12.6-0~ubuntu-xenial
ishouyou@emerald:~$ sudo pkill -SIGHUP dockerd

もしホストにnvidia-docker v1.0がインストールされていて、またはnvidia-docker daemonで追加されたコンテナがある場合、そのコンテナを一旦消去して、nvidai-docker 1.0をパージします。

nvidai-dockerをパージする
ishouyou@emerald:~$ docker volume ls -q -f driver=nvidia-docker | xargs -r -I{} -n1 docker ps -q -a -f volume={} | xargs -r docker rm -f
ishouyou@emerald:~$ sudo apt-get purge nvidia-docker
nvidia-docker2とnvidia-container-runtimeをインストールする
ishouyou@emerald:~$ sudo apt-get install -y nvidia-docker2=2.0.1+docker1.12.6-1 nvidia-container-runtime=1.1.0+docker1.12.6-1
ishouyou@emerald:~$ sudo pkill -SIGHUP dockerd

ここでnvidia-docker2のインストールは完了です。

nvidia-docker2の使用方法

使い方は変わりますが、互換性はバッチリですから、v1.0に慣れた人に同じの使用方法も通じます。

従来nvidia-dockerの使い例
NV_GPU='0' nvidia-docker run --rm nvidia/cuda nvidia-smi

nvidia-docker2は上記のコメンドを自動転換して、下記のようになります。

nvidia-docker2の使い例
docker run --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=0 --rm nvidia/cuda:8.0-cudnn6-devel-ubuntu16.04 nvidia-smi

CUDAなしのイメージでも使える

ホストにインストールされたCUDAバージョンをコンテナにアクセスことができます。

GPU使用できるのコンテナ作成例
docker run --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=0 --rm busybox:latest nvidia-smi

nvidia-docker2とrancherの組み合わせ

docker daemonを設置

docker daemonデバッグモードで試す

dockerデバッグモードを作動する
sudo systemctl stop docker
sudo dockerd -D --default-runtime=nvidia
dockerd
...
DEBU[0004] attach: stdout: end
DEBU[0004] attach: stderr: end
DEBU[0004] Calling POST /v1.22/containers/91af6039e0ab33376fb04a16a5743f75957
66ff2e06a923f0d4454c954032328/wait
DEBU[0004] Calling GET /v1.22/containers/91af6039e0ab33376fb04a16a5743f759576
6ff2e06a923f0d4454c954032328/json
DEBU[0004] Calling DELETE /v1.22/containers/91af6039e0ab33376fb04a16a5743f759
5766ff2e06a923f0d4454c954032328?v=1
DEBU[0004] Calling GET /v1.22/containers/rancher-agent/json
DEBU[0006] Calling GET /v1.22/info
DEBU[0006] Calling GET /v1.22/version
DEBU[0006] Calling GET /v1.22/info
DEBU[0006] Calling GET /v1.22/containers/json?all=1&filters=%7B%22status%22%3
A%7B%22paused%22%3Atrue%2C%22running%22%3Atrue%7D%7D&limit=0
DEBU[0006] Calling GET /v1.22/events
DEBU[0007] Calling GET /v1.22/containers/json?all=1&limit=0
DEBU[0013] Calling GET /v1.22/containers/json?all=1&limit=0
DEBU[0013] Calling GET /v1.22/containers/a108a5f2c630df4ec6644d4eeae10834612c
15a6a2780b6c9cc7513955eee905/json
DEBU[0013] Calling GET /v1.22/containers/json?all=1&limit=0
DEBU[0013] Calling POST /v1.22/containers/a108a5f2c630df4ec6644d4eeae10834612
c15a6a2780b6c9cc7513955eee905/start
...

コンテナを追加

Rancher Web UIから見ると、ホストの配置はほぼ丸見えです。(IPアドレスの部分は隠させていただきます。)

ホスト側で
ishouyou@ubuntu:~$ nvidia-smi
Thu Dec  7 18:54:30 2017
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 384.66                 Driver Version: 384.66                    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla P4            Off  | 00000000:04:00.0 Off |                    0 |
| N/A   28C    P0    23W /  75W |      0MiB /  7606MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  Tesla P4            Off  | 00000000:83:00.0 Off |                    0 |
| N/A   30C    P0    23W /  75W |      0MiB /  7606MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID  Type  Process name                               Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

Web UIからコンテナを追加するのはこんな感じです。

特に注意すべきのは、その変数です。NVIDIA_VISIBLE_DEVICESはGPUを設置するnvidia-docker2の変数です。

NVIDIA_VISIBLE_DEVICESの変数に、値の部分は0が書いてのはGPU 0を利用する。もし全部のGPUが使いたい時、allに記入します。
作成ボタンを押して、GPU利用可能なコンテナを作成することが始めます。
コンテナ作成完了の後、コンソールで確認。

コンテナの中に入る
ishouyou@ubuntu:~$ docker exec -it r-hoge_gpu_0-7e8ff0a0 bash
root@c3a336340dad:/# nvidia-smi
Thu Dec  7 19:01:25 2017
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 384.66                 Driver Version: 384.66                    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla P4            Off  | 00000000:04:00.0 Off |                    0 |
| N/A   28C    P0    23W /  75W |      0MiB /  7606MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID  Type  Process name                               Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

dockerデバッグモードで試し終わりましたら、デバッグモードを終了し、docker daemon設定に書き込む。

docker daemonに設置

daemon.json
{
    "runtimes": {
        "nvidia": {
            "path": "/usr/bin/nvidia-container-runtime",
            "runtimeArgs": []
        }
    },
    "default-runtime": "nvidia"
}
dockerdを再起動する
sudo pkill -SIGHUP dockerd