k4200’s notes and thoughts

Programmer side of k4200

CentOS 6.3でのChef Soloの環境設定

はじめに

最近話題の(?)Chefの環境をCentOS 6.3上に構築し、レシピの書き方の基本的な事を説明する。

Chef Solo環境構築に関する公式ドキュメントはこちら

そこにOS別のインストールドキュメントがあるが、CentOSなどのRed Hat系はこちら。基本はこれに沿ってやっていくが、本記事では一部これとは違う内容もあるので注意。

Chefのインストール

RBELレポジトリというのを有効にする。

$ sudo rpm -Uvh http://rbel.frameos.org/rbel6

次にRuby関連のパッケージをインストール。

$ sudo yum install ruby ruby-devel ruby-ri ruby-rdoc ruby-shadow gcc gcc-c++ automake autoconf make curl dmidecode

ドキュメントだとRubyGemsはソースから入れることになっているが、これもyumで入れる。

$ sudo yum install rubygems

Chefはgem経由で入れることになっているが、これもyumで入れる。

$ sudo yum install rubygem-chef

※ドキュメントに沿ってRubyGemsとChefは別々のコマンドで入れたけど、rubygem-chefはrubygemsに依存しているので、実際にはsudo yum install rubygem-chefだけでrubygemsも勝手に入る。

先ほどのドキュメントで必要なのはここまで。それ以降はChef Clientの設定なので。

Chefのアーキテクチャ

ここでChefのアーキテクチャについて簡単に説明。これが分かっていないと、そもそも何をしているのかが分からなくなるので。こちらのページの上の方の図を参照。

例えば、Chefによって20台のWebサーバーと4台のDBサーバーを管理するとする。通常は、この24台に加えて、Chef Server(1台)とWorkstation(1台以上)が必要になる。

  • Node: Chefによって管理されるコンピューター。ここではWebサーバー20台とDBサーバー4台。
  • Chef Server: サーバーの設定情報(Cookbook)や、Nodeに関する情報などが入っている。
  • Chef Client: Nodeにインストールする必要があるプログラム。Chef Serverから命令を受け取って、各種処理を行う(パッケージのインストール、設定ファイルの更新などなど)。
  • Workstation: Cookbookを作成してChef Serverにアップロードしたり、Nodeの設定を変更したり、各種管理作業を行う端末。

これがフルセットのChefの構成なんだけど、分かる通りこれだと大掛かりでなかなか使うのが難しい。

今回説明するChef Soloは、それ単体で実行可能なしくみ。かなり大雑把に言うと、1台のコンピューターでChef ClientとWorkstationで実行するような内容を実行する。1台~数台のコンピューターを管理する場合には、まずはChef Soloで手軽に管理するのがいいかも。

Chef Solo用の環境設定

基本はこちらに沿ってやっていくが、一部違う部分もある。

自分のホームディレクトリにchef-soloというディレクトリーを作って、基本的には全てそこで作業するようにする。

$ mkdir ~/chef-solo
solo.rb

ここにChef Soloを使うための設定を書いていく。先ほどのドキュメントだと /var/chef-solo 以下のディレクトリーを指定しているが、今回は先ほど作った /home/user/chef-solo を指定する。

file_cache_path "/home/k4200/chef-solo"
cookbook_path "/home/k4200/chef-solo/cookbooks"
log_level :debug

node.json

次に node.json というのを作る。これはChef Soloの時だけ使うファイル。通常のChef ServerとChef Clientを使った場合、ノードの属性(= Attribute)はChef Serverに保存されていて、必要に応じてChef Clientから参照できるが、Chef Soloの場合にはそうした仕組みはないため、JSONファイルを作ってそこにノードの属性を記述する。

今回は以下の内容で。

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

Cookbook, Recipe等、用語の説明

ChefにはCookbook, Recipe等、色々な用語があるので、ここではWebサーバーの初期設定を行うというシナリオを例として、従来の方法と対比しつつ説明する。

こんなシナリオを考える

従来であれば、以下の様な自前パッケージを用意して、setup.shを実行してセットアップを行なうというのは割と一般的だったと思う(※)。

  • setup.sh
  • setup.sh によってコピーされる設定ファイル

setup.sh の中では以下の様なことを実行する。

  • OSの設定
    • webappユーザーを作成
    • iptablesを適切に設定
    • resolve.conf を自前パッケージのものと置き換える
  • Apacheの設定
    • httpd, mod_sslyum を使ってインストールする
    • httpd.conf を自前パッケージのものと置き換える
    • httpd.conf の中の Servername を、hostname コマンドの結果で置き換える

※あくまで例のために古臭い方法を取り上げている。実際はChefを使わなくても、Amazon Web Servicesの場合はカスタムAMIを作ったり、Red Hat系の場合はKickstartを使ったりして、ある程度自動化は出来る。ちなみに、それらとChefは排他的なものではなく、組み合わせて使うもの。

