2015年5月4日月曜日

[docker] Docker ComposeでMySQLを使う

製品の評価や、開発時のテストなどDBをカジュアルに作成して消したいシチュエーションは多々あります。

開発マシンにDBを入れてデータ投入する運用だと、開発マシン環境が汚れてきたり、復数の設定が共存して収集がつかなくなったり、DBやライブラリのバージョンに依存する場合の切り替えに困ったりということになりがちです。

そこで以前だとVMを使ったり、AWSのようなクラウド上にDBを立てたりしていたわけですが、設定はそのものが難しくはないものの、毎回環境を構築する作業が必要になったりと、まだまだ手間のかかる作業でした。

言うまでもなく、このような問題がDockerで一気に解決したのは大変画期的なことです。

今回はDockerを使ってDBをカジュアルに構築する方法について考えてみます。

SoS JobScheduler

今回はジョブ管理製品のSoS JobSchedulerを使ってみました。

JobSchedulerはバックエンドにDBを使っているので、このDBをDocker上でどのようにして構築して接続するのかという点がポイントです。

またJobSchedulerはapt-getやrpmといったインストーラに対応しておらずインストールが手作業になります。このような製品の配布方式はけっこうありますが、この部分をDockerfile側、起動スクリプト側双方のシェルスクリプトで対応することになります。

MySQL公式Dockerイメージ

MySQLをインストールしたマイDockerイメージを作る方法も有力ですが、MySQLの公式Dockerイメージが機能豊富で結構便利だったので使ってみました。

また、JobSchedulerとMySQLを同じDockerイメージにインストールする方法もありますが、JobScheduler用Dockerイメージとしての汎用性が損なわれるので、避けたほうがよいでしょう。

このため、今回使用するDockerイメージはMySQL公式イメージとJobSchedulerをインストールしたマイイメージの2つになります。このように復数のイメージを接続する場合、dockerコマンドののパラメタを設定する方法もありますが、かなり煩雑です。

この問題に対応するため今回はDocker Composeを使ってみました。

Docker Compose

Docker Compose(旧fig)は復数のDockerイメージを連携動作させるための機能です。

定義ファイルdocker-compose.ymlの設定に従って、復数のDockerコンテナを同時に立ち上げ、Dockerのlinking systemを用いて各Dockerコンテナをリンクで接続する処理を行います。

設定

それでは、Docker Composeを用いた設定を行います。設定結果の全体はGitHubにありますので必要に応じて参照して下さい。

docker-compose.yml

docker-compose.ymlの設定は以下になります。

jobscheduler:
  build: .
  links:
    - db
  ports:
    - "4444:4444"
db:
  image: mysql
  ports:
    - ":3306"
  volumes:
    - conf.d/etc.mysql.conf.d:/etc/mysql/conf.d
  environment:
    MYSQL_USER: jobscheduler
    MYSQL_PASSWORD: jobscheduler
    MYSQL_ROOT_PASSWORD: jobscheduler
    MYSQL_DATABASE: jobscheduler

jobschedulerとdbの2つのDockerコンテナの定義をしています。

jobschedulerコンテナは自前のDockerfileを使ったコンテナです。linksでdbコンテナをリンクする設定を行っています。

dbコンテナはMySQL公式イメージをそのまま使っています。ポイントとなるのはenvironmentで指定している4つの環境変数です。これらの環境変数を設定することで、自動的に必要な初期設定をしてくれるようになっています。

多くのケースで、MySQL公式イメージが提供している環境変数で目的が足りると思われるので、MySQL公式イメージはかなり使い出がありそうです。

Dockerfile

JobSchedulerを実行するDockerfileの設定は以下になります。

FROM dockerfile/java:oracle-java8
MAINTAINER asami

ENV JOBSCHEDULER_VERSION 1.9.0

