Chef を学んで使ってみた
空前の DevOps ブームに乗り遅れてはいけないとChefを学び、お客様の次期サーバーやRuby on Rails教育で使うサーバーを構築してみました。
感想
今回、お客様の次期サーバーを作るにあたりChefを使ってみたたところ、一度recipesを作ってしまえば サーバー環境が 10 〜30分くらいで自動的に出来てしまうのは画期的だと感じました!
私は教育・開発者なので、新しいサーバーの構築は年に数回、管理しているサーバーは数台程度です。従来はサーバーの構築・管理は手動で行い、作業内容をメモファイルに残していました。また、再度使う可能性があるサーバー環境はEC2のイメージとして保存して来たりしました。
しかし、作業のメモは必ずしも完璧ではないですし、メモを見落としてインストールに失敗する事もままありました。また保存してあるイメージですが、RubyやRailsがバージョンアップし教育では使えなくなってしまう事もあります。
手動でサーバー環境を構築しようとすると半日仕事になってしまいますが、Chefがあれば 10 〜30分くらい。しかも勝手にやってくれます。今までは、環境構築がおっくうで一つのサーバーに色々なアプリをrbenvとかを駆使して動かしていましたが、コスト面で問題がなければクラウドやVPSでサーバーを立ち上げ、すぐに環境が作れてしまいます。
また、recipe はコードなので少し考えて作っておけば再利用が可能で、新たな環境用に Chef も比較的短時間で作れます。
私のように、頻繁にサーバーを構築する事のない開発者も学んだ方が良い技術だと思います。
学び方
入門
入門は、やはり naoyaさんの 入門Chef Solo を読みましょう。原理的な事から実践的な事までがコンパクトにまとっまている良い書籍だと思います。私は kindle版が出た時に買ってしまったのでMacの横にiPadを置きKindleアプリで見ながら作業をしましたが、今なら 達人出版会からPDF(EPUB)版を買えば PC, Mac で見ながら作業出来るので、こちらがお勧めです。
実際に作ってみる
実際にrecipe作る際には、
- リファレンス: http://docs.opscode.com/chef/resources.html Resources, Recipe DSL は(長いですが)一回眺めておくと良いと思います。
- 参考になる公開されたcookbook: http://community.opscode.com/cookbooks
- Stack Overflow: 何か困ったら chef XXXX で検索し Stack Overflow を眺めると、とても参考になります
Recipe作りの基本
Resources
詳細は、入門書やリファレンスを読むとして、実際に Ruby on Railsアプリを動かすサーバーを構築するにはよく使う 以下のResources (Ruby DSL) を recipe に並べるだけです。
- package: OSのパッケージ(apt, yum) 等のインストール
- gem_package: RubyGemsのインストール
- cookbook_file: 設定ファイル等の作成、用意した設定ファイルのコピー+α
- template: 設定ファイル等の作成、設定ファイルをテンプレート化(Ruby のERB)出来るの汎用性がある
- remote_file: ネット上からファイルをダウンロードする
- file, directory: ファイル、ディレクトリーの作成
- user, group: Unixのユーザー、グループの作成
- service: デーモン(サーバープロセス)の起動、停止・・・
- execute: OSコマンドを実行することで上記の Resources では出来ないような操作を行う
べき等性 (冪等性, idempotence)
Chefのrecipeでは既にrecipeと同じ状態になっている場合は、何も行わないという べき等性を保つようにrecipeを作る必要性がります。
これは、Chef がインストールツールではなく、サーバー等の環境の変更を管理する為のツールだからです。packageをはじめ殆どのResourceは、既にインストールされている場合は何もおきません。
ただし、execute などは自分でべき等になるように作る必要があります、その為の仕組みが幾つかあります。
- creates属性: executeを実行した場合に出来るファイルを書いておくと、そのファイルがある場合は execute が実行されません
- only_if, not_if属性: 書かれたRubyの式、またはshellコマンドの文字列を実行した結果で実行する・しないを制御出来ます
Notifies
設定ファイルが作成・変更された時だけサーバーをリスタートする事が良くあります、このような場合は以下のサンプルのように設定ファイルを作るresource内に notifies を書くことで、設定ファイルが作成・変更された時にサーバーのリスタートを実行できます。
ちなみに、service "mysql" do 〜 のactionがnothingになっているので、最初に service "mysql" do 〜 が実行される際には何も起きません。
service "mysql" do supports :status => true, :restart => true, :reload => true action :nothing end cookbook_file "/etc/mysql/conf.d/character_set_utf8.cnf" do source "character_set_utf8.cnf" owner 'root' group 'root' mode 0644 notifies :restart, 'service[mysql]', :immediately end
Ruby
recipe は Rubyのコードなので、当然 Rubyの式、変数、メソッド(関数)が使えます、何度も出てくるパス名や処理は変数やメソッドを使うとメンテナンス性の高い recipe になります。 ただし、resource内で呼び出すメソッドは libraries ディレクトリーに置きます。
repository > cookbook > recipe
複数のrecipe が集まり cookbook になり、複数の cookbook が集まりrepository になります。 したがって、一つ recipe ファイルはある程度の粒度(作業単位)で書き、cookbook, chef を分ける事が再利用性の高い recipe 作りに役立つと思います。
Chef Cookbooks
http://community.opscode.com に既に作られたrecipe (Cookbooks) がたくさんあります。naoyaさんの本にもChef初心者はCookbooks を使わずに自分で recipe を作った方が良いと書かれていますが、私もその通りだと思います。
一般的にCookbooksにあるものは汎用的で高機能ですが、自分専用の環境を作ったりする際には resouces や LWRP を使い recipe を作った方が勉強になるだけでなく、後々のバージョンアップ等でトラブルが起きにくいと思います。
私の勉強のために iptablesの設定に simple_iptables を使ってみましたが、自分でシンプルなrecipeを書いた場合に比べ良いのかは疑問です ;-)
ちなみに、Cookbooksは http://community.opscode.com/cookbooks ここで検索すると、評価(rating)やダウンロード数が判るので、どれを使うかの参考になると思います。