2011/05/23

Chefでサーバのセットアップ・管理作業を楽チンにしよう~構成編~


どうもhiroshiです。こんなに更新が早くてすみません。

今回もChefについてです。

前回の選定編に続いて、今回はChefの構成を見てみます。もちろんこれも「tommy report in Oct. 2010」からの抜粋です。

5/26 追記)この記事はv0.9.12に基づいてます。

Chefの構成の概要図
こんな感じです。


ツール群
<chef-server>
情報を集約して管理するサーバプロセス。各ClientとはJSON/RESTスタイルで通信する。

<chef-client>
設定を適用する各マシンにインストールされるデーモン。定期的にchef-serverをポーリングして、その内容に従ってレシピを実行する。

<chef-solo>
サーバ無しでレシピを実行するツール。

<knife>
chef-serverに登録されている情報の取得・変更を行うツール。切り刻むよ。

<webui>
chef-serverのWebインターフェース。なんか上手くログインできないので無視。


ということでうちではwebui使ってません。「それは大いなる損失だよ!」ということがありましたら是非教えてください。


主な構成要素
<Cookbook>
Recipe,Template,Attributeなどをひとまとめにしたディレクトリ。ソフトの種類毎に作るのがお約束ぽい。

<Recipe>
実行内容の定義本体。RubyのDSLで記述する。

<Resource>
Recipe内で行う操作を抽象化して宣言文ぽくしたもの。パッケージ管理、デーモン管理、ファイル管理、コマンド実行などが用意されている。


<Template>
設定ファイルを生成するためのテンプレート。中身は eRuby。


<Attribute>
環境依存の処理を吸収するための変数。


<File>
バイナリファイルなど、単にコピーして使うためのファイルを置くところ。


<Metadata>
Cookbookの説明とかのメタ情報。


<Role>
複数のRecipeをまとめて「役割」として定義するためのもの。


<Node>
chef-serverから見た管理対象のマシンのこと。


<run_list>
Nodeに対して適用するRoleやRecipeを指定したリスト。


<Client>
chef-serverにアクセスするツール類のこと。


なんやらいっぱいありますが、すぐ慣れます。寄生獣の後藤も「何事も慣れだ」と言ってました。これ、言うの2回目ですね。
とにかくRecipeです。普通7割くらいRecipe書くのに時間使います。
TemplateとFileは使い分けが若干微妙なところがでてくるかもしれませんが、書き換え可能なファイル(つまりテキストファイル)はTemplate、そうじゃないのはFileというルールでやってます。

例えばapacheなら、http-2.2.xx.tar.bz2はFileだし、httpd.confはTemplateの下に置いとくって感じです。


Attributeについて
レシピで使える属性値は大きく2種類に分かれます。
  1. Nodeの属性値。Nodeから収集した様々なパラメータ(IPとか)がツリー状のデータとして取得できるので、レシピで条件分けに使う。またknifeコマンドでも参照できる。
  2. 自前で設定する属性値。
    1. デフォルト値はCookbookのattributes/*.rbで定義する。
    2. RoleやNodeに対して、デフォルトの設定値を上書きする値を設定できる。これで一部のマシンだけ別設定みたいなことが実現できる。
1についてですが、具体的にはこんな感じです。
$knife node show {domain}
~前略~
    "platform_version": "5.x",
    "fqdn": "hoge.example.jp",
~中略~
    "domain": "xxx.xxx.xx",
    "os": "linux",
    "idletime": "13 days 13 hours 28 minutes 20 seconds",
    "network": {
      "default_interface": "eth0",
      "interfaces": {
        "lo": {
          "flags": [
            "UP",
            "LOOPBACK",
            "RUNNING"
          ],
          "addresses": {
            "::1": {
              "scope": "Node",
              "prefixlen": "128",
              "family": "inet6"
            },
            "127.0.0.1": {
              "netmask": "255.0.0.0",
              "family": "inet"
            }
          },
          "mtu": "16436",
          "encapsulation": "Loopback"
        },
        "eth0:xxx.xxx": {
          "flags": [
            "UP",
            "BROADCAST",
            "RUNNING",
            "MULTICAST"
          ],
~後略~
該当ホスト上でコマンド打ったら取れるような情報は全部入ってるんじゃないでしょうか。

例えば以下はapacheのconfファイルですが、まいど自FQDN名を設定するところがありますが、そんなときにこんな感じで使えます。
# Server port for sending active checks
ServerRoot      "/usr/local/apache"
ServerName      <%= node[:fqdn] %> ←ココ!!

2について、たとえば基本的にapacheのバージョンは2.2.xxを利用する、ということにします。そういう場合、cookbook/apache/attributes/default.rbに
default[:apache][:version] = "2.2.xx"
と書いておいて、apacheのrecipeに
buildtool_make_install "apache" do
  action :install
  tarball node[:apache][:tarball]
  srcdir "httpd-#{node[:apache][:version]}" ←ココ!!
  config_option configure_option()
  not_if {check_compile_setting}
  notifies :create, "template[/etc/httpd/httpd.conf]"
  notifies :restart, "service[httpd]"
end
と書いておけば、基本的にはこの2.2.xxのapacheをインストールさせることができます。

「そんなんじゃ、わかんねーよ!」って思った方、、、、ですよねー。そうだと思います。。
とりあえず、現時点ではなんとなく、で通り過ぎていただければ幸いです。。

ちょっと今回はこのあたりで切り上げます。

次回は、適当なcookbookを例に取って説明ができたらいいな、という「実践編」を書きたいと思いますが、その際、またこの「構成編」の内容をちょくちょく振り返りつつになる気がします。

chefって、一回やってみないと全体像が見えにくいんですよねー。ぼくは3回くらいやってようやく見えてきました><


というわけで、最後に女子力上げたところでまた次回にさせてください~。