Dockerのホストとコンテナの関係を理解する(米国AI開発者がゼロから教えるDocker講座)
これまでは、コンテナを起動する際にホストからファイルをコピーしたり、設定等をおこなったりしていましたが、コンテナを起動してからもファイルのやり取りをしたり、コンテナが利用するリソースを制御したりする方法を理解しました。
今回もかめ@usdatascientistさんの「米国AI開発者がゼロから教えるDocker講座」をUdemyで受講しながら進めています。
とても分かりやすく解説いただけますし、ハンズオン形式で講座が進むので、まさに「手で覚える」ことができるので、おすすめです!
では、振り返っていきたいと思います。
Dockerのホストとコンテナの関係を理解する
1.ホストとコンテナ間でファイルを共有する(-v オプション)
これまで、ホストからコンテナにファイルを渡すときは、Docker image作成時にファイルをコピーしていました、しかしながら、コンテナ起動後、ファイルをやりとりしたくなることもあります。また、コンテナに大きなファイルをおきたくないこともあります。
このようなときには、「-v」オプションを使うことで、ホストのファイルシステムをコンテナにマウントすることができます。
では、早速やってみます。
今回は、ホスト側に「mounted_folder」を作成しマウントされたことの確認用に、この中に「file_at_host」というファイルを作っておきます。
そして、このディレクトリを、コンテナ側に「new_dir」を作成した「new_dir」というディレクトリにマウントさせます。
まずは、以下のDockerfileを作成します。
FROM ubuntu:latest
RUN mkdir new_dir
作成したDockerfileが保存されたディレクトリに移動して、Dockerをbuildします。
docker build .
作成されたDocker imageから、コンテナを立ち上げます。
立ち上げる時に「-v」オプションを指定します。引数には、ホスト側のマウントするホスト側のディレクトリと、コンテナ側のディレクトリを「:」で区切って記載します。
docker run -it -v ~/tmp/docker/mounted_folder:/new_dir 616979cf0014
コンテナが起動したら、「new_dir」が作成され、「mounted_folder」にマウントされている(「file_at_host」が中にある)ことを確認します。
cd /new_dir
ls
無事、「new_dir」に「mounted_folder」がマウントされ、ホスト側の「mounted_folder」内に作成した「file_at_host」が表示されることが確認できました。
2.ホストとコンテナ間でアクセス権限を共有する(-u オプション)
先ほどの「-v」オプションを使ってマウントした場合は、コンテナからホストにアクセスするときに、ルート権限を持ってアクセスできてしまいます。
このため、「-u」オプションを指定することで、適切なアクセス権でマウントさせることができます。
まず、以下のDockerfileを作成します。
FROM ubuntu:latest
RUN mkdir created_in_Dockerfile
作成したDockerfileが保存されたディレクトリに移動して、Dockerをbuildします。
docker build .
次にコンテナを立ち上げる際にアクセス権を指定してみます。
「-u」オプションでは、引数にユーザーID,グループIDを「:」で区切って記載します。
この時、各IDの数字を入力するのではなく、コマンドの実行結果を渡すために$(コマンド)の記載を使って、実行結果を直接、引数として渡します。
docker run -it -u $(id -u):$(id -g) -v ~/docker/mounted_folder:/created_in_run 0f9142f9b4ad bash
マウントされたディレクトリのアクセス権を確認します。
ls -la
Dockerfileで作成した「created_in_Dockerfile」ディレクトリは、ユーザもグループも「root」権限になっています。
コンテナ起動時にアクセス権限を指定した「created_in_run」ディレクトリは、ユーザは「1000」、グループは「staff」となっていることが確認できました。
3.ホストのポートをコンテナのポートにつなげる(-p オプション)
コンテナ上にWebサービスを立ち上げた際に、IPアドレスはホストのアドレスと同じとなるため、コンテナ上のサービスにアクセスするために、「-p」オプションを指定することで、ホストのポートとコンテナのポートにつなげることができ舞う。
今回は、jupyter notebookのDocker imageをpull(run)して、ポート番号8888同士をつなげます。
docker run -it -p 8888:8888 --rm jupyter/datascience-notebook bash
<中略>
コンテナが起動できたら、jupyter notebook を立ち上げます。
jupyter notebook
コンテナ上でjupyter notebookが立ち上がったら、ホストのブラウザから「http://localhost:8888/」にアクセスします。
無事、ホストからコンテナ上のjupyter notebookにアクセスすることができました。
4.コンテナの利用できるリソースを制限する(--cpus,--memory オプション)
コンテナがホストのリソースを使い切ってしまわないように、それぞれのコンテナに利用できるリソースを制限できます。
CPUについては「--cpus」オプションで引数に利用するコア数を指定します。メモリについては「--memory」オプションで、メモリのバイト数を指定します。
例えば、以下は、CPUを1コア、メモリを2GBに制限したコンテナを立ち上げます。
ホストのターミナルから、コンテナのCPU、メモリの利用状況を確認します。
まずは、CPUを確認します。docker inspect コマンドで、コンテナの情報を得ることができます。ただ、情報がたくさん出すぎてしまうので、grepコマンドで、cpuという文字列を含む行だけ出力します。
docker inspect b80dcb84513d | grep -i cpu
少し読みづらいのですが「NanoCpus」を確認すると1000000000NanoCPUであることが確認できます。これは、単位がNanoなので、1CPUということになります。
同様にメモリについても確認します。
docker inspect b80dcb84513d | grep -i memory
またもや、少し読みづらいのですが「Memory」を確認すると2147483648バイトであることが確認できます。これは、1024バイトで1Kバイト、1024Kバイトで1Mバイト、1024Mバイトで1Gバイトなので、計算すると2Gバイトになります。
これで、無事、リソースを制限することができました。
今回の振り返りは以上になります。
今回、Dockerのホストとコンテナの関係を理解し、ディレクトリのマウントや、アクセス権限の管理、ポートの接続、リソースの制限ができるようになりました。
これで、Docker講座の基礎編が終わり、一通りDockerが使えるようになりました。
今回受講している「米国AI開発者がゼロから教えるDocker講座」では、もっと詳しくわかりやすくご説明いただけているので、ほんとうに良い勉強になります。
次回からは、応用編に進み、Dockerを使いこなせるようになりたいと思います!
【過去記事】
2019年8月31日(土)にE資格を受験して、合格しました!
E資格対策として勉強の進め方や、参考書などをまとめました。
これから受験される方がいらっしゃいましたらご参考まで。
2019年3月9日(土)にG検定を受験し、見事合格できました!
受験の体験記や勉強法などを別のブログにまとめました。
これから受験される方がいらっしゃいましたらご参考まで。
【E資格対策に使った参考書】
- 人工知能は人間を超えるか ディープラーニングの先にあるもの (角川EPUB選書) [ 松尾豊 ]
- 深層学習教科書 ディープラーニング G検定(ジェネラリスト) 公式テキスト (EXAMPRESS) [ 一般社団法人日本ディープラーニング協会 ]
- 徹底攻略ディープラーニングG検定ジェネラリスト問題集 [ 明松真司 ]
- 実践機械学習システム [ ウィリ・リチャート ]
- アルゴリズムクイックリファレンス 第2版 [ George T. Heineman ]
- 深層学習【電子書籍】[ 岩澤 有祐 ]
- 入門Python 3 [ ビル・ルバノビック ]
- PythonによるWebスクレイピング 第2版 [ Ryan Mitchell ]
- Think Stats第2版 プログラマのための統計入門 [ アレン・B.ダウニー ]
- 集合知プログラミング [ トビー・セガラン ]
- ITエンジニアのための機械学習理論入門 [ 中井悦司 ]