ぜんぜんわからない、俺たちは雰囲気で Docker を使っているシリーズ、volume です。
$ docker -v Docker version 18.03.1-ce, build 9ee9f40
- volume を使ってマウント
- 別コンテナで同じ volume をマウント
- ファイルが既に存在するディレクトリに volume をマウントしたら?
- --volumes-from で複数ボリュームを持つコンテナを指定してみる
- バックアップ
- 参考文献
まず、Docker においてデータを扱う場合、その扱いとしては、大きく 3 つに分けられます。
- bind mount
- volume
- tmpfs mount
bind mount は Docker ホストの任意のファイル・ディレクトリを Container 内にマウントする機能、volume は Docker が管理するデータ領域を Container 上にマウントする機能です。 tmpfs は Linux でしか使えないけど、データ領域をメモリ上に置く機能です。まぁ、tmpfs の名前そのまま。
tmpfs は別として、bind mount、volume の機能を使用する際のオプション指定は、昔ほとんど同じで docker run -v src:dst:ro
みたいなかんじだったと思います。
今でもこのオプションは使えるんですが、最近はこれよりも docker run --mount
とするのが推奨されています。まぁ昔から -v
オプションは分かりづらかったもんな。
volume を使ってマウント
まず事前状態を確認しておきます。最初は volume は作成されていません。
$ docker volume ls DRIVER VOLUME NAME
ここから、volume を使ってマウントしてみます。
$ docker run --name ubuntu1 -it \ --mount type=volume,src=vol,dst=/vol1 \ ubuntu /bin/bash root@e796842acc29:/# ls /vol1 root@e796842acc29:/#
ここでは --mount
を使ってマウントしていますが、このように --mount
オプションはカンマ区切りでオプションを指定していきます。
これが読みやすいかどうかは個人の感覚に依りますが、ぼくは -v
を使って「これって bind mount?それとも volume??」と混乱するよりは明示的で良いかなと思っています。
きちんと /vol1 が見えているようですね。ここでは、適当にファイルを作成しておきます。
root@e796842acc29:/# echo 'hello world!' > /vol1/hello.txt Ctrl-P Ctrl-Q
別コンテナで同じ volume をマウント
別コンテナで同じ volume をマウントしてみます。 きちんと、先程のファイルの内容が読み取れることが分かります。
$ docker run --name centos1 --mount type=volume,src=vol,dst=/vol-centos -it centos /bin/bash [root@acbe617deee3 /]# cat /vol-centos/hello.txt hello world!
では、次にこの状態 (ubuntu1 と centos1 が同時に vol
をマウントしている状態) で、centos1 が同じファイルに追記してみます。
[root@acbe617deee3 /]# date +%Y-%m-%d >> /vol-centos/hello.txt Ctrl-P Ctrl-Q $ docker exec ubuntu1 cat /vol1/hello.txt # on Docker Host hello world! 2018-06-08
当然ですが、別コンテナでも同じファイルコンテンツを読み取ることができます。
ファイルが既に存在するディレクトリに volume をマウントしたら?
じゃぁ、ファイルが既に存在するディレクトリに volume をマウントしたらどうなるんかいな。
これはちょっと面白くて、「新規ボリューム」をマウントすると、何も起こりません。以下の例では、元々の /tmp に配置されているファイルがそのまま残ります。
$ docker run --rm --mount type=volume,src=hoge,dst=/tmp centos ls -l /tmp total 4 -rwx------ 1 root root 836 May 31 18:03 ks-script-3QMvMi -rw------- 1 root root 0 May 31 18:01 yum.log
一方で、ファイルが既に存在するディレクトリに「ファイルが既に存在するボリューム」をマウントすると、元々の /tmp にあったファイルが見えなくなります。 通常の mount っぽい挙動だ。
$ docker run --rm \ --mount type=volume,src=vol,dst=/tmp centos ls -l /tmp total 4 -rw-r--r-- 1 root root 24 Jun 8 06:32 hello.txt
--volumes-from
で複数ボリュームを持つコンテナを指定してみる
--volumes-from
で複数ボリュームを持つコンテナを指定するとどうなるんやろと思って、試してみます。
結果は想定通りで、--volumes-from
は指定したコンテナがマウントしている全ボリュームを、新しいコンテナからマウントできました。
1 つしかボリュームがなければ別に --mount
でマウントしても良いんじゃねと思ったんですが、そういえば名前を明示的につけずにボリュームをマウントすることもできたので、
そういう場合にもメリットがありそうです。
# 複数ボリュームをマウントしたコンテナを作る $ docker run --name multi-volumes -it --mount source=vol,destination=/vol1 --mount source=vol2,destination=/vol2 ubuntu # volumes-from で上記コンテナを指定したコンテナをつくる % docker run --rm \ --volumes-from multi-volumes \ -it ubuntu /bin/bash root@6d59bc95c759:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var vol1 vol2 root@6d59bc95c759:/# ls vol* vol1: hello.txt vol2: root@6d59bc95c759:/#
バックアップ
対象コンテナがマウントしている volume がわかればバックアップもできるということで、以下のようなかんじでバックアップがとれます。
$ docker run --rm \ --volumes-from multi-volumes:ro \ --mount type=bind,src="$(pwd)/backup",dst=/backup \ -it ubuntu tar czvf /backup/bk.tgz /vol1 /vol2 tar: Removing leading `/' from member names /vol1/ /vol1/hello.txt /vol2/