Dockerことはじめ: 初心者がコンテナを作ったり壊したりして覚えてみる

0. はじめに

0-1. Dockerを使おうとしたきっかけ

  • 私は普段はPyTorch使いなのですが, 研究の都合上, どうしてもTensorFlowを使わないとならない場面に遭遇しました.
  • しかし, とある事情で, NAISTの共用GPUサーバーの環境ではTensorFlowが使えないことが発覚してしまいました.
  • つまり, TensorFlowはどうしても使いたい, しかし, かといって共用サーバーの環境を個人の都合で勝手に弄りたくない, というジレンマに陥ったわけです.
  • そこで, TensorFlowが公式に提供しているDocker Imageを使ってみることにしました.

www.tensorflow.org

0-2. この記事で書いていること/書いていないこと

  • 書いていること
    • Dockerのごくごく初歩 (Docker HubからのImageの入手とコンテナの作成)
  • 書いていないこと
    • コンテナの概念
    • Dockerのインストール方法

0-3. 動作環境

1. Docker Imageを入手したり捨てたりしてみる

1-0. 準備

仮に, 研究プロジェクトの各種ファイルやスクリプト/home/me/myproject以下に保存しているものとします.

me@server ~ $ cd myproject
me@server myproject $ docker --version    # Dockerのバージョン確認
Docker version 19.03.8, build afacb8b

1-1. Docker Imageの入手

TensorFlow最新版のDocker Imageで, GPUとJupyterに対応したものをダウンロードしてきます.

# Docker Imageの名称は <リポジトリ名>:<タグ名> のようになっている
me@server myproject $ docker pull tensorflow/tensorflow:latest-gpu-jupyter

# ダウンロードしたDocker Imageの一覧
me@server myproject $ sudo docker images
REPOSITORY              TAG                  IMAGE ID            CREATED             SIZE
tensorflow/tensorflow   latest-gpu-jupyter   0123456789ab        8 weeks ago         3.99GB

1-2. Docker Imageの削除

一応, 削除のしかたも覚えておきます.

# Docker imageを一度削除してみる
me@server myproject $ sudo docker rmi 0123456789ab

# もう一度同じDocker imageを取得
me@server myproject $ docker pull tensorflow/tensorflow:latest-gpu-jupyter

2. Docker コンテナを作ったり壊したりしてみる

2-1. 作成と起動(1): docker create -> docker start してみる

ものすごく雑な理解では, Docker Imageは設計図でDocker コンテナが仮想マシン本体のようなものだと思っています.
docker createでコンテナを作成してみます.

# Docker imageをもとにコンテナを作成する
# --nameでコンテナ名をつける
# -it オプションを渡しておくとインタラクティブなコンテナを作成できる
me@server myproject $ sudo docker create -it --name tf_container tensorflow/tensorflow:latest-gpu-jupyter

docker ps -aでコンテナの一覧を確認できます.

me@server myproject $ sudo docker ps -a
# STATUSが "Created" になっている (作成されただけで起動はしていない)
CONTAINER ID        IMAGE                                      COMMAND                  CREATED             STATUS                     PORTS                    NAMES
456789abcdef        tensorflow/tensorflow:latest-gpu-jupyter   "bash -c 'source /et…"   30 seconds ago      Created                                             tf_container

docker startでコンテナを起動します.
TensorFlowのJupyter対応版Dockerイメージでは, デフォルトではコンテナの起動と同時にJupyter Notebookが起動するようになっているようです.

# -i オプションでインタラクティブなセッションを開始できる
# Jupyter Notebookがただちに立ち上がる
me@server myproject $ sudo docker start -i tf_container
jupyter_http_over_ws extension initialized. Listening on /http_over_websocket
[I 14:41:29.417 NotebookApp] Serving notebooks from local directory: /tf
[I 14:41:29.417 NotebookApp] The Jupyter Notebook is running at:
[I 14:41:29.417 NotebookApp] http://456789abcdef:8888/?token=xxxxxxxxxxxxxx
[I 14:41:29.417 NotebookApp]  or http://127.0.0.1:8888/?token=xxxxxxxxxxxxxx
[I 14:41:29.417 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 14:41:29.421 NotebookApp] 
    
    To access the notebook, open this file in a browser:
        file:///root/.local/share/jupyter/runtime/nbserver-1-open.html
    Or copy and paste one of these URLs:
        http://456789abcdef:8888/?token=xxxxxxxxxxxxxx
     or http://127.0.0.1:8888/?token=xxxxxxxxxxxxxx

ここでは何もせず, Control+c->yでJupyter Notebookを終了してみます. するとコンテナのインタラクティブセッションも終了し, ホスト側に戻ります.

me@server myproject $