Chefだとどうなる?

これをChefで置き換えると、一番単純なパターンでは以下のようになる。

サーバーセットアップ用のCookbook(≒ディレクトリー)を作成し、その中に以下のファイルを用意する。

  • setup.sh のような役割をする default.rb という名前の Recipe
  • httpd.conf.erb という名前の Template
  • resolve.conf という名前の File

Recipeの中では以下を実行する。

  • Userというリソースを使って、webappユーザーを追加
  • httpd.conf.erb を元に /etc/httpd/conf/httpd.conf を作成
  • resolv.conf を /etc/ 以下にコピー

実際にChef Soloでやってみる

上で挙げたシナリオを、Chef Soloを使って(一部)実行してみる。

Cookbook の作成
$ knife cookbook create sample1 -c ~/chef-solo/solo.rb

これで、~/chef-solo/cookbooks 以下に sample1 という名前の Cookbook が作成される。Cookbook は単なるディレクトリーで、その中に各種ファイルやサブディレクトリが作成されている。

Recipe の作成

sample1/recipes の下に、default.rb を以下のように作成する。Rubyを触ったことがある人であれば(というかプログラマーであれば)、特に説明はいらないはず。

%w{httpd mod_ssl}.each do |pkg|
  package pkg do
    action :install
  end
end
Recipeの実行
$ sudo chef-solo -c ~/chef-solo/solo.rb -j ~/chef-solo/node.json

エラーが出なければOK。上のsolo.rbのところでlog_levelをdebugにしているので、エラーの場合色々ログが出ると思う。

これで、httpd と mod_ssl がインストールされたはず。rpm -q とかで確認しておく。

ここまでが、Chef Solo実行の超基本。

Recipeの作成をもう少し詳しく

基本が分かった所で、もう少しRecipeに色々書いてみる。

ファイルの単純な置き換え

先程の例のsetup.sh では /etc/resolv.conf を、こちらで指定したものに置き換えていたが、Chefバージョンでも同じ事をしたい。

まずはRecipeに以下を追記する。

cookbook_file "/etc/resolv.conf"

次に、sample1/files/default/resolv.conf というファイルを以下のように作成する。

domain foo.example.com
nameserver 192.168.1.2
nameserver 192.168.1.3

これでもう一度Recipeを実行すると、/etc/resolv.conf が、上の内容に置き換わる。

ファイルの中身を動的に変更する

今度は、httpd.conf をこちらで指定したものに置き換えたい。ただし、ファイルの中身は固定ではなく、一部環境によって異なる値を設定したい。

デフォルトの httpd.conf を、sample1/templates/default/httpd.conf.erb という名前でコピーする。

次に、httpd.conf.erb の Servername の部分を、以下のように書き換える。

ServerName <%= node['hostname'] %>

これが何を意味するかは想像付くと思うので説明は省略。

default.rb に以下を追記。

service "httpd" do
  supports :status => true, :restart => true, :reload => true
end

template "/etc/httpd/conf/httpd.conf" do
  notifies :restart, 'service[httpd]'
end

これは httpd というサービスの定義をして、httpd.conf を上で作ったhttpd.conf.erb の内容に置き換えて、httpd サービスを再起動する、という内容のRecipe。

これでもう一度 chef-solo を実行すると、期待する動作が実行されたはず。

構成要素の説明

上に出てきたような

  • cookbook_file
  • package
  • template
  • service

というのは、全て Resource と呼ばれる。ChefではRecipeの中で様々なResourceを使って、Nodeの設定を行なっていく。その他にどのようなリソースがあるかは、こちらのドキュメントを参照。数が多いので一度に全部覚えようとせず、必要なものを順次調べていけば良いと思う。

この後やること

ここまでやれば、Chefの基本的な内容は理解できたはず・・・

この後は、その他のResourceの使い方や、今回ほとんど説明していないAttributeやData bagなどについて調べてみるといいかも。

その後に、Knife Soloというのを使ってもいいし、Nodeが多ければChef ServerとWorkstationを構築して、本格的なChef環境を構築するという選択肢もあり。

まとめ

今回の記事では、最初にChefのアーキテクチャについて簡単について説明した。Chefをスタンドアローンで実行するChef Soloの環境を構築し、簡単なレシピの作成を通じて、いくつかのResourceの基本的な使い方を学んだ。

Chefはドキュメントは整備されているが、仕組みが結構複雑でなので、それを理解していないと、チュートリアル的なドキュメントを読んでも何のチュートリアルなのかがさっぱり分からずに詰まってしまう事が多い。まずはChef Soloで基本的な仕組みを理解しておくと、その後の学習がスムーズだと思う。