2019-10-5追記
この記事を書いて1年が経ちましたが、実は今もほぼ毎日いいねやストックをもらっています。
やはり、Docker の Volume が気になる人は多いんだな、と感じています。
その一方、同じテーマで書いた 『[Docker] containerが使ってる全てのvolumeをCSV出力するワンライナー - Qiita』 は、未だに「1いいね」なのですが、どちらかと言えば、こちらの記事のほうが実践的なので、紹介しておきます。
具体的には「gitからcloneしてきてdocker-composeで起動したけど、これのコンテナとボリュームってどうつながってるの?」といった疑問の解決に使える思います ![]()
はじめに
Docker の Volume って難しくないですか?
理解に自信が無かった部分を、真面目に調べてまとめてみました。
これを読むとわかること
-
コンテナとボリュームの違い -
-v /aaa:/bbbと-v /bbbと-v ccc:/bbbの違い(docker-compose ではvolumes) -
--volumes-from dddの意味(docker-compose ではvolumes_from) - Data Volume と Data Volume Container の違い
- Data Volume Container は、「永続化したいデータの保存先となるコンテナ」という意味ではない。(永続化したいデータの保存先はボリュームです)
ボリューム(Data Volume)とは
-
ボリュームとは、データを永続化できる場所のことである。
- 外部HDDのようなイメージ。コンテナ本体にマウント(
-v)して使う。
- 外部HDDのようなイメージ。コンテナ本体にマウント(
-
コンテナとボリュームの違いについて- コンテナ内部にデータ(ファイル)を保存しても、コンテナ破棄すると消えてしまう。
- なので、データを永続化したいときは、コンテナの外にデータを置く必要がある。
- その場所のことを、ボリュームと呼ぶ。
-
ボリューム(=データを永続化できる場所) は2種類ある。- ホストのディレクトリ(ファイル)
- ホストで
lsで見えるモノ。
- ホストで
- Docker の リソースとしての Volume
-
docker volume lsで見えるモノ。
-
- (本当は、これ以外にもNFSなども指定できるようだ)
- ホストのディレクトリ(ファイル)
-
ボリュームをコンテナにマウントする(
-v)ことで、コンテナからアクセスできるようになる。 -
あるいは
--volumes-from <コンテナ名>とすると、指定したコンテナのマウントと同じようにマウントできる。(指定コンテナの-vの真似をする)
例
-
以下コマンドを実行したとします。
- 1
docker run -it --name c1 -v /hdir:/c1-hdir -v /hfile.txt:/c1-hfile.txt ubuntu:18.04 bash - 2
docker volume create v1 - 3
docker run -it --name c2 -v v1:/c2-v1 ubuntu:18.04 bash - 4
docker run -it --name c3 --volumes-from c1 --volumes-from c2 ubuntu:18.04 bash
- 1
-
イメージは。
+--<Host>----------+ +--<Docker>-------------------------------------+
| | | +--<Container:c1>---+ +--<Volume:v1>-----+ |
| | | | | | | |
| /hdir/--------------------> /c1-hdir/ | | | |
| /hfile.txt----------------> /c1-hfile.txt | | | |
| | | | | | | |
| | | +-------------------+ | | |
| | | | | |
| | | +--<Container:c2>---+ | | |
| | | | | | | |
| | | | /c2-v1/ <-----------------/ | |
| | | | | | | |
| | | | | | | |
+------------------+ | +-------------------+ +------------------+ |
| |
| +--<Container:c3>-------------------------+ |
| | c1,c2 と同じものが同じ場所にマウントされる | |
| | /c1-hdir/ | |
| | /c1-hfile.txt | |
| | /c2-v1/ | |
| +-----------------------------------------+ |
+-----------------------------------------------+
- このようになるので、コンテナ
c1c2を破棄しても、データ元であるボリュームは保持されるので、消えない。 - コンテナ
c3はc1c2のマウントポイントを持つ。(同じボリュームを同じマウントポイントにマウント) - メモ
-
docker volume create v1は実行しなくてもいい。なぜなら-v v1:/c2-v1しいたときにv1が無ければ、自動でv1が作られるから。 -
ボリューム名無し
-v /c2-v1でも自動的にボリュームが作成される。しかしながら、ボリューム名がハッシュ値になるので、docker volume lsしてもどれが使われているのか分かりづらい。$ docker volume ls DRIVER VOLUME NAME local 35ad7529d3e1c981bbc2d9235b9e3e9f6f71aaf8143f5d80015a84db7bb06019・・・ボリューム名無しのとき local v1・・・ボリューム名有のとき -
実は 17.06 から
--mountオプションが追加され、こちらが公式で推奨されている。- Use bind mounts | Docker Documentation https://docs.docker.com/storage/bind-mounts/#choosing-the--v-or---mount-flag
-
Data Volume Container とは
-
「永続化したいデータの保存先となるコンテナ」という意味ではありません。
- 私は勘違いしてましたorz
-
公式サイトで、Data Volume Container という用語はヒットしませんでした。
- 厳密には Container ≠ Volume なので、個人的にはこの用語には違和感があります。
-
複数コンテナでボリュームをマウントするときの
-vの記述を省略するテクニックなのだと理解しています。- 1 軽量なイメージ(busybox)を使って、ボリュームをマウント(
-v)したコンテナを作っておく(これを Data Volume Container、あるいは Data Container と命名。このコンテナ自身は終了していてよい) - 2 新しいコンテナを作る時
--volumes-from <Data Volume Container>するだけで、ボリュームを同じマウントポイントで共有できる。
- 1 軽量なイメージ(busybox)を使って、ボリュームをマウント(
Docker Volume Container の利点がもう1つありました。--rm でボリューム削除されないようにできます。(2018/09/28追記)
- 普通に
docker run --rm ...するとコンテナ停止で、ボリュームも削除される。- 1
docker run -it --rm --name c2 -v /c2-v1 ubuntu:18.04 bash - 2 bashを抜けるとコンテナ停止となるので、コンテナ
c1ボリュームv1が自動で削除される。
- 1
- 上記の操作をしてもボリュームが残るようにしたいなら、先に Data Volume Conteiner を作っておけばよい。(コンテナにマウントされているボリュームは自動削除されない)
- もっとも、Docker Volume Container を使わなくとも、ボリューム名有りマウント
-v v1:/c2-v1すれば--rmしても ボリュームv1を残すことができる。- 1
docker run -it --rm --name c2 -v v1:/c2-v1 ubuntu:18.04 bash - 2 bashを抜けると、コンテナ
c1が削除される。ボリュームv1は残る。
- 1
まとめ
ここまでのポイントを整理しておきます。
ボリュームとは、データを永続化できる場所のことである。
外部HDDのようなイメージ。コンテナ本体にマウント(-v)して使う。
コンテナ≠ボリューム(Data Volume) である。
コンテナ破棄しても、これにマウントされているボリュームは残る。
--volumes-from <コンテナ名> は「コンテナをマウント」しているのではない。
実は「指定コンテナのマウント(-v)のマネ」をしているだけ。マウントできるのはボリュームだけ。
永続化したいならボリューム名有りマウント -v v1:/c2-v1 を使うべき(2018/09/28記述見直し)
- ボリューム名無しマウント
-v /c2-v1のデメリット- ボリューム名がハッシュ値になるので、
docker volume lsしてもどれが使われているのか分かりづらい。 -
--rmオプションを付けてコンテナ起動したとき、コンテナ破棄だけでなく ボリュームも削除されてしまう。
- ボリューム名がハッシュ値になるので、
- ボリューム名有りマウント
-v v1:/c2-v1を使えば、上記のデメリットはない。