概要
dockerによってkerasのgpuおよびjupyterlab環境構築をする。
dockerがどういうものか、dockerのインストール等は省略する。
またついでにport forwardingについて軽く解説する。
イメージのpull
tensorflowのdockerhubにてタグがlatest gpuのimageをpullする。
タグがlatestのみだとcudaが使えない。
やることは以下の通り
$ sudo docker pull tensorflow/tensorflow:latest-gpu
イメージの確認
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tensorflow/tensorflow latest-gpu 20fd065e3887 7 weeks ago 3.15GB
必要そうなモジュールとjupyterをインストール
インストールするモジュール
今回importするのは
- matplotlib
- cv2 (opencv-python)
- keras
- jupyter lab
インポートする前にdockerのコンテナをイメージから作成しておく。環境構築の際はrootで入る。
$ sudo docker run -it tensorflow/tensorflow:latest-gpu
pipとaptのアップデート
# pip install --upgrade pip
# apt-get update -y
opencvのインストールのための準備
以下を参照した
DockerでpythonのTensorFlowとOpenCVの実行環境を構築する
# apt-get install -y libopencv-dev
結構時間がかかる。
必要モジュールのインストール
# pip install matplotlib opencv-python keras
# pip install jupyterlab
モジュールがimportできるかテスト
# python
Python 3.6.9 (default, Jul 17 2020, 12:50:27)
[GCC 8.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import matplotlib
>>> import numpy
>>> import cv2
>>> import keras
2020-09-20 01:02:34.313977: I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library libcudart.so.10.1
>>> import tensorflow
大丈夫そうだ。
Ctrl + d
で対話モードを抜けられる。
jupyterlabもこれにてインストールできているのだが、実行するためにはport forwardingをしないといけない。詳しい実行手順を確かめたかったら最後までこの記事を読んでほしい。
イメージのコミット
jupyter lab のテストの前に一旦コンテナをイメージにcommitする。つまり色々インストールした現在の状況をセーブする。
Ctrl+p,Ctrl+q
でコンテナを稼働させたままコンテナから抜ける。
現在稼働中のコンテナの確認
$ sudo docker ps -n=-1
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a24503258ede tensorflow/tensorflow:latest-gpu "/bin/bash" 24 minutes ago Up 24 minutes romantic_gauss
コンテナのコミット
$ sudo docker commit a24503258ede keras-jupyter
sudo docker commit (コンテナID) (つけたいイメージの名前)
のようにする。以降今まで作ったものはkeras-jupyterという名前のイメージをビルドすれば先程のコンテナが出来上がる。
コンテナの停止
先程のコンテナを一旦止める。
$ sudo docker stop a245
$ sudo docker ps -n=-1
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
コンテナIDは最初4文字くらいで反応してくれる。
port forwardingについて
これからjupyterlabの動作確認を行うのだが、ついでにport forwardingについて軽く説明する。
port forwarding(ポートフォワーディング)とは
現在私は以下の図のように私自身のパソコンからサーバにssh接続し、その上でdockerを走らせて、更にその上でjupyterlabを起動させようとしている。
しかしjupyterlabはブラウザ上で扱うもののためssh接続とは別にもう一つjupyterlabまでの接続経路を作成しないといけない。
そのためブラウザ上でもjupyterに接続できるようssh以外の接続経路(トンネル)を作成することをport forwardingという。
以下の図のように各コマンドにオプションを加えることでsshのポート22番の他にトンネルを開けることができる。
ただ今回は解説のためにすべてポート番号を変えているが、間違えないようすべてのポートフォワードするポートは8888などに統一すると良いだろう。
それでは具体的にjupyterlabのテストを通してポートフォアディングができているか確認していこう。
jupyterlabへのport forwarding
sshでのport forward
まずローカルからsshでサーバに接続する。
$ ssh user@x.x.x.x -L 8800:x.x.x.x:8880
-L {ローカルのポート番号}:{サーバのip}:{サーバでつなぎたいポート番号}
のようにオプションを付ける。
dockerでのport forward
-p 8880:8888
をオプションに追加する。
これによりサーバからdockerにアクセスした際にサーバのポート8880番がdockerの8888番につながる。
$ sudo docker run -it -p 8880:8888 keras-jupyter
これによりローカルの8800番はdockerの8888番につながった。
jupyterlabの起動
次にコンテナ上でjupyterlabを以下のコマンドで起動する。
# jupyter lab --port 8888 --ip=* --allow-root
以下コマンドの解説
- まずdockerのport8888番がローカルとつながっているためjupyterのportを8888とする。(
--port 8888
) - jupyterをそのまま起動するとipがわからず接続できないためdocker環境とアドホックにつなぐ。(
--ip=*
) - 最後に現在dockerはrootで起動してるためルートでの接続を許可する。(
--allow-root
)
以下のような出力の``http://127.0.0.1:8888/?token=614f6e5d410a1c459baa691ee28fdd0e2593c4644189a09e```をコピー。
[W 02:52:43.023 LabApp] WARNING: The notebook server is listening on all IP addresses and not using encryption. This is not recommended.
[I 02:52:43.028 LabApp] JupyterLab extension loaded from /usr/local/lib/python3.6/dist-packages/jupyterlab
[I 02:52:43.028 LabApp] JupyterLab application directory is /usr/local/share/jupyter/lab
[I 02:52:43.030 LabApp] Serving notebooks from local directory: /
[I 02:52:43.030 LabApp] Jupyter Notebook 6.1.4 is running at:
[I 02:52:43.030 LabApp] http://0829a84d25eb:8888/?token=614f6e5d410a1c459baa691ee28fdd0e2593c4644189a09e
[I 02:52:43.030 LabApp] or http://127.0.0.1:8888/?token=614f6e5d410a1c459baa691ee28fdd0e2593c4644189a09e
[I 02:52:43.030 LabApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
jupyterへの接続
先程のurlの一部を以下のように変更し、ローカルのブラウザに貼り付ける。
http://localhost:8800/?token=614f6e5d410a1c459baa691ee28fdd0e2593c4644189a09e
これでサーバで実行中のjupyterにポートフォアディングによって接続できる。
余談
実際dockerを実行する際にはユーザーをdockerとserverでバインドするなどここでは詳しく解説しないが以下のようにdocker run コマンドをaliasに登録して使うとよいだろう。
alias docker-run-keras = 'sudo docker run -v /etc/group:/etc/group:ro -v /etc/passwd:/etc/passwd:ro -v $HOME:$HOME -u $(id -u $USER):$(id -g $USER) -it --gpus 2 -p 8888:8888 --shm-size 30g keras-jupyter