MySQLをDockerコンテナで用意する方法(その2)

MySQLをDockerコンテナで用意する方法 | hiro345」に引き続き、MySQLをDockerコンテナで用意する方法について調べています。下記が参考になりました。


公式のMySQLイメージでは「/etc/mysql/conf.d/*.cnf」を設定ファイルとして利用するそうです。ですから、「-v」でボリュームマウントをすれば設定を指定できます。

まず次のスクリプトcreate_mysqld_cnf.shを用意します。

#!/bin/sh
d="/var/opt/app001/mysqld/etc"
 
if [ ! -e ${d} ]; then
  mkdir -p ${d}
fi
 
sh -c "cat << EOF > ${d}/section_mysqld.cnf
[mysqld]
character-set-server=utf8
default_password_lifetime = 0
EOF"

次に、これをsudoコマンドで実行して、ホスト側に/var/opt/app001/mysqld/etc/section_mysqld.cnfを用意します。

$ sudo sh create_mysqld_cnf.sh

起動時にボリュームマウントをします。

$ docker run \
 --name mysqld003 \
 -v /var/opt/app001/mysqld/etc/:/etc/mysql/conf.d \
 -e MYSQL_ROOT_PASSWORD=secret \
 -d \
 mysql

MySQLのDockerfile
 「mysql/Dockerfile at master · docker-library/mysql · GitHub」にあるので確認するとわかりますが、「VOLUME /var/lib/mysql」としてあるのでコンテナを削除しない限りはMySQLのデータベースは永続化されています。ホスト側ディレクトリを明示的に指定したい場合は、このDockerfileを参考にして自分でDockerfileを作成してイメージを用意すれば良いでしょう。
 たしか「-v」オプションで指定すると、そちらが優先するような気もしますから、それでもいいかもしれません(2016-06-10追記:「-v」オプションの方が優先でした)。ちなみに、docker inspectでボリュームの情報は確認できます。

ボリュームマウント
 少しボリュームマウントについて整理しておきましょう。dockerのボリュームマウントオプションとしては次の「--volume」と「--volumes-from」を覚えておきましょう。「--volume」は「-v」と同じです。

  • --volume <host_path>:<container_path> … ホストの <host_path> を <container_path> にマウントしてコンテナを起動
  • --volume <container_path> … データボリュームを作成して <container_path> にマウントしてコンテナを起動
  • --volumes-from <container> … <container> で指定したコンテナのデータボリュームを全部マウントしてコンテナを起動

<host_path>:<container_path> を指定すると、ホストのファイルシステムを明示的にマウントして、コンテナ内部から利用できるようになります。<container_path>を指定すると、コンテナがホストの/var/lib/docker以下などにマウント用のディレクトリやファイルを自動で作成して、コンテナ内部から利用できるようになります。コンテナ専用なので、コンテナを削除すると、自動で作成されたディレクトリやファイルは一緒に削除されます。

「--volume <container_path>」を使うと、ホスト環境と独立したデータボリューム専用コンテナが用意できるため、ホストに干渉しないコンテナを用意したいときに利用します。

2016-06-03 追記:docker volumeコマンドを使うとボリュームの管理が簡単にできるそうです。docker volume ls、docker volume rmなどが使えます。

データボリューム専用コンテナ
 それではデータボリューム専用コンテナを用意してみましょう。元とするイメージはなんでもいいのですが軽量のbusyboxがよく使われているようです。

$ docker pull busybox

 ここでは、mysqld_data000 という名前で用意します。

$ docker run \
 --name mysqld_data000 \
 -v /opt \
 -it \
 busybox /bin/sh

 mysqld_data000 を利用するコンテナを起動します。ここではmysqlイメージを使っていますが、データボリューム専用コンテナの動作を確認するのなら、ubuntuなど別イメージを使ってもかまいません。

$ docker run \
 --name mysqld004 \
 -it \
 --volumes-from mysqld_data000 \
 mysql /bin/bash

 mysqld004コンテナ内で /opt にファイルを新規作成したりするとmysqld_data000が削除されない限り永続化されていることが確認できます。

データボリューム専用コンテナのイメージ作成
 ちなみにデータボリューム専用コンテナのイメージを作りたい場合は、次のようにDockerfileを用意してbuildします。

$ cat << EOF > Dockerfile
FROM busybox
VOLUME /opt
CMD /bin/sh
EOF
$ docker build -t hiro345/mysqld_data_volume .

 起動は次のようになります。

$ docker run -i -t --name mysqld_data001 hiro345/mysqld_data_volume

データボリュームの削除
 データボリュームはコンテナを削除しても参照ができなくなるだけで残っているそうです。martin/docker-cleanup-volumes を使うと削除できるそうです。手元の開発用CentOS7ではrootになってSELinuxをpermissiveモードにして使えました。--dry-runで削除されるファイルを確認してから削除が良いでしょう。

$ sudo su -
# setenforce 0
# docker run \
 --rm \
 -v /var/run/docker.sock:/var/run/docker.sock \
 -v /var/lib/docker:/var/lib/docker \
 martin/docker-cleanup-volumes --dry-run
# docker run \
 --rm \
 -v /var/run/docker.sock:/var/run/docker.sock \
 -v /var/lib/docker:/var/lib/docker \
 martin/docker-cleanup-volumes
# setenforce 1
# exit

データボリュームのバックアップ
 データボリュームのバックアップはコンテナでマウントしてtarで固めてとりだすというのが基本だとのことです。たとえば、container001 という名前の Data Volume Container を、--volumes-from で読み込んでいる container002 があるとします。dckr/docker-backupでバックアップします。

$ docker run \
 --name container001 \
 -v /opt \
 -it \
 busybox /bin/sh
$ docker run \
 --name container002 \
 -it \
 --volumes-from container001 \
 mysql /bin/bash
$ sudo su -
# setenforce 0
# docker run --rm \
 -v /var/run/docker.sock:/var/run/docker.sock \
 -v /var/lib/docker/vfs/dir:/var/lib/docker/vfs/dir \
 -v $(pwd):/backup \
 dckr/docker-backup store /backup/container002.tar container002
# setenforce 1
# ls
container002.tar
# exit

container003を用意して、そちらへ復元するには下記のようにします。

$ docker run \
 --name container003 \
 -v /opt \
 -it \
 busybox /bin/sh
$ docker inspect \
 --format='{{range $vol, $path := .Volumes}}{{$vol}}:{{$path}}{{"\n"}}{{end}}' \
 container003
(略)
$ sudo su -
# setenforce 0
# ls
test-container.tar
# docker run --rm \
 -v /var/run/docker.sock:/var/run/docker.sock \
 -v /var/lib/docker/vfs/dir:/var/lib/docker/vfs/dir \
 -v $(pwd):/backup \
 dckr/docker-backup restore /backup/container002.tar
$ docker inspect \
 --format='{{range $vol, $path := .Volumes}}{{$vol}}:{{$path}}{{"\n"}}{{end}}' \
 container003
(略)

docker inspectの結果(ここでは省略)がdckr/docker-backup restore の前後で変わることからリストアができていることがわかるはずです。

Dockerについては下記の資料も参考になります。

同じタグの記事: Docker
同じタグの記事: MySQL
同じカテゴリの記事: Linux