Dockerfile + chef-solo
既存のChefレシピをDockerfileに流用してみます。
Dockerコンテナそのものは状態を持たない(ステートレス)ように動かすのが良さそうなので
mysqld等のRDBMSを始めとした状態を持つ(ステートフル)なイメージは作成しません。
またserviceコマンドで利用される/etc/init.d配下のスクリプトはDockerコンテナ内では利用できないのが注意です。
↑使えました
docker run実行時に起動スクリプトを用いずプロセスを起動する必要があります。
そのためchefのserviceリソースは流用できませんが(意味ない)
package, template, attribute等のパラメータを設定するためのリソースは流用できるのでDockerイメージの作成に十分役立つと考えています。
さて作成順序は以下のとおりです。
- Berkshelfで利用するCookbookを取得して一つのディレクトリ内に集約する
- Dockerfileを作成する
- docker buildでDockerイメージを作成する
環境: OS X@boot2docker(docker v0.8.1)
- 作業ディレクトリの構成
こんなかんじです。使わないcookbookが転がってるけどきにsない
orenomac$ tree -L 2 . ├── Berksfile★ ├── Dockerfile★ ├── Gemfile ├── README.md ├── Vagrantfile ├── cookbooks ├── data_bags │ └── sensu ├── environments ├── nodes │ └── webserver.json ├── roles │ ├── sensu-client.json │ └── sensu-server.json ├── site-cookbooks │ ├── apache │ ├── base-cookbooks │ ├── mysql │ ├── php │ └── redis ├── solo.rb └── vendor
- Berkshelfでcookbooksの取得
opscodeやローカルのsite-cookbooksにあるcookbookをcookbooks/以下に取得します。
Dockerイメージには導入してないcookbookばかりで業が深い。
※ こちらはBerkshelf 3.0以降では使えません!
$ cat Berksfile site :opscode cookbook "yum" cookbook "yum-centos" cookbook "yum-epel" cookbook "yum-percona" cookbook "yum-elrepo" cookbook "yum-repoforge" cookbook "yum-ius" cookbook "yum-pgdg" cookbook "td-agent", git: "https://github.com/treasure-data/chef-td-agent.git" cookbook "nginx" cookbook "sensu" cookbook "auditd" cookbook 'base-cookbooks', path: 'site-cookbooks/base-cookbooks' cookbook 'apache', path: 'site-cookbooks/apache' cookbook 'php', path: 'site-cookbooks/php' cookbook 'redis', path: 'site-cookbooks/redis' cookbook 'mysql', path: 'site-cookbooks/mysql' cookbook 'chef-docker', git: "https://github.com/bflad/chef-docker.git" $ berks install --path cookbooks
- node.jsonの作成
webserverというノードアトリビュートでサーバを作ります。
epelリポジトリを導入してApacheとPHPをインストールするだけです。
$ cat nodes/webserver.json { "run_list": [ "recipe[yum-epel]", "recipe[apache]", "recipe[php]" ] }
- Dockerfileの作成
標準リポジトリよりcentosをpullしてomnibusインストーらーを使ってchef-soloをインストールしています。
Berkshelfで取得したCookbookやchef-repositoryに必要なデーター一式をDockerfileのADD構文でローカル->Dockerイメージへsyncしてるのが味噌です。
Dockerfileの構文は単純です。
また1構文毎にコミットポイントが設けられており、イメージ作成時に自動的にスナップショットが取得されるようになっています。
FROM centos MAINTAINER buta9999 RUN curl -L http://www.opscode.com/chef/install.sh | bash ENV CHEF_REPO /root/chef-repo WORKDIR /root/dockerbuild ADD cookbooks ${CHEF_REPO}/cookbooks ADD nodes ${CHEF_REPO}/nodes ADD solo.rb ${CHEF_REPO}/solo.rb ADD data_bags ${CHEF_REPO}/data_bags ADD roles ${CHEF_REPO}/roles RUN cd ${CHEF_REPO} && chef-solo -c ${CHEF_REPO}/solo.rb -j ${CHEF_REPO}/nodes/webserver.json
- イメージの作成
Dockerfileを作成したディレクトリを指定します。docker buildを実行するカレントにDockerfileを作るのが良さそうです。
デフォルトはcacheを利用します。成功したコミットポイントをスキップしてDockerfileの下行へ遷移していきます。
cacheを利用したくない場合は--no-cacheオプションを指定してdocker build構文を実行します。
$ docker build -t centos/webserver . Uploading context 3.108 MB Uploading context Step 0 : FROM centos ---> 539c0211cd76 Step 1 : MAINTAINER buta9999 ---> Using cache ---> 244e53897526 Step 2 : RUN curl -L http://www.opscode.com/chef/install.sh | bash ---> Using cache ---> 11cee5f445aa Step 3 : ENV CHEF_REPO /root/chef-repo ---> Using cache ---> ee8a750c7eb9 Step 4 : WORKDIR /root/dockerbuild ---> Using cache ---> cf42203ce8a3 Step 5 : ADD cookbooks ${CHEF_REPO}/cookbooks ---> ef938d1b58aa Step 6 : ADD nodes ${CHEF_REPO}/nodes ---> e522db37eeb8 Step 7 : ADD solo.rb ${CHEF_REPO}/solo.rb ---> bd3f354c0eaf Step 8 : ADD data_bags ${CHEF_REPO}/data_bags ---> 8c0dec6a99ac Step 9 : ADD roles ${CHEF_REPO}/roles ---> 567cadb0a3a4 Step 10 : RUN cd ${CHEF_REPO} && chef-solo -c ${CHEF_REPO}/solo.rb -j ${CHEF_REPO}/nodes/webserver.json ---> Running in 89b99a2f8cf7 [2014-03-11T13:57:26-04:00] INFO: Forking chef instance to converge... ・・省略・・ [2014-03-11T14:04:20-04:00] INFO: template[/etc/php.ini] sending reload action t o service[httpd] (immediate) [2014-03-11T14:04:20-04:00] INFO: Processing service[httpd] action reload (php:: default line 50) [2014-03-11T14:04:21-04:00] INFO: Processing template[/etc/php.d/redis.ini] acti on create (php::default line 42) [2014-03-11T14:04:21-04:00] INFO: template[/etc/php.d/redis.ini] backed up to /v ar/chef/backup/etc/php.d/redis.ini.chef-20140311140421.056733 [2014-03-11T14:04:21-04:00] INFO: template[/etc/php.d/redis.ini] updated file co ntents /etc/php.d/redis.ini [2014-03-11T14:04:21-04:00] INFO: template[/etc/php.d/redis.ini] sending reload action to service[httpd] (immediate) [2014-03-11T14:04:21-04:00] INFO: Processing service[httpd] action reload (php:: default line 50) [2014-03-11T14:04:21-04:00] INFO: Processing service[httpd] action restart (php: :default line 50) [2014-03-11T14:04:23-04:00] INFO: service[httpd] restarted [2014-03-11T14:04:23-04:00] INFO: Chef Run complete in 384.048111735 seconds [2014-03-11T14:04:23-04:00] INFO: Running report handlers [2014-03-11T14:04:23-04:00] INFO: Report handlers complete ---> ce84df388d67 Successfully built ce84df388d67
- イメージの確認
作成したイメージが表示されます
$ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE centos/webserver latest ce84df388d67 8 minutes ago 840.9 MB
制約はあるもののべんりです。
あとはpushして既に稼働しているサーバーへdocker pull.そしてEXPOSEポートの設定変更で大正義コンピューティングかと。
Dockerfileを用いてサーバを作る場合は、chefのノードアトリビュートに一気通貫レシピを書くのではなく
細かい単位で素早く流用できるようにコミットポイントを設けておくのが良いと思いました。
- ベースを作りコミット
- サーバロールごとにイメージを作りコミット
- 監視..とか?
眠くてよくまとまらなくなってきた。ひとまずここまで。