docker ps -aでもう一度コンテナの一覧をみるとコンテナの停止を確認できます.

me@server myproject $ sudo docker ps -a
# STATUSが "Exited" になっている (コンテナが停止している)
CONTAINER ID        IMAGE                                      COMMAND                  CREATED             STATUS                     PORTS                    NAMES
456789abcdef        tensorflow/tensorflow:latest-gpu-jupyter   "bash -c 'source /et…"   30 seconds ago      Exited (0) 5 seconds ago                            tf_container

2-2. 起動時のコマンドを変えてみる(1)

先ほどはコンテナを起動した瞬間にJupyter Notebookが立ち上がりました.
しかし, これではJupyter Notebook以外に何もできないので, かわりにコンテナ起動時にシェルが立ち上がるようにしたいです.

再びdocker startでコンテナを起動してみます.

# ここでは -i オプションを渡さずに起動する
# すると, コンテナは起動するがインタラクティブセッションには移らない
me@server myproject $ sudo docker start tf_container
tf_container

docker exec コンテナ名 コマンドでコマンドを実行できます.

# -it オプションを渡すとインタラクティブセッションが始まる
me@server myproject $ sudo docker exec -it tf_container bash

コンテナ内でシェルが立ち上がりました!

________                               _______________                
___  __/__________________________________  ____/__  /________      __
__  /  _  _ \_  __ \_  ___/  __ \_  ___/_  /_   __  /_  __ \_ | /| / /
_  /   /  __/  / / /(__  )/ /_/ /  /   _  __/   _  / / /_/ /_ |/ |/ / 
/_/    \___//_/ /_//____/ \____//_/    /_/      /_/  \____/____/|__/


WARNING: You are running this container as root, which can cause new files in
mounted volumes to be created as the root user on your host machine.

To avoid this, run the container by specifying your user's userid:

$ docker run -u $(id -u):$(id -g) args...

root@456789abcdef:/tf# 

ここでは何もせず, コンテナのインタラクティブセッションから抜けます.

root@456789abcdef:/tf# exit
exit
me@server myproject $

docker ps -aでもう一度コンテナの一覧を確認してみます.

me@server myproject $ sudo docker ps -a
# STATUSは "Up" になっている (コンテナは起動したまま)
CONTAINER ID        IMAGE                                      COMMAND                  CREATED             STATUS                     PORTS                    NAMES
456789abcdef        tensorflow/tensorflow:latest-gpu-jupyter   "bash -c 'source /et…"   30 seconds ago      Up 15 seconds              8888/tcp                 tf_container

2-3. 停止と削除

docker stopでコンテナを停止 -> docker rmでコンテナを削除できます.
(もしくは, docker rm -fで起動中のコンテナも強制的に削除可能)

me@server myproject $ sudo docker stop tf_container
tf_container
me@server myproject $ sudo docker rm tf_container
tf_container

2-4. 作成と起動(3): docker run してみる

docker run イメージ名:タグ名 コマンドでコンテナの作成と起動を同時に行うことができます.

# 先ほどとはコンテナ名を変えて, tf_container_shell という名前で作成する
# 末尾に起動直後に実行させたいコマンド (ここでは bash) を付加する
me@server myproject $ sudo docker run -it --name tf_container_shell tensorflow/tensorflow:latest-gpu-jupyter bash

ここでは docker run-it オプションと bash コマンドを付加したので, tf_container_shell コンテナが作成されると同時にコンテナ内でシェルが立ち上がり, そのインタラクティブセッションに移行することができます.

________                               _______________                
___  __/__________________________________  ____/__  /________      __
__  /  _  _ \_  __ \_  ___/  __ \_  ___/_  /_   __  /_  __ \_ | /| / /
_  /   /  __/  / / /(__  )/ /_/ /  /   _  __/   _  / / /_/ /_ |/ |/ / 
/_/    \___//_/ /_//____/ \____//_/    /_/      /_/  \____/____/|__/


WARNING: You are running this container as root, which can cause new files in
mounted volumes to be created as the root user on your host machine.

To avoid this, run the container by specifying your user's userid:

$ docker run -u $(id -u):$(id -g) args...

root@23456789abcd:/tf# 

ここでは何もせず, インタラクティブセッションから抜け, コンテナも削除します.

root@23456789abcd:/tf# exit
exit
me@server myproject $ sudo docker rm tf_container_shell
tf_container_shell

3. おわりに

Dockerコンテナの作成, 削除, 起動, 停止についてだいぶ慣れてきました.
次はDockerコンテナ内で研究プロジェクトを動かす準備をしていきたいと思います.

次の記事はこちら

参考にした記事
https://qiita.com/tifa2chan/items/e9aa408244687a63a0ae