Chef-Solo で PHP をインストールしてみた
開発環境、ステージング環境、本番環境と似たような環境を構築する機会は多いわけで、このあたりを自動化したいとは前々から思っていたんですが。
今回 PHP(と pear のパッケージいくつか)をインストールするために Chef というやつを使ってみたので、これについて書いてみます。
結論としては、いちおうインストールできましたが、結構いろいろ難ありでした。
Chef とっかかり
システム自動管理ツールについて
システム自動管理ツールというと Puppet が有名です。システムの構成を自動化するだけであればスクリプトなんかでもできないことはないんですが、Puppet 導入の利点として
では
- 使い捨てスクリプトの量産を防ぐことによる手間の軽減
- 管理タスクを誰もが同じ形で定義でき,管理品質を均一化できる
- 管理タスクを誰もが見える形で定義でき,変更履歴の追跡や監査が可能になる
というのが挙げられています。
個人的にいいなと思ったのは、この 3 点目で。Puppet Dashboard や Redmine の Initr プラグイン を使うと、ブラウザからノードの一覧と役割が一望できて、サーバ構成を説明する手間が省けるんじゃないかなと期待していたのでした。
Puppet じゃなくて Chef?
ということで Puppet を使いたくなったわけですが、
を読んでしまいまして。自分が使うなら Chef のほうかなと。
Rails に慣れている身なので、設定ファイルが内部 DSL(Ruby スクリプトとして動作する)のは魅力的です。文法を覚えなくていいのと、柔軟/簡潔な文法で書けることが約束されているので。
Ruby に詳しくない人間に展開することを考えると、外部 DSL である Puppet のほうが強いのかなという気もするんですけど・・・Capistrano なんかでも Ruby の内部 DSL は使われているわけで、Ruby をメインで使わない人も覚えてても損はしないんじゃないかと思います。
Chef の参考 URL
使い方がイメージできなくていろんなサイトを見て回ってました。いくつか挙げておきます。
- Chefを最速で使いこなすためのいくつかのポイント - Masatomo Nakano Blog
- 上記の続きになるエントリ。用語の補足説明とか。
- ここからリンクされてるスライドも機能をひととおり知るのによいです。
- サーバの構築作業やシステム管理を自動化する「Chef」|サイバーエージェント 公式エンジニアブログ
- こちらも入門記事で、概要が簡潔に書かれてます。
あとは細かい使い方で迷ったら、公式のドキュメントを読み進めるのが一番手っ取り早かったです。Web 上には情報少ないので。
今回の方針
今回はサーバを使わない Chef-Solo を試してみました。
サーバを使わなかった理由ですが、公式のサーバは
Sign up today to manage up to 5 nodes free.
とか書いてあって制限が面倒に思えたのと、自前サーバのインストールは
によるとすごく大変みたいなので。
サーバを使わないといろいろと活かせないようなんですけど、まずは手始めということで。
今回 Chef や PHP を導入したサーバについて
Rails アプリのデモ用に用意した CentOS 5.5 の環境です。Git や REE(Ruby Enterprise Edition)等がインストール済みのところで検証してしまったので、クリーンな環境では動作しないところがあるかもしれません。
PHP のインストール時には内部で yum install php みたいなコマンドが走ります。--enablerepo 等のオプションなしで目的の PHP がインストールできる環境は、あらかじめ整えておく必要があります。(※デフォルト設定の場合です。ソースからインストール方法もあります。)
Chef-Solo による PHP のインストール
を見比べながらやりました。
rvm、MRI Ruby のインストール&有効化
(追記)※REE が入っていたので rvm 使いましたけど、まっさらな状態であれば yum 等でインストールできる ruby 1.8.7 等で問題なく動作すると思います。
(さらに追記)yum で普通に入れると 1.8.5 が入るみたいですね。あと RVM の利用には git が必要みたいです。
REE が入っている環境だと書きましたが、REE で chef を動作させると pear モジュールのインストールに
/opt/ruby-enterprise-1.8.7-2011.03/lib/ruby/gems/1.8/gems/chef-0.9.14/bin/../lib/chef/shell_out.rb:381:in `fork': Cannot allocate memory - fork(2) (Errno::ENOMEM)
のようなエラーが発生して、うまく動作しませんでした。
については動作したものの
については動作しませんでした。
なので、今回は RVM(複数の Ruby を共存させるツール)を利用して
# 2011-04-25 URL 変更 #bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head ) bash < <(curl -s https://rvm.beginrescueend.com/install/rvm) rvm install 1.8.7
として MRI Ruby 1.8.7 をインストールしておいて、
rvm use 1.8.7
ruby --version
として 1.8.7 を有効化&正しく使われていることを確認しておきました。
Chef のインストール
gem install chef --no-rdoc --no-ri
で Chef をインストールします。依存モジュールが多いので --no-rdoc --no-ri しておいたほうが時間かからなくてよいです。今回は chef 0.9.14 がインストールされました。
solo.rb の配置
参考 URL では .chef/solo.rb や ~/solo.rb が使われていましたが、マニュアルの最後のほうに書いてあるとおり、デフォルトの /etc/chef/solo.rb に置くことにします。
mkdir /etc/chef cat <<\EOS > /etc/chef/solo.rb file_cache_path "/var/chef-solo" cookbook_path ["/var/chef-solo/site-cookbooks/opscode", "/var/chef-solo/cookbooks"] EOS
cookbook_path はサンプルに少し変更を加えて site-cookbooks を追加しています。(理由については後述します。)
なお、パスはフルパスで書かないとエラーになる(/root を ~/ と書いたりはできない)ようなのでご注意ください。
opscode の cookbook 取得
opscode で cookbook が多数提供されているわけですが、インストールする際は自動的に cpscode が参照されるものの、レシピを参照したいような場合はうまく参照できないようです。
仕方ないので、
cd /var/chef-solo
git clone git://github.com/opscode/cookbooks.git site-cookbooks/opscode
として自前でレシピを取得しておきます。(前の手順で solo.rb で追加したのはこのパスです。)
当初は solo.rb に
recipe_url "https://github.com/opscode/cookbooks/tarball/master"
と書けばいけるかなと期待したんですけど、file_cache_path 配下に opscode-cookbooks-24226fd みたいなディレクトリが作成されてしまい、うまくいきませんでした。
この状態で
chef-solo
を実行すると、エラーなしで終了するはずです。(もし問題が発生して原因がわからない場合は -l debug オプションを付加すると、もう少し詳細なログが出力されるようになります。)
php のレシピ修正(CentOS/Redhat の 32 bit OS の場合のみ)
(2011-04-23 追記)レシピが修正されたようなので、最新版を使えばこの項の修正は不要なはずです。
困ったことに、レシピの templates/centos/php.ini.erb にライブラリのパスが
extension_dir = "/usr/lib64/php/modules"のようにベタ書きされており、32 bit OS だとうまく動作しません。(centos だけでなく、redhat のほうもそうなっているようです・・・。)
apache2/recipes/default.rb に
if node[:kernel][:machine] == "x86_64" libdir = value_for_platform("arch" => { "default" => "lib" }, "default" => "lib64") else libdir = "lib" endこのような処理がありましたので、これに倣って /var/chef-solo/site-cookbooks/opscode/php/templates/centos/php.ini.erb を以下のように変更しておきます。(Redhat の場合はたぶん redhat/php.ini.erb が使われるので、そちらを修正してください。)
diff --git a/php/templates/centos/php.ini.erb b/php/templates/centos/php.ini.erb index 747b518..246b355 100644 --- a/php/templates/centos/php.ini.erb +++ b/php/templates/centos/php.ini.erb @@ -526,7 +526,11 @@ doc_root = user_dir = ; Directory in which the loadable extensions (modules) reside. +<%- if node[:kernel][:machine] == "x86_64" -%> extension_dir = "/usr/lib64/php/modules" +<%- else -%> +extension_dir = "/usr/lib/php/modules" +<%- end -%> ; Whether or not to enable the dl() function. The dl() function does NOT work ; properly in multithreaded servers, such as IIS or Zeus, and is automatically @@ -1218,4 +1222,4 @@ soap.wsdl_cache_ttl=86400 ; Local Variables: ; tab-width: 4 -; End: \ No newline at end of file +; End:(追記)いちおう報告しておきました。
node.json の配置
参考 URL によると chef-repo\.chef\chef.json や ~/node.json になっていましたが、
を見た感じだと、ノード毎の設定は /etc/chef にまとまっているようなので、 /etc/chef/node.json を作成することにします。
cat <<\EOS > /etc/chef/node.json { "run_list": [ "recipe[portal_site_php]" ] } EOS
今の案件ではいくつかサイトがあるんですが、その中のポータルサイト用 PHP 環境ということで、今回は portal_site_php という名称でレシピを作成することにしました。
この状態で
chef-solo -j /etc/chef/node.js
PHP インストール用の cookbook 作成
cd /var/chef-solo rake new_cookbook COOKBOOK=portal_site_php
として cookbook を作成します。(参考 URL に記載があったとおり、サーバを使っていないので knife は使えず、rake で代用しています。)
を参考にしつつ、
の末尾に以下のように設定を追加します。(モジュールその他のオプションは環境に合わせて変えてください。)
include_recipe "php" package "php-pgsql" do action :install end %w(mdb2 mdb2_driver_pgsql Pager HTTP_Upload xml_serializer-beta Crypt_Blowfish).each do |package_name| php_pear package_name do action :install end end php_pear "Mail" do version "1.1.14" action :install end php_pear "Mail_Mime" do version "1.5.2" options "--nodeps" action :install end php_pear "Mail_mimeDecode" do version "1.5.0" options "--nodeps" action :install end
php_pear 内部で pear コマンドが呼ばれるので、pear のインストールを保証するために include_recipe "php" を実行しています。
また、必須ではないようですが cookbooks/portal_site_php/metadata.rb 末尾に以下を追加しておきます。(ついでに他の属性もそれらしく変更しておいたほうがいいと思います。)
depends "php"
この状態で
chef-solo -j /etc/chef/node.json
とすると、
のインストールが行われるはずです。
ちなみに 37signals のほうにも PHP の cookbook はあったんですが、PEAR に対応してない&ちょっと特殊な設定みたいなので opscode のほうを使いました。
問題点
今後やりたいこと
その他気になる情報
- Cookbook Shelves - Composable Configurations
- 外部の shelve を使う方法。
- 今回は cookbook_path を増やす形で対応しましたが、特定の cookbook を使いたいだけならこの方法で動作すると思います。
- 大規模システム運用でpuppetやchefだけでは解決しづらいことを解決するMCollective! - よかろうもん!
- Chef だけだと運用が難しい部分が出てくるらしい。
- 導入しても使われないと悲しいので、こういうのも検証しておきたい。
- Comparison - puppet wiki (パペウィキ) - Trac
- デプロイツールの比較。
- 今は Capistrano を使ってないからいいけど、両方使うようになったら使い分けを考えないと。
2011-06-02 追記
環境の構築についていろいろ書きましたが、もっと簡単にセットアップできるようにしてくれている方が。
CentOS5上にChef環境を用意するためのYumレポジトリを用意したので、 それを使って手っ取り早く試してみます。
ただし、今回は64ビット版のみしかYumレポジトリを用意していないため、OSはCentOS 5.3 64bit Plainを選択してください。
とのこと。CentOS 64-bit を使っている方はこれを使わせてもらうとよさげ。
「Chef のサーバ構築はすごく大変」と書きましたが、Capistrano ですぐに行えるようにしているそうで。Chef 以外にも活かせそうなノウハウですね。