1.はじめに

こんにちは! ドワンゴのインフラ担当の氏家です。

ドワンゴは歌舞伎座タワーに在りまして、東銀座駅と地下で直結しています。そこからオフィスに向かうエレベータが並んでるんですが、一機だけは観光用の屋上庭園に向かう専用のエレベータがあり、ガイドさんが「こちらですよ」と案内してエレベータのボタンを押してくれたりします。

移転後の出社初日だけは「屋上庭園に行きますか?」と聞かれたのですが、それ以降は、パッと一目確認されると、何かを察してか何も言われなくなってしまいました。まあ屋上庭園に行く人とは客層が違うから当たり前ですよね。。

さて今回は実際に実際にKnife Soloを使ってChef Soloを実行するまでを解説したいと思います。

2.Chefの実行に必要なファイルを作成
2−1.Cookbookの作成
Cookbookは複数のrecipeを含みます。
recipeはセットアップの手順書で、Cookbookはそれらrecipeとそれ以外にセットアップに必要なものがまとまった集合体です。Cookbookは"apache"や"mysql"といった単位で作成します。
Cookbookのひな型は、前回の記事のように 作成したchefリポジトリのディレクトリ内に入り、下記のコマンドを実行すると作成されます。
knife cookbook create [cookbook名] -o [作成先ディレクトリ]
※Cookbookを作成する度に必ずやる必要はなく、既にあるCookbookをコピーするだけでも構いません

例えば、下記のように実行すると
$ cd [リポジトリ]  #リポジトリとは、前回の記事で"knife solo init"で作ったディレクトリをさします
$ knife cookbook create apache2 -o cookbooks
[リポジトリ]/cookbooks/apache2/ にひな型が作成されます。

上記で作成されるディレクトリがたくさんあり混乱してしまいますが、これはほぼ必ず使うっていうものだけリストアップすると、recipesattributestemplatesの三種だけです。

ちなみにいまさらですが、用語について、
 Chef=料理人 Cookbook=料理本 Recipe=料理のレシピ
で"セットアップ"を "料理"に例えたんでしょうが、個人的にはかえってこの用語の方が混乱してしまうような気もします。attributeとかtemplateとかは料理と関係ないですし。

2−1−1.Cookbookの要素

recipe:
一番肝心なもので、セットアップの手順を書いておくスクリプトファイルです。recipeはなるべく汎用的に書きます。

attribute:
そしてサーバーごと に異なる設定値はなるべく外出しします。それがattributeです。例えばapacheでいえばhttpd.confの中の設定値とかですね。

template:
erbという、テキスト内にruby構文を埋められる形式でファイルを作成します。ruby構文を用いて、attributeの値を動的に取り込むことができます。

2−1−2.実例

[リポジトリ名]/cookbooks/apache2/templates/default/httpd.conf.erb
ServerRoot <%= @server_root %>

[リポジトリ名]/cookbooks/apache2/attributes/default.rb
default['apache2']['server_root'] = "/etc/httpd"

[リポジトリ名]/cookbooks/apache2/recipes/default.rb
template "/etc/httpd/conf/httpd.conf" do
    owner "root"
    group "root"
    mode  0644
    variables({
        :server_root => node['apache2']['server_root']
    })
end

これを実行すると、
 -rw-r--r-- root /etc/httpd/conf/httpd.conf
というファイルが作成され、中身は
 ServerRoot "/etc/httpd"
が書き込まれています。

2−1−3.defaultの意味
ここで1つ注意が必要なのが、Chefでは度々出てくるキーワード"default"です。
いくつか出てきますが、それぞれ意味が異なるので注意が必要です。

templates/default/
OSによって読み込むtemplate,attributeを分けたいときに使います。
  • templates/default/httpd.conf.erb
  • templates/ubuntu/httpd.conf.erb
recipes/default.rb
実行するrecipeを分けたいときに使います。

詳しくは次章で解説しますが、
 cookbooks/apache2/recipes/default.rb
を呼び出すときは、nodeと呼ばれるファイルに
 "recipe[apache2]"
と書きます。

例えばdefaultはパッケージからapacheをインストールするrecipeだとします。
一方ソースからコンパイルするrecipeが別途必要であれば、
 cookbooks/apache2/recipes/source.rb
に記述をし、呼び出すときは
 "recipe[apache2::source]"
と書く、といった使い分けをします。

attributes/default.rb
これは上記に関連しますが、recipe毎にパラメータを変えたい場合書きます。
 cookbooks/apache2/attributes/default.rb
 default['apache2']['server_root'] = "/etc/httpd"

 cookbooks/apache2/attributes/source.rb
 default['apache2']['server_root'] = "/usr/local/apache2"
2−2.nodeの作成
node(対象サーバー)に、実行するCookbookのrecipeを記述します。

[リポジトリ名]/nodes/192.168.1.1.json
{
        "run_list":[
                "recipe[apache2]"
        ]
}

これでChefを実行する準備ができました。
3.Knife Soloを用いてChef Soloを実行

Knife Solo実行するには次のようなことをします。
  • Cookbookなどのファイルを作業マシン上で作成
  • それをsshで対象のサーバーにファイル転送 (1)
  • 対象サーバー上でChef Soloを実行 (2)
ここで設定しておくことがあります。

(1)
ssh接続は、毎回rootでするわけにはいきません。セキュリティ上、直接rootアカウントにssh接続はできないようにするかと思います。また普通にやるとssh接続のパスワードが毎回聞かれてしまいます。
そのため、作業マシンでssh認証用の秘密鍵・公開鍵を作り、対象サーバーに公開鍵認証でパスフレーズ無しで接続できるアカウントを作るのがベストです。

