dockerのvolumeについて調べた。
・dockerコンテナの内部データは削除時に消える。
・データ永続化のためにホストやdocker volumeというdockerが管理する領域をマウントする。
・マウントに指定したファイルやディレクトリはコンテナ削除した後も残る(データがコンテナ外部に保存されている感じ)
・マウントには二種類ある。hostのディレクトリを同期するタイプとdockerが管理するvolume空間をマウントするやつ。
・前者をバインドマウント, 後者をvolumeという。
・前者は開発中のコードをコンテナ内に同期して開発するのに使ったりする(エディタで編集しながらコンテナ内にコードを配置できる)。後者はホスト側で管理しなくても良い時に使う(mysqlのデータとかnginxとphpを繋ぐソケットファイルとか)
使い方 基本
docker run実行時に-v オプションでマウントできる
書式は-v ホストpath:コンテナpath。
ホストのpathに相対pathは使えないので絶対pathで書くこと。
↓a.txtを同期させる
$ docker run -it --rm -v ~/Documents/test/docker/volume_test/a.txt:/a.txt centos:centos8
[root@defef339acca /]# ls -la
-rw-r--r-- 1 root root 4 Dec 15 12:02 a.txt
略
ホスト側でa.txtを更新するとコンテナ側にも反映される。
また、コンテナ側から変更してもホスト側に反映される。
$ echo "aaa" > a.txt
↓コンテナ側
[root@defef339acca /]# cat a.txt
aaa
ホスト側でa.txtを削除するとコンテナ側でバグる。ls -la だと存在するが、ファイルへのアクセスはできなくなる。
[root@defef339acca /]# ls -la
-????????? ? ? ? ? ? a.txt
[root@defef339acca /]# cat a.txt
cat: a.txt: No such file or directory
コンテナ側でa.txtを削除しようとするとエラーになる。ファイル編集は可能。
[root@57c0c3b18570 /]# rm a.txt
rm: remove regular file 'a.txt'? yes
rm: cannot remove 'a.txt': Device or resource busy
a.txtがホスト側にない状態でマウントしようとすると、a.txtという名前でディレクトリが作成され、それがマウントされる。
[root@47850246319a /]# ls -la
drwxr-xr-x 2 root root 64 Dec 15 12:12 a.txt
ファイルだけでなく、ディレクトリもマウントできる。
$ mkdir hoge
$ touch hoge/a.txt
$ docker run -it --rm -v ~/Documents/test/docker/volume_test/hoge:/hoge centos:centos8
[root@3c0109bbdf3c /]# ls -la
drwxr-xr-x 3 root root 96 Dec 15 12:24 hoge
使い方 複数volumeマウント
-vオプションは複数使用できる。
$ docker run -it --rm -v ~/Documents/test/docker/volume_test/a.txt:/a.txt -v ~/Documents/test/docker/volume_test/b.txt:/b.txt centos:centos8
[root@19354f136991 /]# ls -la
-rw-r--r-- 1 root root 0 Dec 15 12:14 a.txt
-rw-r--r-- 1 root root 0 Dec 15 12:14 b.txt
使い方 dockerボリュームをマウントする
-vオプションの値を変えることでdockerボリュームをマウントできる
ホストのディレクトリをマウントする際は絶対pathを使用したが、dockerボリュームをマウントする際はvolume名を指定する
-v volume名:コンテナpath
$ docker run -it --rm -v hoge:/hoge centos:centos8
[root@31ac4d5be7fa /]# ls -la
drwxr-xr-x 2 root root 4096 Dec 15 12:40 hoge
[root@31ac4d5be7fa /]# touch hoge/a.txt
[root@31ac4d5be7fa /]# exit
--rmをつけてコンテナ起動しているのでexit時にコンテナは破棄される。
↓再度コンテナを作成する
$ docker run -it --rm -v hoge:/hoge centos:centos8
↓hogeはdockerボリュームになっているので永続化されていることが分かる。
[root@4c03049e11c9 /]# ls hoge
a.txt
docker volumeをコマンドで確認する
$ docker volume ls
DRIVER VOLUME NAME
local hoge
dockerボリュームをマウントする際はvolume名を指定しなくても良い。
volume名を指定しないvolumeを匿名ボリュームという。
その場合は、コンテナpathだけ指定する。
-v コンテナpath
$ docker run -it --rm -v /fuga centos:centos8
[root@6806bc7b9bcf /]# ls -la
drwxr-xr-x 2 root root 4096 Dec 15 12:44 fuga
ただし、volume名を指定しないとvolume名はハッシュ値となり何のvolumeなのか分かりづらくなるのでおすすめしない。
$ docker volume ls
DRIVER VOLUME NAME
local 16fba3a332888fcd049a7dd569d6d27f360cc07ef58000bfee93f25e85416df9
また、volume名をつけない + --rm付きで起動した場合、コンテナ内でディレクトリは作成されたがvolumeは作成されず永続化されなかった。--rmなしでやるとvolumeが作成された。
(あれ、こんな挙動だったっけ?)
docker volumeコマンド
docker volumeコマンドには以下がある。
$ docker volume
Usage: docker volume COMMAND
Manage volumes
Commands:
create Create a volume
inspect Display detailed information on one or more volumes
ls List volumes
prune Remove all unused local volumes
rm Remove one or more volumes
Run 'docker volume COMMAND --help' for more information on a command.
ls でvolume一覧を表示する。
prune で未使用のローカルvolume削除
rm で特定のvolume削除
docker volume inspectについて
inspect = 検査。
volumeの詳細情報を教えてくれるらしい。
Mountpointを見るとvolumeがどこに格納されているか分かる。このpathはmac上のpathではなくdocker engineが動いているvm上のpath。
$ docker volume ls
DRIVER VOLUME NAME
local 16fba3a332888fcd049a7dd569d6d27f360cc07ef58000bfee93f25e85416df9
local bbb
local hoge
$ docker volume inspect hoge
[
{
"CreatedAt": "2020-12-15T12:40:52Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/hoge/_data",
"Name": "hoge",
"Options": null,
"Scope": "local"
}
]
参考
公式
https://matsuand.github.io/docs.docker.jp.onthefly/storage/volumes/