chef-solo と knife-solo を使う

2013-03-21追記

この記事は古くなっています.

knife-solo 0.1.0よりknife-soloのコマンドの名前空間が"knife solo"に移動しました.以前のkitchen, cookコマンドはdeprecatedになっています.

https://github.com/matschaffer/knife-solo/blob/master/CHANGELOG.md#changes-and-new-features-2

今月のSoftware Designを読んでChefに興味出たのですが,管理するサーバが数台しかない場合はChefサーバの立ち上げが面倒です.そんな場合はスタンドアロンで動作するchef-soloを使う訳ですが,chef-soloの運用を補助するknifeのプラグインであるknife-soloが便利っぽかったので,Chefのお勉強のついでに試してみました.

まずchefとknife-soloをインストールします.

$ gem install chef
$ gem install knife-solo

knifeの初期設定を行います. 今回はChefサーバは使わずchef-soloのみを使うのですべてデフォルトのままでOKです.

$ knife configure

次に kitchen コマンドでkitchenを生成します.

$ knife kitchen my-kitchen

kitchen は chef-solo を動かすためのファイル一式を格納したもので,以下のようなディレクトリ構成になっています.

.
└── my-kitchen
    ├── cookbooks
    ├── data_bags
    ├── nodes
    ├── roles
    ├── site-cookbooks
    └── solo.rb

キッチンのディレクトリに移動してクックブックを作成します.

$ cd my-kitchen
$ knife cookbook create hello -o cookbooks/

クックブックのディレクトリには以下のファイルが格納されます.

  • Recipes ソフトウェアのインストールや設定ファイルの生成など,サーバに対する処理を記述したRuby DSL形式のファイル.
  • Templates 設定ファイルのひな型となるERB形式のファイル.
  • Attributes レシピやテンプレートで使う変数を定義する.
  • Definitions ユーザが定義したResource.ここで定義したものはRecipeの中で使うことができる

他にもLibrariesやMetadata,Filesがあります.http://wiki.opscode.com/display/chef/Cookbookshttp://jp.rubyist.net/magazine/?0035-ChefInDECOLOG#l12 に詳細が載っています.

次にRecipeを作成します.今回は

  • Apacheのインストール
  • ドキュメントルートにchefで生成したindex.htmlを置く
  • Apacheの有効化と起動

の以上3つを行うレシピを書いてみます.

./my-kitchen/cookbooks/hello/recipe/default.rb

package "apache2" do
  action :install
end

template "/var/www/index.html" do
  source "index.html.erb"
  mode 0644
end

service "apache2" do
  action [ :enable, :start ]
end

packageやtemplate等の命令はResourceといいます.Chefではあらかじめ様々なResourceが定義されており,一覧が http://wiki.opscode.com/display/chef/Resources にあります.

次にindex.htmlのテンプレートを書きます.ここではデフォルトで定義されている変数からOSやIPアドレスなどの情報を出力してみます.

./my-kitchen/cookbooks/hello/templates/default/index.html.erb

<!DOCTYPE html>
<html>
  <head>
    <title>hello, world</title>
  </head>
  <body>
    <p>
      あなたの予想に反してこのページが見えているでしょうか?
    </p>
    <ul>
      <li>OS: <%= node[:platform] %> <%= node[:platform_version] %></li>
      <li>IP Address: <%= node[:ipaddress] %></li>
      <li>Hostname: <%= node[:hostname] %></li>
      <li>Recipes: <%= node[:recipes] %></li>
    </ul>
  </body>
</html>

ここまでの作業でクックブックが一応完成しました. クックブックの動作をテストをするため仮想マシンを立ち上げます.今回はVagrantを使用しました.ゲストOSはUbuntu 12.04です.

$ vagrant box add base http://files.vagrantup.com/precise64.box
$ vagrant init

Vagrantfile は以下のようにしました.

./Vagrantfile

Vagrant::Config.run do |config|
  config.vm.box = "precise64"
  config.vm.network :hostonly, "192.168.33.10"
end

Vagrantfileの設定が終わったら仮想マシンを起動して knife prepare コマンドでサーバにchefの実行環境をセットアップします.

$ vagrant up
$ knife prepare vagrant@192.168.33.10

セットアップが完了すると,キッチンのnodesディレクトリにJSONファイルが生成されます.このファイルに実行するレシピのリストを記述します.

./my-kitchen/nodes/192.168.33.10.json

{ "run_list": ["recipe[hello]"] }

JSONファイルを編集後,ホスト側で knife cook を実行するとSSH経由でクックブックを実行します.

$ cd my-kitchen
$ knife cook vagrant@192.168.33.10

実行後, http://192.168.33.10 にアクセスできれば成功です.

f:id:st63jun:20121011002737p:plain