このブログサイトをConoHaに移設したタイミングで、これまで裸で使っていたdockerコンテナについて、完全docker-compose化を行いました。しばらく運用していますが、とにかくdocker-composeと最新のdocker(1.12系)の組み合わせは最高に便利です。
Dockerは使っていたけど・・・
このサイトはWordpressで運用しているので、MariaDB(mysql)とphp(hhvm)とnginxを組み合わせて運用しています。普通にOS上で起動しても良いのですが、各々の設定やインフラ設定を管理しやすくするため、すべてdockerコンテナにして、DockerfileをGithubで管理することで、バージョン管理・構成管理を纏めて行っています。
元々docker化自体はこのサイト運用当初から実施していたのですが、dockerを裸で運用していました。要するに、ブログサーバーの起動はスクリプトにしていて、これを手で起動していたと。こんな感じです。
% docker run -d -h mariadb.home --name mariadb.home -v /share/mariadb.home:/share -v /share/socks:/socks centos6/mariadb:20151024 /usr/bin/mysqld_safe % docker run -d -h nginx.home --net=host --name nginx.home -v /share/www/html:/var/www/html -v /share/nginx.home/var/log:/var/log -v /share/nginx.home/var/cache:/var/cache -v /share/socks:/socks --restart=on-failure:5 centos7/nginx nginx
そもそもDockerイメージを作るところも多少手でやっていたところもあり、設定を変える場合には、
- docker exec /bin/bashでコンテナに入る。
- viで設定を編集(※なのでvimもコンテナイメージにインストールしてある)
- docker restartで再起動(※linkが切れないようにするため)
- 設定をイメージに保存するため、docker commit(※結構時間かかる)
- 忘れないように、変更箇所をメモる(※そして忘れる)
なんてことをしていたと。今から考えるとなんとも前時代的だ。
そこで、ConoHaに移すタイミングで、これまでなんとなく管理していたDockerfile等の設定を含め、すべてをGithub管理にして、docker-composeで一括管理できるようにしてみたと。
docker-compose導入
まずは、docker-composeを導入する前に、既存コンテナについては、Dockerfileから確実にbuild出来るようにしておくことが前提です。
docker-composeのインストールについては、Dockerのサイトの通りに実施すればOK。あと、docker-engineについても、OSディストリビューションに同梱されているものではなく、個別にDockerのリポジトリから新しいものを入れたほうが良いです。
なぜ新しいほうが良いかと言うと、Dockerは1.10以降、Embedded DNS機能が実装されて、link無しでも同じネットワーク内のコンテナがhostnameで参照できるようになっているためです。これによって、link切れによるコンテナ再作成等の手間を大きく低減できます(まぁdocker-compose使ってしまうとあまり関係無いのですが)。
あと、Dockerのストレージエンジンは、なるべくoverlayfsを使うことをオススメします。何より速いのと、devicemapper(特にLVM)を使っていると、容量が足りなくなったとき、死ぬためです(※経験者は語る。本当に、暴走して、起動出来なくなって、死ぬ)。そのためにこのブログサイトは、OSを従来使っていたCentOSからUbuntuに変更しました。なるべく新しいkernelを使うためです。
普通にUbuntuでdocker-engineを導入すると、loopback deviceのdevicemapperでとりあえず動き出しますので、以下のように修正します。
% sudo systemctl stop docker % sudo vi /lib/systemd/system/docker.service ※以下修正 ExecStart=/usr/bin/dockerd -H fd:// -s overlay % sudo systemctl daemon-reload % sudo rm -fr /var/lib/docker % sudo systemctl start docker % sudo systemctl status docker
docker-composeを使う
Docker Composeの具体的な使い方ですが、以下を参照してください。
あまり綺麗ではないのはご愛嬌。このリポジトリを作ったことで、どこの環境でも一瞬で快速Wordpress環境が作れるようになりました。maxscaleが居るのは、趣味です。
docker-compose.ymlの書き方についてはドキュメント参照してください。基本的なオペレーションですが、いきなりupでも良いのですが、まずはbuildしましょう。docker-compose.ymlのあるフォルダで、docker-compose buildを実行します。
% git clone https://github.com/tkshimada0912/Dockerfile % cd Dockerfile/blogserver % docker-compose build
すると、関連するイメージがbuildされます。
サービスを上げるには、upです。ここで「-d」を付けないと、フォアグラウンドになってしまい、Ctrl-Cで停止すると、サービスが全部落ちてしまいますので、忘れずに「-d」を付けましょう。
% docker-compose up -d Creating network "blogserver_default" with the default driver Creating blogserver_memcached_1 Creating blogserver_mariadb_1 Creating blogserver_maxscale_1 Creating blogserver_hhvm_1 Creating blogserver_nginx_1 % docker-compose ps Name Command State Ports ---------------------------------------------------------------------------------------------------------- blogserver_hhvm_1 sudo -u www-data hhvm --mo ... Up blogserver_mariadb_1 /usr/bin/mysqld_safe Up blogserver_maxscale_1 maxscale -d Up blogserver_memcached_1 /start.sh Up 11211/tcp blogserver_nginx_1 nginx Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
こんな感じでサービスが上がってきます。
止めたくなったら、docker-compose downです。
% docker-compose down
Stopping blogserver_nginx_1 … done
Stopping blogserver_hhvm_1 … done
Stopping blogserver_maxscale_1 … done
Stopping blogserver_mariadb_1 … done
Stopping blogserver_memcached_1 … done
Removing blogserver_nginx_1 … done
Removing blogserver_hhvm_1 … done
Removing blogserver_maxscale_1 … done
Removing blogserver_mariadb_1 … done
Removing blogserver_memcached_1 … done
Removing network blogserver_default
ここでポイントなのが、docker-composeはnetworkをdefineするところと、サービス停止すると、dockerコンテナもすべて破棄されるところです(※一応、pauseもできるようです・・・どう使うのかはわかりません)。永続化データは、外部ディスクをmountして置いておく必要があります。
docker-composeで設定変更
ここからが真骨頂。設定変更を行う場合、従来はdocker execでコンテナ内のファイルを書き換えて、commitしたりしていたのですが、まぁ普通のDockerの使い方からすると、やっぱりイメージに設定ファイルは反映して作成しなおしますよね。これがdocker-composeを使うととても綺麗にできます。
例えば、memcachedのメモリサイズを変更してみます。
% vi Dockerfile/alpine/memcached/Dockerfile
※以下を修正
ENV MEMCACHED_MEMORY 128
そうしたら、イメージを作り直します。docker-compose buildを行うと、変更されたイメージだけが再作成されます。
% cd Dockerfile/blogserver % docker-compose build ....※blogserver_memcachedだけが更新される。あとはcacheされているままなので更新されない。
ここでおもむろにupすると、更新されたコンテナと、関連するコンテナだけを再作成してくれます。
% docker-compose up -d Recreating blogserver_memcached_1 blogserver_mariadb_1 is up-to-date blogserver_maxscale_1 is up-to-date blogserver_hhvm_1 is up-to-date Recreating blogserver_nginx_1
Dockerfile側で設定をすべて管理することで、このように設定変更操作が非常にスマートになります。
当然ながら、試験環境で上記の通り動作確認をした上で、git commitをかけて、プロダクション環境側ではリポジトリからリリース、なんていう流れがこれで実現できるようになります。
もちろん、Dockerだけでもできるんですが、docker-composeで管理することで、複数コンテナでもまとめて操作できるので、非常にインフラ管理の手間が減って楽になります。
DockerらしいDockerの使い方
という感じで、docker-compose化したことで、このサイトの設定周りの運用がすこぶる楽になりました。
Immutable Infrastructureって、言葉では言いますが、docker-compose化したことで、コンテナ内の設定ファイル等を変えないことが徹底され、Githubでの構成管理も安定しました。これこそImmutableなんだなぁと、勝手に納得しています。
docker-composeはscale等の機能のほうが有名な気がしますが、基本的なコンテナ依存性の管理を使うだけでも、こんなことができるんですね。便利だし、これはみんなに使って欲しいなぁと。
コメント