DockerでPythonによるデータ分析環境を作る

提供: Eospedia
2019年5月14日 (火) 05:25時点におけるKttn (トーク | 投稿記録)による版

移動: 案内検索

Dockerとは

  • あまりうまいこと説明できないのでググってください。
  • CUIベースで(GUIアプリも使えるけど)、スクリプト(Dockerfile)で環境構築でき、オーバーヘッドの少ない仮想環境程度の気持ちで使っています。
  • Dockerfileや構築済みのDockerイメージさえあれば、どのマシンでも(ほぼ)同じ環境を構築できるため、色々なマシンで作業したり他人と作業環境を共有したい場合に便利です。もちろん環境を切り分け管理できることが最大の利点です。

実行環境

Ubuntu 16.04.6 LTS

  • 3.6 GHz Intel Xeon E5-1650
  • 64 GB 2133 MHz DDR4
  • NVIDIA GeForce GTX 1080 8 GB x 4台
    • Driverバージョン 418.74
    • CUDAバージョン 10.1

インストール

Docker

  • 公式の手順に従う。
  • 一応打ったコマンドを記載しておく。(2019年5月14日)


  • 古いバージョンのDockerが入っているので、削除する。
$ sudo apt remove docker docker-engine docker.io containerd runc

以下のようなエラーが出た。

パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
パッケージ 'docker-engine' はインストールされていないため削除もされません
パッケージ 'docker' はインストールされていないため削除もされません
パッケージ 'containerd' はインストールされていないため削除もされません
パッケージ 'docker.io' はインストールされていないため削除もされません
パッケージ 'runc' はインストールされていないため削除もされません

確かにDockerはインストールされているのだが。Dockerの.debファイルをdpkgでインストールしたから?


  • 別の方法試した。
$ sudo dpkg --purge docker-ce

これでアンインストールできた。


  • パッケージインデックスのアップデート
$ sudo apt update


  • (インストール済みなことはわかりつつも一応)HTTPS越しでリポジトリを使うために必要なパッケージのインストール
$ sudo apt-get install \
   apt-transport-https \
   ca-certificates \
   curl \
   gnupg-agent \
   software-properties-common


  • DockerのGPG鍵(リポジトリからダウンロードしたパッケージが正しい配布先のものか検証するために使う公開鍵)を登録する
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -


  • GPG鍵がきちんと登録できたかチェックする(GPG鍵の下8桁で検索)
$ sudo apt-key fingerprint 0EBFCD88
pub   4096R/0EBFCD88 2017-02-22
      フィンガー・プリント = 9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
uid                  Docker Release (CE deb) <docker@docker.com>
sub   4096R/F273FCD8 2017-02-22

フィンガー・プリントが"9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88"なら、Docker公式リポジトリの鍵を登録できている。


  • x86_64, stable版のDockerリポジトリを追加する。
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"


  • パッケージインデックスの更新
$ sudo apt update
ヒット:1 http://jp.archive.ubuntu.com/ubuntu xenial InRelease
ヒット:2 http://jp.archive.ubuntu.com/ubuntu xenial-updates InRelease                                            
ヒット:3 http://jp.archive.ubuntu.com/ubuntu xenial-backports InRelease                                          
ヒット:4 http://security.ubuntu.com/ubuntu xenial-security InRelease                                   
取得:5 https://download.docker.com/linux/ubuntu xenial InRelease [66.2 kB]
取得:6 https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages [8,482 B] 
ヒット:7 http://ppa.launchpad.net/graphics-drivers/ppa/ubuntu xenial InRelease

Dockerのパッケージインデックスを読み込めている。


  • インストール
$ sudo apt-get install docker-ce docker-ce-cli containerd.io


# dockerユーザーグループの作成
$ sudo groupadd docker
# ユーザーをdockerグループへ追加
$ sudo usermod -aG docker <ユーザー名>


  • 動作テスト - Hello Worldコンテナの実行 -
$ docker run hello-world

