MroongaのDockerコンテナーでのdatadirの使い方いろいろ

メリークリスマス! DBAです。
この記事は Groonga Advent Calendar 2015 の25日目の記事です。
1日目の MySQLで日本語全文検索ができるMroongaのDockerリポジトリーをメンテナンスしています 、8日目の MroongaのDockerイメージをメンテナンスする、とは に続き、Mroonga + Docker第3弾です。
groonga/mroonga のDockerイメージでは、現在3通りのdatadirの扱い方をサポートしています。
- コンテナーの/var/lib/mysqlをコンテナーの中だけで使う
- コンテナーの/var/lib/mysqlをホストにマウントして使う
- ホストの(Mroongaのインストール済みの)datadirをコンテナーの/var/lib/mysqlにマウントして使う
まず、MroongaのDockerコンテナーではビルド時に「すぐに使い始められるような」状態に/var/lib/mysqlをセットアップしています。
具体的には、
- root@% ユーザーをパスワードなしで作ります
- Mroongaのinstall.sqlを実行します(INSTALL PLUGINと各種UDFのCREATE FUNCTIONが走ります)
の2つをやっています。MySQL 5.7になってちょっと細工が必要になっています が、そのあたりは こんな風 に細工してあります。
コンテナーのビルド時にdatadirがセットアップ済みなので、1. の使い方は非常に簡単で、docker runすればいいだけです。この場合、datadirは使い捨て(コンテナーをrmすると消える)になります。
それに対して 2. の方法では、「セットアップされていない(であろう)/var/lib/mysql」がマウントされるため、Mroongaのインストールやroot@%の作成を後付けで行わなくてはなりません。
というわけで それに対応したコミットがこちら です。/var/lib/mysql/ibdata1が存在しなければ、初期化されてないdatadirだとみなして、service mysqld start(この中でmysql_install_dbやmysqld --initializeが流れる)と、イメージビルドの時点でコピーしておいたmysql-community-mroongaのpost-installスクリプトを流し、さらにroot@%を作ります。
$ sudo docker run -d -v /home/yoku0825/mroonga:/var/lib/mysql groonga/mroonga 04d4a69f0321d15d55edd1dc73c0f9607314f0e18a966837511588d66c7aa358 $ sudo docker logs 04d4a69f0321d15d55edd1dc73c0f9607314f0e18a966837511588d66c7aa358 .. Initializing MySQL database: .. [ OK ] Starting mysqld: [ OK ] /usr/bin/mysql -u root < /usr/share/mroonga/install.sql Stopping mysqld: [ OK ] Starting mysqld: [ OK ] Stopping mysqld: [ OK ] .. Version: '5.6.27' socket: '/var/lib/mysql/mysql.sock' port: 3306 MySQL Community Server (GPL)
このとおり、docker logsでdatadirが初期化され、install.sqlが実行されているのを見ることができます。
$ ls -l mroonga/ total 110612 -rw-rw---- 1 mysql mysql 4 Dec 24 11:48 04d4a69f0321.pid -rw-rw---- 1 mysql mysql 56 Dec 24 11:48 auto.cnf -rw-rw---- 1 mysql mysql 576 Dec 24 11:48 groonga.log -rw-rw---- 1 mysql mysql 12582912 Dec 24 11:48 ibdata1 -rw-rw---- 1 mysql mysql 50331648 Dec 24 11:48 ib_logfile0 -rw-rw---- 1 mysql mysql 50331648 Dec 24 11:48 ib_logfile1 drwx------ 2 mysql mysql 4096 Dec 24 11:48 mysql srwxrwxrwx 1 mysql mysql 0 Dec 24 11:48 mysql.sock drwx------ 2 mysql mysql 4096 Dec 24 11:48 performance_schema
ホストから参照することも可能です。この方法でホスト上にdatadirを固定化しておけば、Dockerコンテナーを破棄してもdatadirは失われないためこれを利用して 3. の方法で使いまわすことができます。
3. の方法なんて本当は大したことはないのですが、1つだけ問題があります。上記 2.でホスト上に作成したdatadirを使い回すには問題ないのですが、それ以外の方法で「どこか(たとえば、ホスト上のMySQLとか)で作ったdatadir」を使い回す場合、パーミッションの問題が発生することがあるのです。
Mroongaのイメージ上では、mysqlユーザーのUIDは27で固定されています(これはmysql-community-serverのpost-installスクリプトにハードコードされています)そのため、datadirのオーナーはUID 27でなければなりませんが、これはホスト側の設定に依存します。
というわけで、3. の方法で起動された場合、コンテナーの中から見てオーナーがmysqlユーザーになるようにchownをかけて、mysqldの終了後に元のオーナーにchownで戻す処理が entrypoint.sh に入っています。
$ sudo chown -R yoku0825. /home/yoku0825/mroonga $ ls -l /home/yoku0825/mroonga/ total 110612 -rw-rw---- 1 yoku0825 yoku0825 4 Dec 24 11:48 04d4a69f0321.pid -rw-rw---- 1 yoku0825 yoku0825 56 Dec 24 11:48 auto.cnf -rw-rw---- 1 yoku0825 yoku0825 804 Dec 24 12:06 groonga.log -rw-rw---- 1 yoku0825 yoku0825 12582912 Dec 24 12:06 ibdata1 -rw-rw---- 1 yoku0825 yoku0825 50331648 Dec 24 12:06 ib_logfile0 -rw-rw---- 1 yoku0825 yoku0825 50331648 Dec 24 11:48 ib_logfile1 drwx------ 2 yoku0825 yoku0825 4096 Dec 24 11:48 mysql drwx------ 2 yoku0825 yoku0825 4096 Dec 24 11:48 performance_schema $ sudo docker run -d -v /home/yoku0825/mroonga:/var/lib/mysql groonga/mroonga 0c35fe26c14393bc8bbea17c468ae31baafd78b6d6d442b2ed6ed31bdfad2984 $ ls -l /home/yoku0825/mroonga/ total 110616 -rw-rw---- 1 27 27 4 Dec 24 11:48 04d4a69f0321.pid -rw-rw---- 1 27 27 3 Dec 24 12:07 0c35fe26c143.pid -rw-rw---- 1 27 27 56 Dec 24 11:48 auto.cnf -rw-rw---- 1 27 27 924 Dec 24 12:07 groonga.log -rw-rw---- 1 27 27 12582912 Dec 24 12:07 ibdata1 -rw-rw---- 1 27 27 50331648 Dec 24 12:07 ib_logfile0 -rw-rw---- 1 27 27 50331648 Dec 24 11:48 ib_logfile1 drwx------ 2 27 27 4096 Dec 24 11:48 mysql srwxrwxrwx 1 27 27 0 Dec 24 12:07 mysql.sock drwx------ 2 27 27 4096 Dec 24 11:48 performance_schema $ mysqladmin -h 172.17.0.95 shutdown $ ls -l /home/yoku0825/mroonga/ total 110612 -rw-rw---- 1 yoku0825 yoku0825 4 Dec 24 11:48 04d4a69f0321.pid -rw-rw---- 1 yoku0825 yoku0825 56 Dec 24 11:48 auto.cnf -rw-rw---- 1 yoku0825 yoku0825 1032 Dec 24 12:09 groonga.log -rw-rw---- 1 yoku0825 yoku0825 12582912 Dec 24 12:09 ibdata1 -rw-rw---- 1 yoku0825 yoku0825 50331648 Dec 24 12:09 ib_logfile0 -rw-rw---- 1 yoku0825 yoku0825 50331648 Dec 24 11:48 ib_logfile1 drwx------ 2 yoku0825 yoku0825 4096 Dec 24 11:48 mysql drwx------ 2 yoku0825 yoku0825 4096 Dec 24 11:48 performance_schema
ここでひとつ注意しないといけないのは、docker stopでコンテナーを停止させてしまうと オーナーは元に戻らない ことです。あくまでentrypoint.shの中でmysqldが終了した後に記述してあるコマンドで元に戻しているので、entrypoint.shをそのまま停止してしまうdocker stopではオーナーはUID 27のままになります。なので、mysqladmin shutdownで停止してあげてください。
Mroongaを利用したアプリの単体テストなどにご利用ください。
それでは良いお年を!