背景
Dockerの書籍(Docker&Kubernetesのきほんのきほん) という本を先輩にお借りしてかなり勉強になったので、整理するために残しておきたい。
Dockerの用語、container, image, network, volume, Dockerfile, docker-composeをなんとなくしか知らなかったので、それを明確にしていきたい。
Dockerとは
一言で表すと、「データやプログラムを隔離できる仕組み」
データやプログラムを隔離できると何が嬉しいのか
パソコンや物理サーバーでプログラムを実行する場合、複数のプログラムが動いている。
それらのプログラムにはそれぞれの実行環境があり、その実行環境では同一のライブラリを参照している場合がある。
仮にAとBというプログラムで参照しているZライブラリがある。Aをアップデートする都合上、Zライブラリをアップデートしたい。しかし、ZライブラリがアップデートされるとBプログラムは動かなくなる。などの共有部分の依存問題がある。
そこで、AとZ, BとZのようにプログラムを隔離することで、同じ箇所を参照することがなくなり、共有部分の依存関係を調整する必要がなくなる。
Container
Container(コンテナ)は データやプログラムを隔離する箱のようなもの
隔離する箱がわからない場合は、本記事の「データやプログラムを隔離できると何が嬉しいのか」を読むとわかるかも。
コンテナには様々な実行環境をいれることができる。(webサーバ, メールサーバ, dbサーバなど)
実行環境は1コンテナに対して 1つずつor一緒でも 作れる。
コンテナはimageという設計書のようなものを元にして作ることができる。また、コンテナからimageを作ることもできる。
image
imageはコンテナを作るための設計書。
Docker Hubというimageがたくさんまとまっている場所から簡単にpullすることができる。
公式で公開しているimageや個人開発者が公開しているimageがあるので、使用用途を考えてpullする。
ホストのOSが異なっていても簡単に環境構築できるのは、imageをもとに実行環境を作れることが理由の一つとなっている。
network
imageをもとにコンテナを作ったとして、それぞれが結びつかなければ意味がない。
実はコンテナはDocker EngineというDockerの実行環境の上に載っている。Docker Engineでは、imageを元にコンテナを作ったり、コンテナ同士の接続も行う。そのコンテナ同士の接続を担うのがNetworkである。
仮に、AというWebサーバのコンテナと、BというDBサーバのコンテナを接続したい場合、
- Nというネットワークを作成(コンテナ作成時にネットワークを設定するため)
- BのDBサーバコンテナをNネットワークを利用するオプションを付けて作成
- AのWebサーバコンテナをNネットワークを利用するオプションを付けて作成
これによって、Docker内でAとBのコンテナが接続した状態を作ることができる
volume
volumeはコンテナで利用するストレージ。画像だけではなく、ディレクトリやhtmlファイルなども対象となる。
ホスト上にあるディレクトリやファイルを、コンテナ内の指定したpathにマウントしたり、Docker Engine上にストレージとして新しく作成することができる。
また、volumeはコンテナのライフサイクルとは別になっているため、コンテナが削除されても残っている。
volumeの種類は以下3種類ある
- ホスト上にあるデータやファイルを参照(バインドマウント)
- 例えば、ホスト上のhtmlファイルをマウントして、そのhtmlファイルを変更した場合、マウントしたコンテナにも反映される。マウントするホスト上のpathが間違っていると、volumeの作成に失敗する。
- Docker Engine上のファイルを参照(volumeマウント)
- docker engineにvolumeがある限り永続化させることができる。あまり触らないファイルなどをこちらに入れることが多い。volumeが消えると一緒に消える。
- 一時的にメモリとして、Docker Engine上で参照(tmpfsマウント)
Dockerfile
Dockerfileはイメージを作成することができる。
既存イメージに変更を加えたい時や、コンテナをビルドする時にコマンドを実行する事ができる。
imageを作成する時にわざわざコマンドを毎回打たなくても、Dockerfileにそのコマンドを書けば、Dockerfileをビルドするだけでよくなる。
docker-compose
docker-composeはコンテナ、イメージ、ネットワーク、ボリュームをまとめて起動/停止できる。いわば手順書。
これがないと、コンテナの数だけイメージのpullやネットワーク/ボリュームの作成をやらないといけない。もちろん停止する場合も一つずつやる。
それが辛いので、その手順書docker-compose.yml
で管理して、起動コマンドを1つ実行することで、楽に起動/停止を行える。
また、Dockerfileでビルドしたimageをdocker-compose.yml
で読み込むことも可能。
余談
LinuxOSであることが必須
Dockerはよく、「OSっぽいもの」ごとにコンテナを隔離できるという説明がある。
また別の記事で詳しくまとめたいが、簡単述べると、ホスト側もDocker側もLinuxで統一することで、OSで必要な機能を一部しか使わなくて良くなり、軽量かつOSっぽいものでコンテナを作ることができる。
ちなみにOSはカーネルと呼ばれる、ハードウェア命令を下すものと、機械語に翻訳などをする周辺の機能の2つに分かれており、Docker上ではハードウェアに命令を下すわけではないので、周辺の機能だけを搭載されている。(からOSっぽいものと言われている。)
余談の余談 いやいや、MacOSでDocker使ってますけど
その場合はdocker desktop for mac で無理やりLinuxOSっぽい環境をMacOS上に作っているか、 Virtual boxでLinuxOSの仮想マシン上でDockerを使っていると思います。なので、結局LinuxOS上でDockerが動いているんですね。