出力は以下。

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete 
Digest: sha256:5f179596a7335398b805f036f7e8561b6f0e32cd30a32f5e19d17a3cda6cc33d
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

こんにちは。


$ sudo systemctl enable docker
Synchronizing state of docker.service with SysV init with /lib/systemd/systemd-sysv-install...
Executing /lib/systemd/systemd-sysv-install enable docker

NVIDIA Docker

  • https://github.com/NVIDIA/nvidia-docker
    • ホストマシンのNvidia GPUデバイスとGPUドライバをDockerコンテナ内から使える様にする。
    • Dockerコンテナの"ランタイム"の一種のようだが、ランタイムとは何なのかがよくわからない。Dockerの拡張機能的なものだと(勝手に)思って使っている。
    • GPUドライバはホストマシンのものに限定されるが、CUDAやcuDNNなどのライブラリはコンテナ内で好き勝手使えるため、CUDAバージョンごとでコンテナを分けて開発、作業したりできる。



  • GPG鍵の登録
$ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey |   sudo apt-key add -


  • リポジトリを追加
$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
$ curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \
   sudo tee /etc/apt/sources.list.d/nvidia-docker.list

/etc/apt/sources.list.d/nvidia-docker.listの中身はこんな感じ

deb https://nvidia.github.io/libnvidia-container/ubuntu16.04/$(ARCH) /
deb https://nvidia.github.io/nvidia-container-runtime/ubuntu16.04/$(ARCH) /
deb https://nvidia.github.io/nvidia-docker/ubuntu16.04/$(ARCH) /


  • パッケージインデックスの取得
$ sudo apt update

上記登録したリポジトリからインデックスを取得できています。

ヒット:1 http://jp.archive.ubuntu.com/ubuntu xenial InRelease
取得:2 http://jp.archive.ubuntu.com/ubuntu xenial-updates InRelease [109 kB]                                     
取得:3 http://jp.archive.ubuntu.com/ubuntu xenial-backports InRelease [107 kB]                                   
取得:4 https://nvidia.github.io/libnvidia-container/ubuntu16.04/amd64  InRelease [1,139 B]                       
取得:5 https://nvidia.github.io/nvidia-container-runtime/ubuntu16.04/amd64  InRelease [1,136 B]                  
取得:6 https://nvidia.github.io/nvidia-docker/ubuntu16.04/amd64  InRelease [1,129 B]                             
ヒット:7 https://download.docker.com/linux/ubuntu xenial InRelease                                               
取得:8 https://nvidia.github.io/libnvidia-container/ubuntu16.04/amd64  Packages [6,712 B]
取得:9 https://nvidia.github.io/nvidia-container-runtime/ubuntu16.04/amd64  Packages [7,588 B]
ヒット:10 http://ppa.launchpad.net/graphics-drivers/ppa/ubuntu xenial InRelease                
取得:11 https://nvidia.github.io/nvidia-docker/ubuntu16.04/amd64  Packages [7,684 B] 
取得:12 http://security.ubuntu.com/ubuntu xenial-security InRelease [109 kB]
取得:13 http://security.ubuntu.com/ubuntu xenial-security/main amd64 DEP-11 Metadata [68.0 kB]
取得:14 http://security.ubuntu.com/ubuntu xenial-security/main DEP-11 64x64 Icons [67.0 kB]
取得:15 http://security.ubuntu.com/ubuntu xenial-security/universe amd64 DEP-11 Metadata [116 kB]
取得:16 http://security.ubuntu.com/ubuntu xenial-security/universe DEP-11 64x64 Icons [173 kB]
取得:17 http://security.ubuntu.com/ubuntu xenial-security/multiverse amd64 DEP-11 Metadata [2,464 B]


  • NVIDIA Dockerのインストール
$ sudo apt install -y nvidia-docker2


  • 一旦Dockerデーモンを停止。次回起動する時に新しい設定を読み込ませるための処置みたい。
