概要
Dockerのデータをホスト側に保持する方法をまとめます。
Dockerはコンテナの破棄・再作成が簡単にできる一方、そのままだとデータも消えてしまいます。
今回のDate Volume
はデータの永続性を保つべきシーンで必要となる知識です。
環境
- OSX 10.11.4
- docker 1.11.0
- docker-machine 0.7.0
4つのパターン
docker run
するときに以下のオプションをつけると使えます。
-v <container_path>
-v <host_path>:<container_path>
-v <data_volume>:<container_path>
--volumes-from <container_name>
これらを順に説明していきます。
通常のDocker run
今回はubuntuのimageを使います。
$ docker run -it --name my-data ubuntu /bin/bash
通常だとデータはコンテナ内のみに残るので、コンテナを破棄するとデータも消えてしまいます。
これに先ほどのオプションをつけてデータの永続化をします。
a. -v <container_path>
コマンド
$ docker run -it --name my-data -v /hoge ubuntu /bin/bash
同期されるフォルダ
マシン | フォルダ |
---|---|
コンテナ | /hoge 。存在しないフォルダなら自動生成される |
ホスト | /var/lib/docker/volumes/<ランダムな文字列>/_data/ に同期される |
同期確認
コンテナ側
適当なファイルを作成します。
root@fab1e6ce7428:/# cd /hoge/ root@fab1e6ce7428:/hoge# touch feee root@fab1e6ce7428:/hoge# ls feee
ホスト側
# cd /var/lib/docker/volumes/b3beace9176f1631d02f6398a7df4c201c67f7a49adb6087aa1add9958385568/_data # ls feee
ちゃんとファイルが存在します。
b. -v <host_path>:<container_path>
bind mountとも呼ばれる方式です。
コマンド
$ docker run -it --name my-data -v /fuga:/hoge ubuntu /bin/bash
同期されるフォルダ
マシン | フォルダ |
---|---|
コンテナ | /hoge 。存在しないフォルダなら自動生成される |
ホスト | /fuga に同期される。fuga のように、ルートから始めない場合c のdata volumeとして扱われる |
同期確認
コンテナ側
適当なファイルを作成します。
root@fab1e6ce7428:/# cd /hoge/ root@fab1e6ce7428:/hoge# touch feee root@fab1e6ce7428:/hoge# ls feee
ホスト側
$ cd /fuga/ # ls feee
ちゃんとファイルが存在します。
注意
bind mountの場合、ホスト側のデータに同期されるためコンテナ側で指定したディレクトリに既存のファイルがあったとしても見えなくなります。
ref: バインドマウントの利用 | Docker ドキュメント
c. -v <data_volume>:<container_path>
コマンド
$ docker run -it --name my-data -v some_data:/hoge ubuntu /bin/bash
同期されるフォルダ
マシン | フォルダ |
---|---|
コンテナ | /hoge 。存在しないフォルダなら自動生成される |
ホスト | docker volumeにsome_data が追加される。また /var/lib/docker/volumes/some_data に実体ができる |
同期確認
コンテナ側
適当なファイルを作成します。
root@fab1e6ce7428:/# cd /hoge/ root@fab1e6ce7428:/hoge# touch feee root@fab1e6ce7428:/hoge# ls feee
ホスト側
$ cd /var/lib/docker/volumes/some_data # ls feee
ちゃんとファイルが存在します。また
$ docker volume ls DRIVER VOLUME NAME local some_date
docker volumeの一覧にも登録されます。
d. --volumes-from <container_name>
これは同期設定した別コンテナを用意し、それを利用するパターンです。
同期設定したコンテナを用意
another-container
というコンテナを用意します。
$ docker run --name another-container -v /piyo:/hoge busybox
busybox
と言うのはデータ用コンテナでよく使われるimageです。
このコンテナはフォアグラウンドで起動している必要はありません。
同期されるフォルダ
マシン | フォルダ |
---|---|
コンテナ | /hoge 。存在しないフォルダなら自動生成される |
ホスト | /piyo に同期される。piyo のように、ルートから始めない場合/var/lib/docker/volumes/piyo にできる |
コマンド
$ docker run -it --name my-data --volumes-from another-container ubuntu /bin/bash
同期されるフォルダ
another-container
の設定の通りです。
同期確認
コンテナ側
適当なファイルを作成します。
root@fab1e6ce7428:/# cd /hoge/ root@fab1e6ce7428:/hoge# touch feee root@fab1e6ce7428:/hoge# ls feee
ホスト側
$ cd /piyo/ # ls feee
ちゃんとファイルが存在します。
その他
volume一覧を見たい時
$ docker volume ls DRIVER VOLUME NAME local 04566d1da2b17a53229d2dc17ea24c51e94a61806f8bb866f5822be477d03875 local 129bdd40ce9ba5344b3760dcac8691605546224a8002077e8bc837fdd0464171 local 298358023d1fd03cc47cce2fc384f569f1d5152946546a154e7d42a6237b7749 local 50974a5f0b1aeb09d7b5c7cae492c648d7cd00e73403c51ff163c6fe8bdbf530 local 728dc999bc7c2c5a15c20cbf483000042bbdcdef5ae12413c6199c1ba91b330e
残ったdocker volumeをまとめて消したい時
-q
オプションをつけるとIDのみ表示されるので、それをxargsで渡すとまとめて消せます。
$ docker volume ls -q | xargs docker volume rm
コンテナの中に入りたい時
$ docker exec -it <コンテナ名> /bin/bash
ホストVMの中に入りたい時
docker-machineで動かしている場合はホストはVMなので以下のようにして入ります。
$ docker-machine ssh <VM名>
明示的にvolumeを作りたい
$ docker volume create --name mysql_data $ docker volume ls DRIVER VOLUME NAME local mysql_data
明示的に作った後でc
のマウントも可能
$ docker run -it --name my-data -v mysql_data:/hoge ubuntu /bin/bash
DockerfileのVOLUMEは?
-v
を付けなければa
と同じく
- ホスト側:自動でvolumeが生成
- コンテナ側:Dockerfileの
VOLUME
で設定されたディレクトリ
が同期されます。
docker rm
してコンテナを再作成した場合、過去のvolumeは再利用されません。
自動生成されたvolumeをb
のようにマウントすると再利用は可能です。
まとめ
初期はホストのディレクトリを直接マウントすることでデータの永続性を担保していましたが、data volumeの機能が充実したことでdocker側からも管理しやすくなりました。
なので基本的にはc
のやり方で、
- ホスト側にデータの実体を保持する
- docker volumeで管理できるようにする
とするのが良いかなと思います。