LoginSignup
1076
824

More than 3 years have passed since last update.

Docker、ボリューム(Volume)について真面目に調べた

Last updated at Posted at 2018-09-27

2019-10-5追記
この記事を書いて1年が経ちましたが、実は今もほぼ毎日いいねやストックをもらっています。
やはり、Docker の Volume が気になる人は多いんだな、と感じています。
その一方、同じテーマで書いた 『[Docker] containerが使ってる全てのvolumeをCSV出力するワンライナー - Qiita』 は、未だに「1いいね」なのですが、どちらかと言えば、こちらの記事のほうが実践的なので、紹介しておきます。
具体的には「gitからcloneしてきてdocker-composeで起動したけど、これのコンテナとボリュームってどうつながってるの?」といった疑問の解決に使える思います :wink:

はじめに

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)して使う。
  • コンテナボリューム の違いについて

    • コンテナ内部にデータ(ファイル)を保存しても、コンテナ破棄すると消えてしまう。
    • なので、データを永続化したいときは、コンテナの外にデータを置く必要がある。
    • その場所のことを、ボリュームと呼ぶ。
  • ボリューム(=データを永続化できる場所) は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
  • イメージは。

+--<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/                               |  |
                       |  +-----------------------------------------+  |
                       +-----------------------------------------------+
  • このようになるので、コンテナ c1 c2 を破棄しても、データ元であるボリュームは保持されるので、消えない。
  • コンテナ c3c1 c2 のマウントポイントを持つ。(同じボリュームを同じマウントポイントにマウント)
  • メモ

    • 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 オプションが追加され、こちらが公式で推奨されている。

Data Volume Container とは

  • 「永続化したいデータの保存先となるコンテナ」という意味ではありません。

    • 私は勘違いしてましたorz
  • 公式サイトで、Data Volume Container という用語はヒットしませんでした。

    • 厳密には Container ≠ Volume なので、個人的にはこの用語には違和感があります。
  • 複数コンテナでボリュームをマウントするときの -v の記述を省略するテクニックなのだと理解しています。

    • 1 軽量なイメージ(busybox)を使って、ボリュームをマウント(-v)したコンテナを作っておく(これを Data Volume Container、あるいは Data Container と命名。このコンテナ自身は終了していてよい)
    • 2 新しいコンテナを作る時 --volumes-from <Data Volume Container> するだけで、ボリュームを同じマウントポイントで共有できる。

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 が自動で削除される。
  • 上記の操作をしてもボリュームが残るようにしたいなら、先に 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 は残る。

まとめ

ここまでのポイントを整理しておきます。

ボリュームとは、データを永続化できる場所のことである。

外部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 を使えば、上記のデメリットはない。
1076
824
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1076
824