$ sudo pkill -SIGHUP dockerd


  • 動作テスト -NVIDIA Dockerを使ってDockerコンテナを起動し、その中でnvidia-smiコマンドを起動し、出力をホストマシンのコンソールへ戻す-
$ docker run --runtime=nvidia --rm nvidia/cuda:9.0-base nvidia-smi

出力

Unable to find image 'nvidia/cuda:9.0-base' locally
9.0-base: Pulling from nvidia/cuda
34667c7e4631: Pull complete 
d18d76a881a4: Pull complete 
119c7358fbfc: Pull complete 
2aaf13f3eff0: Pull complete 
4d96b2dafaa5: Pull complete 
f8c41b380cab: Pull complete 
d2c1b4858446: Pull complete 
Digest: sha256:0afacc402b0eb2333d1075d051e237710483b29cdd51c4e7de5d60be4cb1468f
Status: Downloaded newer image for nvidia/cuda:9.0-base
docker: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "process_linux.go:424: container init caused \"process_linux.go:407: running prestart hook 1 caused \\\"error running hook: exit status 1, stdout: , stderr: exec command: [/usr/bin/nvidia-container-cli --load-kmods configure --ldconfig=@/sbin/ldconfig.real --device=all --compute --utility --require=cuda>=9.0 --pid=12852  /var/lib/docker/aufs/mnt/7ebf9cc5554558f39056930a1eeb8e5a5751db71c5db608960e4bf4a9ee10921]\\\\nnvidia-container-cli: initialization error: cuda error: no cuda-capable device is detected\\\\n\\\"\"": unknown.

えー...


$ ls -l /dev/nvidia*
crw-rw---- 1 root vglusers 195, 254  5月 12 21:24 /dev/nvidia-modeset
crw-rw-rw- 1 root root     241,   0  5月 14 14:03 /dev/nvidia-uvm
crw-rw-rw- 1 root root     241,   1  5月 14 14:03 /dev/nvidia-uvm-tools
crw-rw---- 1 root vglusers 195,   0  5月 12 21:24 /dev/nvidia0
crw-rw---- 1 root vglusers 195,   1  5月 12 21:24 /dev/nvidia1
crw-rw---- 1 root vglusers 195,   2  5月 12 21:24 /dev/nvidia2
crw-rw---- 1 root vglusers 195,   3  5月 12 21:24 /dev/nvidia3
crw-rw---- 1 root vglusers 195, 255  5月 12 21:24 /dev/nvidiactl

GPUデバイスの所有者はrootだが、グループがvglusersになっていることが問題の様。


Nvidia Dockerの設定ファイル /etc/nvidia-container-runtime/config.toml に、以下の行を追加すればいい様。

user = "root:vglusers"


再度実行してみる

$ docker run --runtime=nvidia --rm nvidia/cuda:9.0-base nvidia-smi
Tue May 14 05:19:30 2019       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 418.74       Driver Version: 418.74       CUDA Version: 10.1     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GTX 1080    Off  | 00000000:05:00.0  On |                  N/A |
| 29%   44C    P8     7W / 180W |     37MiB /  8119MiB |      1%      Default | 
+-------------------------------+----------------------+----------------------+
|   1  GeForce GTX 1080    Off  | 00000000:06:00.0 Off |                  N/A |
| 28%   41C    P8     6W / 180W |      2MiB /  8119MiB |      1%      Default | 
+-------------------------------+----------------------+----------------------+
|   2  GeForce GTX 1080    Off  | 00000000:09:00.0 Off |                  N/A |
| 27%   36C    P8     6W / 180W |      2MiB /  8119MiB |      1%      Default |
+-------------------------------+----------------------+----------------------+
|   3  GeForce GTX 1080    Off  | 00000000:0A:00.0 Off |                  N/A |
| 27%   37C    P8     6W / 180W |      2MiB /  8119MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================| 
+-----------------------------------------------------------------------------+

はい、動きました。

イメージ構築

コンテナ起動

コンテナ内のJupyterサーバーにリモートからアクセスする