こんにちは!データサイエンティストの山本( @__Y4M4MOTO__ )です。
プロダクト開発本部では毎月「プラットフォーム技術共有会」という技術共有の場が設けられています。以前、下記の技術書を読んでこちらの会で発表してきました。
この記事では、その時発表した利用を公開しています(発表したのが昨年なので、情報が古くなっている可能性があります。ご了承ください🙇)。
以下、発表資料をテキストに直したものです。
どんな本?
[Q.] どんな本?
[A.] 「Docker よくわからない」を終わりにする本。
[Q.] 読んでみてどうだった?
[A.] 今まで何となくの理解でやってた部分がちゃんと説明されていてスッキリした。
- Docker って仮想 OS 的なもの…ではない?
docker run
とdocker exec
て何が違うの?docker exec -it <container> bash
のbash
の部分って何?- etc…
[Q.] どんな内容?
[A.] 全部で3チャプター。各チャプターの内容は以下の通り。
- チャプター1: Docker の概念理解
- チャプター2: Docker の基本操作
- チャプター3: 実際にサンプルアプリケーションで実践
[Q.] どんな人に(特に)オススメ?
[A.] こんな人↓
- Docker触ったことない人
- この本の内容一通りやれば、理解も実際に手を動かす部分もバッチリになれる
- とりあえず動かしながらDockerを始めた人
- (自分はこのパターン)
- 手を動かしながら始めるとすっ飛ばしがちな内容もしっかり理解できるようになる
個人的に勉強になった点
① Docker Desktop って何?
とりあえずインストールして何気なく使っている Docker Desktop ですが、「なぜインストールする必要があるのか?」といったところは正直今まであまり意識してきませんでした…。
ですので、この本を読んで
- Docker は Linux カーネルを使って動作する
- したがって、 Linux 以外の OS では本来使えないはず
- そこへ Docker Desktop をインストールすることで、 Linux カーネル等必要な一式がインストールされ Docker が使えるようになる
といったところをきちんと確認できたのは良かったなと思います。
② Docker コンテナは仮想 OS っぽいけど仮想 OS ではない
こちらも今まであまり意識できていなかったところでした…。
特に勉強になったのは「Docker は ホストマシン上の Linux カーネルを利用して動作しており、『 M1 Mac だと動かない』現象は Linux カーネルの違いが原因」というところです。ここを知れたおかげで、以後の Docker 関係のトラブルシューティングがかなりイメージしやすくなりました。
③ コンテナ起動時に実行する命令の指定方法
この部分の理解を深められたおかげで、今後の Dockerfile や docker-compose.yml の作成がとてもやりやすくなりました。
起動時の命令指定方法およびそれぞれの優先度は次のようになっています。
* docker-compose.yml の command: で指定する * docker exec のオプションで指定する ↓ * Dockerfile の CMD 命令で指定する ↓ * Docker イメージ内で指定されているデフォルト命令
実際に確認してみた
準備
本の内容を踏まえて実際に確認してみました。確認には Ubuntu (ubuntu:20.04
) の Docker イメージを利用しました。
まず、ubuntu:20.04
の Docker イメージのレイヤー構成 を確認してみます。
最後のレイヤーを見てみると、デフォルト命令は /bin/bash
であることがわかります。
続いて、 Ubuntu イメージをベースイメージとした自作イメージ my-ubuntu
を作成してみます。 my-ubuntu
イメージの Dockerfile は次のようにします。
FROM ubuntu:20.04 CMD ["echo", "CMD"]
これにより、コンテナ起動時に実行される命令は /bin/bash
ではなく echo 'CMD'
になりました。
確認 1 |そのままコンテナを起動した場合
そのままコンテナを起動してみます。起動コマンドおよびその結果は次のとおりです。
$ docker container run \ --name ubuntu1 \ --rm \ --interactive \ --tty \ my-ubuntu CMD
実行結果は CMD
となっており、 Dockerfile で指定した命令が実行されていることが確認できます。
確認 2 | docker exec
で指定した場合
docker exec
で起動時の命令を指定してみます。起動コマンドおよびその結果は次のとおりです。
$ docker container run \ --name ubuntu1 \ --rm \ --interactive \ --tty \ my-ubuntu \ echo "exec" exec
実行結果は exec
となっており、 docker exec
で指定した命令が実行されていることが確認できます。
確認 3 | docker-compose.yml で指定した場合
docker-compose.yml の command:
で起動時の命令を指定してみます。 docker-compose.yml の中身は次のようにします。
version: '3' services: sample: image: my-ubuntu tty: true command: echo "compose"
docker-compose up
コマンドを実行してコンテナを起動してみます。実行結果は次のとおりです。
$ docker-compose up [+] Running 2/0 ⠿ Network tech-book-lt_default Created 0.0s ⠿ Container tech-book-lt-sample-1 Created 0.0s Attaching to tech-book-lt-sample-1 tech-book-lt-sample-1 | compose tech-book-lt-sample-1 exited with code 0
実行結果は compose
となっており、 docker-compose.yml で指定した命令が実行されていることが確認できます。
④ volume マウント、 bind マウント、 Dockerfile の COPY 命令の違い
こちらも、理解を深められたおかげで今後の Dockerfile や docker-compose.yml の作成がとてもやりやすくなった箇所です。
この部分について、本書の内容を自分なりにまとめてみたものが次の表です。
方法 | 効果 | ホストマシンとの関係 |
---|---|---|
volume マウント | Docker が管理する領域をコンテナ内の指定ディレクトリに割り当てる | ホストマシンからはアクセスできない =ファイルを削除したりしてもホストマシンには影響が出ない |
bind マウント | ホストマシンの指定ディレクトリをコンテナ内の指定ディレクトリに割り当てる | ホストマシンからアクセスできる =ファイルを削除するとホストマシンからも消える |
Dockerfile の COPY 命令 | 指定ファイルをイメージビルド時にコピーする | コンテナを起動するとファイルが存在 →変更の反映にはイメージの再ビルドが必要 |
特に勉強になった点は次のとおりです。
- volume マウントって何やってるの?(自分は普段あまり volume マウントを使用しないため、あまり良く分かっていませんでした…)
- COPY 命令を使用している場合、ファイル内容の変更はイメージをビルドし直さないと反映されない
⑤ Docker Hub のレイヤー情報の見方
「Docker Hub で確認できるレイヤー情報は Dockerfile そのものではなく、 Dockerfile によって積み重ねられたレイヤーの情報」というのは知らなかったので、とても勉強になりました。
実際に rails:5.0.1
イメージで確認してみました。すると、 Docker Hub で確認できる rails:5.0.1
のレイヤー情報はruby:2.3
のレイヤーに Rails の Dockerfile が積み重ねられたものであることが確認できました。
結び
この記事では、プラットフォーム技術共有会にて「実践 Dockerソフトウェアエンジニアの『Docker よくわからない』を終わりにする本」の技術書 LT を行った際の発表内容について記しました。
とても良い本だなと思ったので、この記事をお読みになった方もぜひ読んでみていただければと思います!