今回は NVIDIA Container Toolkit を使って Docker コンテナから Docker ホストの GPU を使う方法について書く。 これまで Docker コンテナで GPU を使う方法は、nvidia-docker と nvidia-docker2 という二つの世代を経てきた。 それも、ここに来てやっと一息ついたかな、という印象がある。 GPU の基本的なサポートが Docker 本体側に取り込まれて (v19.03 以降)、GPU ベンダーはそのドライバを提供する形に落ち着いた。 そして、従来の nvidia-docker2 は非推奨 (Deprecated) な方法となっている。
なお、GPU ベンダーがドライバを提供する、と前述した通り NVIDIA のリソースが一切不要になったわけではない。 そのため、インストール手順やインターフェースの使い勝手という観点では nvidia-docker2 から大して変わっていない、というのが実状ではあるだろう。
使った環境は次の通り。
$ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=18.04 DISTRIB_CODENAME=bionic DISTRIB_DESCRIPTION="Ubuntu 18.04.3 LTS" $ uname -r 4.15.0-1044-gcp $ lspci -vv | grep -i nvidia 00:04.0 3D controller: NVIDIA Corporation Device 1eb8 (rev a1) Subsystem: NVIDIA Corporation Device 12a2 Kernel modules: nvidiafb $ sudo docker version Client: Docker Engine - Community Version: 19.03.2 API version: 1.40 Go version: go1.12.8 Git commit: 6a30dfc Built: Thu Aug 29 05:29:11 2019 OS/Arch: linux/amd64 Experimental: false Server: Docker Engine - Community Engine: Version: 19.03.2 API version: 1.40 (minimum version 1.12) Go version: go1.12.8 Git commit: 6a30dfc Built: Thu Aug 29 05:27:45 2019 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.2.6 GitCommit: 894b81a4b802e4eb2a91d1ce216b8817763c29fb runc: Version: 1.0.0-rc8 GitCommit: 425e105d5a03fabd737a126ad93d62a9eeede87f docker-init: Version: 0.18.0 GitCommit: fec3683
もくじ
- もくじ
- Docker をインストールする
- NVIDIA Graphics Driver をインストールする
- NVIDIA Container Toolkit をインストールする
- インストール後の確認作業
- Docker コンテナから GPU を使ってみる
- Docker Compose の対応について
- 補足
Docker をインストールする
まずは Docker をインストールする。
必要なパッケージをインストールしておく。
$ sudo apt -y install \ apt-transport-https \ ca-certificates \ curl \ gnupg-agent \ software-properties-common
Docker のリポジトリを APT に登録する。
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - $ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" $ sudo apt update
そして、Docker のコンポーネントをインストールする。
$ sudo apt -y install docker-ce docker-ce-cli containerd.io $ sudo docker version Client: Docker Engine - Community Version: 19.03.2 API version: 1.40 Go version: go1.12.8 Git commit: 6a30dfc Built: Thu Aug 29 05:29:11 2019 OS/Arch: linux/amd64 Experimental: false Server: Docker Engine - Community Engine: Version: 19.03.2 API version: 1.40 (minimum version 1.12) Go version: go1.12.8 Git commit: 6a30dfc Built: Thu Aug 29 05:27:45 2019 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.2.6 GitCommit: 894b81a4b802e4eb2a91d1ce216b8817763c29fb runc: Version: 1.0.0-rc8 GitCommit: 425e105d5a03fabd737a126ad93d62a9eeede87f docker-init: Version: 0.18.0 GitCommit: fec3683
NVIDIA Graphics Driver をインストールする
続いて Docker ホストに NVIDIA の Graphics Driver をインストールする。
ドライバのリポジトリを APT に登録する。
$ sudo add-apt-repository ppa:graphics-drivers/ppa $ sudo apt update
推奨されているドライバをインストールする。
$ sudo apt -y install ubuntu-drivers-common $ sudo ubuntu-drivers autoinstall
NVIDIA Container Toolkit をインストールする
次に Docker ホストに NVIDIA Container Toolkit をインストールする。 この中に Docker で NVIDIA の GPU を使うのに必要なランタイムなどが含まれている。
まずはリポジトリを APT に登録する。
$ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - $ curl -s -L https://nvidia.github.io/nvidia-docker/$(. /etc/os-release;echo $ID$VERSION_ID)/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list $ sudo apt update
その上でツールキットをインストールする。
$ sudo apt -y install nvidia-container-toolkit
ここまで終わったら、一旦マシンを再起動しておく。
$ sudo shutdown -r now
インストール後の確認作業
まずは nvidia-container-cli info
コマンドを使って、ちゃんと GPU が認識できていることを確認しよう。
また、同時に使用できるドライバと CUDA のバージョンが確認できる。
$ nvidia-container-cli info NVRM version: 435.21 CUDA version: 10.1 Device Index: 0 Device Minor: 0 Model: Tesla T4 Brand: Tesla GPU UUID: GPU-bcf7de51-87c5-4b98-f8c1-b1a9072696ca Bus Location: 00000000:00:04.0 Architecture: 7.5
ちなみに nvidia-container-cli list
を使うと Docker コンテナ側に注入されるファイル一覧が確認できる。
これらのファイルがコンテナからアクセスできるようになることで GPU が使えるようになる。
$ nvidia-container-cli list /dev/nvidiactl /dev/nvidia-uvm /dev/nvidia-uvm-tools /dev/nvidia-modeset /dev/nvidia0 /usr/bin/nvidia-smi /usr/bin/nvidia-debugdump /usr/bin/nvidia-persistenced /usr/bin/nvidia-cuda-mps-control /usr/bin/nvidia-cuda-mps-server /usr/lib/x86_64-linux-gnu/libnvidia-ml.so.435.21 /usr/lib/x86_64-linux-gnu/libnvidia-cfg.so.435.21 /usr/lib/x86_64-linux-gnu/libcuda.so.435.21 /usr/lib/x86_64-linux-gnu/libnvidia-opencl.so.435.21 /usr/lib/x86_64-linux-gnu/libnvidia-ptxjitcompiler.so.435.21 /usr/lib/x86_64-linux-gnu/libnvidia-fatbinaryloader.so.435.21 /usr/lib/x86_64-linux-gnu/libnvidia-compiler.so.435.21 /usr/lib/x86_64-linux-gnu/libnvidia-encode.so.435.21 /usr/lib/x86_64-linux-gnu/libnvidia-opticalflow.so.435.21 /usr/lib/x86_64-linux-gnu/libnvcuvid.so.435.21 /usr/lib/x86_64-linux-gnu/libnvidia-eglcore.so.435.21 /usr/lib/x86_64-linux-gnu/libnvidia-glcore.so.435.21 /usr/lib/x86_64-linux-gnu/libnvidia-tls.so.435.21 /usr/lib/x86_64-linux-gnu/libnvidia-glsi.so.435.21 /usr/lib/x86_64-linux-gnu/libnvidia-fbc.so.435.21 /usr/lib/x86_64-linux-gnu/libnvidia-ifr.so.435.21 /usr/lib/x86_64-linux-gnu/libnvidia-rtcore.so.435.21 /usr/lib/x86_64-linux-gnu/libnvoptix.so.435.21 /usr/lib/x86_64-linux-gnu/libGLX_nvidia.so.435.21 /usr/lib/x86_64-linux-gnu/libEGL_nvidia.so.435.21 /usr/lib/x86_64-linux-gnu/libGLESv2_nvidia.so.435.21 /usr/lib/x86_64-linux-gnu/libGLESv1_CM_nvidia.so.435.21 /usr/lib/x86_64-linux-gnu/libnvidia-glvkspirv.so.435.21 /run/nvidia-persistenced/socket
Docker コンテナから GPU を使ってみる
それでは、実際に Docker コンテナから GPU を使ってみることにしよう。
まずは、特に何もケアせずに Ubuntu のコンテナを起動して nvidia-smi
コマンドを実行してみる。
$ sudo docker run \ --rm \ -it ubuntu \ nvidia-smi docker: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "exec: \"nvidia-smi\": executable file not found in $PATH": unknown.
プレーンな Ubuntu のコンテナには、NVIDIA の GPU を扱うためのファイル群が含まれていない。 そのため、この実行は上記の通り失敗に終わる。
続いては --gpus
オプションを指定して同じコマンドを実行してみよう。
すると、次のようにちゃんとコマンドの実行が成功する。
$ sudo docker run \ --rm \ --gpus all \ -it ubuntu \ nvidia-smi Sun Sep 22 05:31:27 2019 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 435.21 Driver Version: 435.21 CUDA Version: N/A | |-------------------------------+----------------------+----------------------+ | 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 T4 Off | 00000000:00:04.0 Off | 0 | | N/A 44C P0 26W / 70W | 0MiB / 15109MiB | 0% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | No running processes found | +-----------------------------------------------------------------------------+
同じように CentOS のイメージでも動作するか確認してみよう。 こちらも上手くいく。
$ sudo docker run \ --rm \ --gpus all \ -it centos \ nvidia-smi Sun Sep 22 06:10:59 2019 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 435.21 Driver Version: 435.21 CUDA Version: N/A | |-------------------------------+----------------------+----------------------+ | 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 T4 Off | 00000000:00:04.0 Off | 0 | | N/A 71C P0 32W / 70W | 0MiB / 15109MiB | 0% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | No running processes found | +-----------------------------------------------------------------------------+
上記から、もはや NVIDIA が提供している公式イメージも必須ではなくなったことがわかる。
上記は、前述した通り必要なファイルがコンテナからアクセスできるようになることで実現されている。
まず、何もオプションを付けずに実行したときの /usr/lib/x86_64-linux-gnu/
ディレクトリを確認してみよう。
$ sudo docker run \ --rm \ -it ubuntu \ ls /usr/lib/x86_64-linux-gnu/ audit libgnutls.so.30 libpanelw.so.5 coreutils libgnutls.so.30.14.10 libpanelw.so.5.9 gconv libhogweed.so.4 libpcreposix.so.3 libapt-pkg.so.5.0 libhogweed.so.4.4 libpcreposix.so.3.13.3 libapt-pkg.so.5.0.2 libidn2.so.0 libsemanage.so.1 libapt-private.so.0.0 libidn2.so.0.3.3 libstdc++.so.6 libapt-private.so.0.0.0 liblz4.so.1 libstdc++.so.6.0.25 libdb-5.3.so liblz4.so.1.7.1 libtasn1.so.6 libdebconfclient.so.0 libmenu.so.5 libtasn1.so.6.5.5 libdebconfclient.so.0.0.0 libmenu.so.5.9 libtic.so.5 libffi.so.6 libmenuw.so.5 libtic.so.5.9 libffi.so.6.0.4 libmenuw.so.5.9 libunistring.so.2 libform.so.5 libnettle.so.6 libunistring.so.2.1.0 libform.so.5.9 libnettle.so.6.4 libzstd.so.1 libformw.so.5 libp11-kit.so.0 libzstd.so.1.3.3 libformw.so.5.9 libp11-kit.so.0.3.0 perl libgmp.so.10 libpanel.so.5 perl-base libgmp.so.10.3.2 libpanel.so.5.9
特に GPU 関連のファイルが含まれている形跡はない。
続いて --gpus
オプションをつけて同じコマンドを実行してみよう。
$ sudo docker run \ --rm \ --gpus all \ -it ubuntu \ ls /usr/lib/x86_64-linux-gnu/ audit libgnutls.so.30.14.10 libpanel.so.5 coreutils libhogweed.so.4 libpanel.so.5.9 gconv libhogweed.so.4.4 libpanelw.so.5 libapt-pkg.so.5.0 libidn2.so.0 libpanelw.so.5.9 libapt-pkg.so.5.0.2 libidn2.so.0.3.3 libpcreposix.so.3 libapt-private.so.0.0 liblz4.so.1 libpcreposix.so.3.13.3 libapt-private.so.0.0.0 liblz4.so.1.7.1 libsemanage.so.1 libdb-5.3.so libmenu.so.5 libstdc++.so.6 libdebconfclient.so.0 libmenu.so.5.9 libstdc++.so.6.0.25 libdebconfclient.so.0.0.0 libmenuw.so.5 libtasn1.so.6 libffi.so.6 libmenuw.so.5.9 libtasn1.so.6.5.5 libffi.so.6.0.4 libnettle.so.6 libtic.so.5 libform.so.5 libnettle.so.6.4 libtic.so.5.9 libform.so.5.9 libnvidia-cfg.so.1 libunistring.so.2 libformw.so.5 libnvidia-cfg.so.435.21 libunistring.so.2.1.0 libformw.so.5.9 libnvidia-ml.so.1 libzstd.so.1 libgmp.so.10 libnvidia-ml.so.435.21 libzstd.so.1.3.3 libgmp.so.10.3.2 libp11-kit.so.0 perl libgnutls.so.30 libp11-kit.so.0.3.0 perl-base
すると、libnvidia-*
といった GPU 関連の共有ライブラリが確認できるようになる。
Docker Compose の対応について
残念なお知らせだけど、まだ現時点 (2019/09/22) では Docker Compose が上記の --gpus
オプションに対応できていない。
$ sudo apt -y install python3-pip $ sudo pip3 install docker-compose $ docker-compose version docker-compose version 1.24.1, build 4667896 docker-py version: 3.7.3 CPython version: 3.6.8 OpenSSL version: OpenSSL 1.1.1 11 Sep 2018
Docker Compose と一緒に万全の体制で使うには、もう少し時間を必要としそうだ。
Support for NVIDIA GPUs under Docker Compose · Issue #6691 · docker/compose · GitHub
補足
今回使った GPU マシン環境は次のようにして用意した。
$ gcloud compute instances create gcp-gpu-t4-x1 \ --preemptible \ --zone us-central1-a \ --machine-type n1-standard-2 \ --accelerator type=nvidia-tesla-t4,count=1 \ --maintenance-policy TERMINATE \ --restart-on-failure \ --image-project ubuntu-os-cloud \ --image-family ubuntu-1804-lts
いじょう。
- 作者:もみじあめ
- 発売日: 2020/02/29
- メディア: Kindle版