(2)
Chefはサーバーへのインストールを行うためroot権限が必須です。そのため上記で作成したアカウントはNOPASSWDでrootになれるようにsudoersを設定する必要があります。

そのため、セットアップを行う前に対象サーバーで上で次のスクリプトを実行しましょう。
ADMIN_USER=[chefを実行するユーザーアカウント名]
useradd $ADMIN_USER -G wheel
sudo -u $ADMIN_USER sh -c "cd /home/$ADMIN_USER && mkdir .ssh && chmod 700 .ssh && echo \"[作業マシンで作成した鍵の公開鍵]\" > .ssh/authorized_keys && chmod 600 .ssh/authorized_keys"

echo '%wheel  ALL=(ALL)       NOPASSWD: ALL' >> /etc/sudoers

そうすれば以後は、作業マシン上で[リポジトリ]ディレクトリの中に入り
knife solo cook [ユーザーID]@[ホスト名]
を実行すれば、対象サーバーでChef Soloが実行されるようになります。

余裕があれば上記のユーザー作成もrecipe化してしまうとよいと思います。

4.補足1−attributeのオーバーライド

上記までで最低限の実行はできますが、roleを使うともっと設定の幅が広がります。
roleについては前回も説明しましたがおさらいでもう一度説明すると、”webサーバーで実行するrecipe"、"DBサーバーで実行するrecipe"をまとめることができます。

例えば
  • roles/web.rb には "recipe[apache2]", "recipe[php]" を記述
  • roles/db.rb には "recipe[mysql]" を記述
しておけば、
  • nodes/192.168.1.1.jsonで "role[web]" を記述
するだけで、apache2とphpがインストールされるわけです。「webサーバー」という役割のサーバーを複数台設定する場合、各nodeごとに"apache2"とか"php"とか書かなくてもすむので便利になりますね。

そしてこのroleにはattribute値も書くことができます。実はnodeにもattribute値を書くことができます。同じ変数名が定義されてると、
attributes/default.rb のattribute値 < role のattribute値 < node のattribute値
というような優先度になります。

例えばapacheのアクセスIP制限だと、
  • Cookbook自体は普通の汎用的なapacheサーバー向けに作ったので、デフォルトとなるattributeファイルは全公開として定義
  • roleは、社内専用のWebサーバーとして使うので特定のセグメントのみ公開
  • nodeは、「このサーバーだけは管理用サーバー」なので、さらに限定した範囲のみ公開
といった場合、次のように定義ができます。

apache2/attributes/default.rb
default['apache2']['allow_ip'] = "all"

roles/office_web.rb
default_attributes(
    'apache2' => {
        'allow_ip' => "192.168.0.0/16"
    }
)

nodes/192.168.1.1.json
{
    "run_list":[
        "recipe[apache2]"
    ],
    "apache2" : {
        "allow_ip" : "192.168.1.0/24"
    }
}

そうすれば、recipe内 では
node['apache2']['allow_ip']
の値が状況によって変化します。
※レシピ内ではattribute値は、"node[]"というハッシュに展開されます

5.補足2−recipeに書くリソース

2章で書いた、httpd.confを作成するときに
template "/etc/httpd/conf/httpd.conf" do
    owner "root"
    group "root"
    mode  0644
    variables({
        :server_root => node['apache2']['server_root']
    })
end
と書きました。
この1行目の"template"がリソースと呼ばれるものです。
templateリソースは、変数値を後で付加できるテンプレートファイルを作成する機能をもちます。

※なぜリソースというのか
Chefが何をするかというと、サーバーの状態を管理し、ノード(サーバー)をあるべき状態に収束させることです。
あるべき状態=ソフトウェアのセットアップのみでなく、ファイルを所定の場所に置いたり、設定値を書き換えたり、サービスを起動させたりします。
そのために必要なのがソフトウェアのパッケージだったり、設定ファイルだったり、サービスの起動スクリプトだったり、そういったリソースが必要です。
サーバーをあるべき状態にするために、レシピに、リソースを書くことで、収束させることができるわけです。
なので、サーバーをあるべき状態にするものをリソースといいます。
ただプログラマからしたら”メソッド”と覚えた方が直観的かもしれないですね。

このリソースには様々な種類があり、代表的なものをいくつかリストアップしてみます。
詳しくは公式サイトを参照ください。
  • bash…個人的には一番よく使うもので、要はbashが起動し任意のスクリプトを実行できます。
  • directory…ディレクトリを作成・削除できます。
  • file…任意の場所にテキストファイルを作成することができます。
  • package…packageをインストールします。OSによってrpmだったりdebだったり。
  • remote_file…http経由でファイルをダウンロードします。
  • user…ユーザーを作成します。
ただ、結局標準で提供されてるリソースでは機能が足りないことも多く、結局bashを多用してしまっています。(例えばソースからコンパイルするなど)
注意しなければいけないのは、標準のリソースはべき等性が保たれてて何回同じリソースを実行しても問題ないのですが、bashの場合は自分でそれを担保しなければなりません。

各リソースの詳しい説明は割愛しますが、各自いろいろ試してみてください。



さて、今回は前回と合わせて、初めてChef Soloを実行するまでの解説におさまってしまったので、次回は、私がはまったところやコツ、TIPS等の解説をできればと思います。
これで少しでもChef構築の手助けになれば幸いです。

そしてドワンゴでは、現在エンジニアを積極的に採用中です。 特に、このような環境構築自動化のノウハウを持ったインフラエンジニアは大歓迎です。 ご興味がある方は是非コチラからご応募ください!ニコニコ入社一時金制度もやっています。