この記事はnvidia-docker v1.0の仕様を説明しています。現在の最新版はnvidia-docker2であり、この記事の仕組みでは動いていません。
nvidia-dockerのwikiにかいてあった
nvidia-dockerとは?
nvidia-dockerを使うとdockerコンテナ内部から簡単にNVIDIAのGPUを使うことができる。
$ nvidia-docker run --rm nvidia/cuda nvidia-smi
nvidia-dockerを使うことによって、GPUのドライバとCUDA/cuDNNの関係を疎にしてあげる事ができる。結果として、ひとつのホスト上で複数のCUDA/cuDNNのバージョンのコンテナを動かす事ができ、CUDA/cuDNNを使っているコンテナのポータビリティがあがるらしい。
どうやって動いてるの?
nvidia-dockerは大まかにいうと、実行したいコンテナ内からGPUにアクセスできるようにDocker Engine APIに色々なパラメータを指定してあげてコンテナを起動している。GPU関連の情報を取得できるようにnvidia-docker-pluginっていうGPU関連の情報をHTTPのサーバが立っている。
なので,nvidia-dockerコマンド経由でなくても、通常のdockerコマンドから、GPUを利用するdockerコンテナを動かす事もできる。(volume plugin機能も提供しているみたいなので、インストール自体は必要っぽい。)
オプションの付与
nvidia-docker経由でコマンドを実行したときの処理の流れ
$ nvidia-docker run --rm nvidia/cuda nvidia-smi
- nvidia-dockerがコマンドをうけとる
- nvidia-dockerがnvidia-docker-pluginへホスト側のGPUに関連する情報を問い合わせる
- nvidia-dockerは受け取った情報を元に、docker-engineへ渡すべきオプションを生成する
- nvidia-dockerはdocker-engineのAPIをオプション付きで呼び出してコンテナを立ち上げる
nvidia-docker-plugin
REST API
以下のエンドポイントがある。
GET /v1.0/gpu/info, /v1.0/gpu/info/json
GET /v1.0/gpu/status, /v1.0/gpu/status/json
GET /v1.0/docker/cli, /v1.0/docker/cli/json
GET /v1.0/mesos/cli
cliのAPIを叩いた時には、dockerにそのまま渡せるオプションを返してるらしい。
$ curl -s http://localhost:3476/docker/cli
--device=/dev/nvidiactl --device=/dev/nvidia-uvm --device=/dev/nvidia3 --device=/dev/nvidia2 --device=/dev/nvidia1 --device=/dev/nvidia0 --volume-driver=nvidia-docker --volume=nvidia_driver_361.48:/usr/local/nvidia:ro
nvidia-dockerはdockerエンジンに以下のオプションを渡している。
volume/volume-driver
ホスト側のnvidia driverをコンテナ側でもマウントさせている
device
ホスト側の/dev/nvidia*
に存在するデバイスファイルをコンテナ側に追加している
Dockerイメージの検証
nvidia-dockerはdockerエンジンのAPIを叩く前に、対象コンテナにGPUオプションを渡す必要があるか、コンテナを当該ホストで起動できるかを検証している。
GPUを使うコンテナかの検証
そもそも、nvidia-dockerコマンド経由で実行されようとしているdockerコンテナがGPUを使わなければ、nvidia driverやdeviceのマウントは必要ない。nvidia-dockerはDockerイメージのcom.nvidia.volumes.needed
ラベルを見て、そいつがGPUを使うコンテナか調べてる。
コンテナが当該ホストで実行ができるかの検証
CUDAのそれぞれのバージョンには最低限必要とするnvidia driverのバージョンが存在する。
nvidia-dockerはdockerコンテナを起動しようとする時に、ホスト側のnvidia driverのバージョンを見て、起動したいdockerイメージに含まれるCUDAのバージョンが動くか調べて、無理な時はコマンド実行時にエラーを返すらしい。
nvidia/cuda
を継承しているDockerイメージにはcom.nvidia.cuda.version
というラベルがついていて、dockerイメージにインストールされているCUDAのバージョンがわかるらしい。
まとめ
nvidia-dockerすごい