chef-containerを使ってみて

chef-containerで色々なコンテナを作成してみて思ったことなど。

fig良い

と言いつつ、いきなり脱線しちゃうんですが、ちょっと前に、boot2docker v1.3がリリースされ、ホストマシンからboot2docker上のDockerコンテナへディレクトリマウントが可能になりました。
また、同時にDockerコンテナを使用して開発環境を構築するための公式ユーティリティツールであるfigもv1.0がリリースされました。
これらを使用すると簡単にポコっと開発環境コンテナ群というものを立ち上げることが出来ます。(boot2docker+figの詳細は既にWebにあると思いますので割愛)

これまで開発環境にはVagrantを使用していたのですが、figを使うと簡単に全開発環境、いわゆる、ローカル環境、テスト環境みたいなものがそれぞれリポジトリをクローンして fig up とコマンド打つだけで再現出来るため、boot2docker+figに移行しました。

例えば、今開発中の案件だと以下のようなデーモン達が必要で。

これを以下のようなコンテナ群にして。

  • web (nginx + httpd + php + fluentd) → chef-containerでコンテナ作成後DockerHubへpush
  • web2 (nginx + nodejs) → chef-containerでコンテナ作成後DockerHubへpush
  • mysql → DockerHubから適当なやつ
  • memcached → DockerHubから適当なやつ
  • redis → DockerHubから適当なやつ
  • mongodb → DockerHubから適当なやつ

これらが fig up とすると立ち上がります。
さらにfigのlinkというオプションを利用すると、web1,2/etc/hosts に各バックエンドサーバーのIPアドレスと任意のホスト名を登録することが出来ます。
これにより、WAFによくあるバックエンド接続情報にその任意のホスト名を書いておけば、Dockerが動作するどの環境でも同じようにコードを変更することなく動作する環境が手に入るという感じです。素晴らしく使いやすいです。

chef-containerの話

で、chef-container。

Dockerコンテナの作成にはchef-containerを採用しました。
理由は、本番環境ではDockerコンテナを使わないからです。(ちょっと知見が足りな過ぎる気がしているのでまだ踏み切れないといった感じ。)
ただ、本番サーバーをプロビジョニングする必要は当然あるので、chef-containerを使っとくと取り敢えずレシピが残るという点で採用しました。

ただchef-containerは、コンテナ起動時に毎度プロビジョニングが実行されます。
これはまぁ仕方が無いけど正直微妙。コンテナスタンバイにまぁ数分かかっちゃう。(起動だけなら数秒なのに)

いやわかるんですけどね。
Dockeコンテナにinitデーモンが存在しない都合上、chefによってインストールされOS起動時に起動するよう設定されたデーモンを起動する術が無いから、chef-initが再度プロビジョニングすれば全部起動するよねという発想。だと思うんだけど。(cookbook_fileなどはコンテナ内にキャッシュされているものがコピーされる模様)

僕はこれを勘違いしていて、chef-containerで作ったコンテナはchef-initがプロビジョニングせずデーモンを次々起動してくれるものだと思っていて。
ただある日なんかコンテナ起動したのにブラウザでアクセスしても暫く繋がらない事案が発生してしまって。調べてみるとそういうことだった。(fig logs web1とかやると見れる)

まー割りとchefのレシピはある日突然動かなくなったりするので(特にyumリポジトリのURLが変わったりだとか、突然postfixが必要になったりだとか...)、毎度プロビジョニングも悪くは無いのかもしれないけれども。

そんなわけでDockerコンテナは開発から本番まで通して使用し、Dockerfileで構築するのがベストプラクティスな気がしたわけです。(公式まんまだけども)

そうなるとchefのレシピからDockerfileを生成出来ると嬉しいかもしれない。
Ansibleからなら比較的やりやすそうな印象あるがchefからは色々大変そうだな。。