データの永続化はdockerでよく課題になると思います。
docker docsには、Manage data in containersの節に、いくつかの方法が示されています。
- データボリュームを利用する
- ホストのディレクトリにマウントする。
しばらく前まではホストのディレクトリに逃がしていたのですが、ホストのディレクトリとコンテナの中ではユーザの番号や書き込み権限の管理が違ったりして、うまくいかないことも多かったので、最近はまじめにデータボリュームを使うようにしています。
MySQLを例に、データボリュームとそのバックアップ方法をまとめてみます。
データボリュームを作成してマウントする
データボリュームは、dockerfileのVOLUME
で指定したディレクトリ、またはdocker run
にて-v
で指定したディレクトリに、自動で作られます。そしてそれは、コンテナとは別に管理され、docker commit
やdocker export
してもデータボリュームの内容は含まれません。コンテナ間のデータ共有は、データボリュームによってのみ可能です。
自動で作られるだけではなく、コマンドで作ることもできます。MySQLのデータを管理するデータボリューム作ってみます。
このデータボリュームの名前をmysql_data
とします。
docker volume create --name mysql_data
データボリュームのリストは、コマンドで確認できます。
docker volume ls
DRIVER VOLUME NAME
local mysql_data
では、MySQLのコンテナにこのデータボリュームをマウントさせます。
docker run -d --name mysql -p 3306:3306 -v mysql_data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=password mysql
確かに、マウントされていることが、docker inspect
で確認できます。
docker inspect mysql
...
"Mounts": [
{
"Name": "mysql_data",
"Source": "/mnt/sda1/var/lib/docker/volumes/mysql_data/_data",
"Destination": "/var/lib/mysql",
"Driver": "local",
"Mode": "z",
"RW": true
}
],
...
なお、データボリュームはcreateすることができますが、標準のlocal
の場合、一度コンテナに紐付けられると、そのコンテナが破棄された時にデータボリュームも一緒に破棄されます。よって、データボリュームを作成するときは、busyboxなどのコンテナにわかりやすい名前で紐つけておいたほうが良いと思われます。
docker create --name mysql_data -v mysql_data:/var/lib/mysql busybox
(2015/12/09追記)確認しました。基本的にデータボリュームはコンテナを消しても削除されません。--rm
をオプションにつけると、コンテナと一緒にデータボリュームを消す機能があるようです。
データボリュームのバックアップ
コンテナやイメージと違い、データボリュームは単体でバックアップする方法は提供されていないようでした。このデータボリュームはプラグイン化されており、docker volume create -d [plugin]
で指定できます。きっとバックアップは各プラグインで考えることなのだろうと思います。
ちなみに、上記のdocker inspect
の結果local
と書かれていますが、実はSource
のディレクトリがマウントされているだけです。バックアップには、このディレクトリを直接処理しても良いと思います。
よく登場するのは、他のコンテナにこのデータボリュームをマウントし、そこでバックアップをする方法です。なんだかなーとおもって、データバックアップ専用のコンテナ74th/volumebackup
を作成しました。
https://hub.docker.com/r/74th/volumebackup/
https://hub.docker.com/r/74th/volumerestore/
以下のコマンドを実行すると、mysql_data-YYYYMMDDHHmmss.tar.gz
というファイルにバックアップします。
docker run -v mysql_data:/target -v `pwd`:/export -e NAME=mysql_data 74th/volumebackup
復元するには、復元用コンテナを使います
docker volume create --name mysql_data2
docker run -v mysql_data2:/target -v `pwd`:/import -e TARGETFILE=mysql_data-20151206124353.tar.gz 74th/volumerestore
最後に、このバックアップが使えることを確認します。
docker run -d --name mysql2 -p 3306:3306 -v mysql_data2:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=password mysql
おわり
dockerは正義!なツールを発表しようと思っていましたが、まだ未熟なツールなので、ちゃんと理解していなかったデータボリュームについてまとめました。
[https://github.com/74th/flyingwhale](Flying Whale : any package management systems in the container)