RUN mkdir -p /opt/jobscheduler && cd /opt/jobscheduler; curl -L http://freefr.dl.sourceforge.net/project/jobscheduler/jobscheduler_linux-x64.$JOBSCHEDULER_VERSION.tar.gz -o - | tar -xz --strip-components=1

# SSH, API/HTTP, API/HTTPS, JOC
EXPOSE 22 44440 8443 4444

USER root

COPY scheduler_install.xml /opt/jobscheduler/scheduler_install.xml

# Set the default command to run when starting the container
COPY startup-jobscheduler.sh /opt/startup-jobscheduler.sh
CMD ["/opt/startup-jobscheduler.sh"]

JobSchedulerがJava 8依存なので、基盤イメージとしてjava8版のJava公式イメージを指定しています。

wgetはインストールが必要なので用いずcurlを使っています。curlとtarを連動させている以下の行は:

RUN mkdir -p /opt/jobscheduler && cd /opt/jobscheduler; curl -L http://freefr.dl.sourceforge.net/project/jobscheduler/jobscheduler_linux-x64.$JOBSCHEDULER_VERSION.tar.gz -o - | tar -xz --strip-components=1
  • 中間ファイルを残さない。
  • 配布アーカイブにあるディレクトリ"jobscheduler.1.9.0"を"jobscheduler"に付け替え。こうすることで、後続の処理でバージョン番号を意識する処理を減らすことができます。

という意図です。このようなケースのイディオム的なスクリプトです。

startup-jobscheduler.sh

dockerの定義で比較的難しいのは起動スクリプトのところです。

基本的には、ターゲットのプログラムを起動するだけなのですが、環境との整合性を取るための処理を色々と書く必要があります。

今回の起動スクリプトはstartup-jobscheduler.shで、DockerfileのCMDで指定しています。

#! /bin/bash

sleep 10s

sed -i -e "s/{{DB_PORT_3306_TCP_ADDR}}/$DB_PORT_3306_TCP_ADDR/g" /opt/jobscheduler/scheduler_install.xml
sed -i -e "s/{{DB_PORT_3306_TCP_PORT}}/$DB_PORT_3306_TCP_PORT/g" /opt/jobscheduler/scheduler_install.xml

(cd /opt/jobscheduler;/usr/bin/java -jar jobscheduler_linux-x64.$JOBSCHEDULER_VERSION.jar scheduler_install.xml)

sleep infinity

DBの起動を待ち合わせるためsleepコマンドで10秒ウエイト入れています。

scheduler_install.xmlの設定を、Docker実行時の環境に適合するようにsedコマンドで書き換えています。環境変数DB_PORT_3306_TCP_ADDRとDB_PORT_3306_TCP_PORTはDockerのlinking systemが設定してくる環境情報です。これらの情報の取り込みを起動スクリプトで対応する必要があります。

JobSchedulerは起動後、自動的にバックグラウンドになってしまうため、そのままstartup-jobscheduler.shが終わるとそのままDockerも終わってしまいます。そこでsleepコマンドで永久にウエイトするようにしています。

実行

Docker Composeを使ってJobSchedulerを立ち上げてみましょう。

設定の取得

GitHubから設定一式を取得します。

$ git clone https://github.com/asami/SoS-JobScheduler-docker.git
ビルド

docker-composeコマンドのbuildを実行します。

$ docker-compose build
実行

docker-composeコマンドのupを実行します。

$ docker-compose up

起動は以上で終了です。

以下のアドレスにアクセスするとJobSchedulerの管理画面が表示されます。(Macの場合)

まとめ

Docker Composeを使って、自前のJobSchedulerコンテナとMySQL公式イメージを連動させ、JobSchedulerの実行環境を作ってみました。

MySQL公式イメージの機能が結構豊富なので、DB側は設定だけで使用することができました。

Dockerも便利ですが、Docker Composeもかなり便利で、アイデア次第で色々と応用がありそうです。

諸元

Mac OS 10.7.5 docker 1.6 docker-compose 1.2.0

0 件のコメント:

コメントを投稿