2014/05/23(Fri) サービス開発
鈴木 弦

今更聞けない人の為の Chef 再入門

chef

こんにちは、エンジニアの鈴木です。
今更聞けない人の為の Vagrant 再入門」に引き続き、今回は Chef 再入門をお送りします。

この記事は以下のような人を対象としています。
・Chef ってそもそも何?
・Chef って名前を聞いたことあるけど、触ったことがない。

Chef ってそもそも何?

Chef(シェフ) とは Ruby 製のシステム構成管理ツールでインフラの構築を自動化できます。
サーバを弄ったことがある人なら誰しもが経験していると思われる「手順書」の作成。
手順書からコマンドをコピペして、ユーザ作成してWebサーバいれてDBいれて。。あとからこのパッケージが必要になったから手順書を変更して。。
どう考えてもオペミスの温床になります。
Chef はインフラをすべてコードで管理するので、Gitなどでインフラを管理でき、いつどこで誰が修正したのか分かるのでドキュメントや構築手順書のメンテナンスに追われること無いですし、一度書いてしまえばサーバの台数によらず全部自動化できるので、大幅にインフラエンジニアのリソースを削減できるようになります。

Chefの利用実績としては、
・CyberAgent
・GREE
・nanapi
・EngineYard
・37signals
・Facebook
・etc
Facebookにいたっては数十万台規模のサーバ群をすべて Chef で管理しているそうです。

Chef って難しいって聞くけど?

Chef に関わろうとすると沢山の用語やツールに直面して、それらを一度にすべて理解しようとすることで難しいと感じる人が多いように思います。ですので今回は Chef Solo に絞り、使うツールも極力絞って解説していきたいと思います。

今回の記事で覚えておくべき用語

リポジトリ

Chef の実行に必要な一連のファイルをまとめる入れ物

クックブック

特定のレシピに必要なデータやファイルをまとめる、構成設定ファイルセット。

レシピ

Cookbook の中に実際に実行されるもの。Ruby で記述します。
とりあえずここにハードコーディングしても動くので、今回はここにインストールするパッケージやサーバの設定などをもろもろ記載していきます。

リポジトリ > クックブック > レシピ という階層です。

Chef でなにかをしようとしたらまずリポジトリを作り。たとえば Nginx を入れたかったら Nginx のクックブックを作り、そのための設定をレシピに書くというイメージです。

knife

knife は Chef に含まれるツールでレポジトリを操作したり Cookbook を作ったりできます。

Chef Solo

Chef Solo は自分自身に対して Cookbook を実行することができます。
Chef Solo はログインしたサーバー内での実行を前提としています。
Chef Soloのイメージ

knife solo

Chef Solo をもっと便利に使うツール。knife solo を使うことでリモートホストに対して Chef をインストールしたり Chef Solo を実行したりできるようになります。クックブック等の設定ファイルの転送にはrsync、Chef Solo コマンドの実行にはSSHが利用されます。
knife soloのイメージ

さっそくやってみる

環境

ローカルホスト: MacOS X 10.9、Ruby1.9.2以上
リモートホスト: Ubuntu 13 (IP:192.168.33.10)

リモートホストの Ubuntu は 前回の記事で作成した Vagrant 環境のものです。前回記事の Apache インストール手前まで実施してください。
( Vagrant の provision で Chef のレシピをキックする機能もありますが、今記事は Chef Solo の理解を目的にしていますので、それは使用しません。)

Chef と knife solo をローカルホストにインストール

$ curl -L https://www.opscode.com/chef/install.sh | sudo bash
$ sudo gem install knife-solo --no-ri --no-rdoc

knife の初期化

$ knife configure

色々聞かれるのですが設定はデフォルトでいいのですべてEnterで。
これで一先ずインストールは終了です。

Chef のリポジトリを作る

$ knife solo init schoolwith

これで schoolwith というリポジトリが作成されました。
リポジトリの構成は以下の様になっています。

└── schoolwith
    ├── cookbooks
    ├── data_bags
    ├── environments
    ├── nodes
    ├── roles
    └── site-cookbooks

色々ありますが、今回使うのは nodessite-cookbooks になります。
site-coolbooks には自分で作成するクックブックを入れるのが慣例になっています。ちなみにcookbooksディレクトリには第三者が公開しているクックブックを入れます。今回は使用しません。
nodes は環境設定をしたい対象となるサーバの設定が入ります。対象サーバのことを Chef の文脈では node と呼びます。
knife コマンドから扱いやすいようにリモートホストへの SSH の設定をします。

$ vagrant ssh-config --host schoolwith_server >> ~/.ssh/config

これで schoolwith_server という名前でアクセスできるようになりました。
それでは リモートホスト に Chef をインストールしましょう。

$ cd schoolwith
$ knife solo prepare schoolwith_server

少し時間がかかりますが、これでリモートホストに Chef が入りました。

クックブックを作成してレシピを書く

まずは nginx のクックブックを作成してみましょう。

$ knife cookbook create nginx -o site-cookbooks/
** Creating cookbook nginx
** Creating README for cookbook: nginx
** Creating CHANGELOG for cookbook: nginx
** Creating metadata for cookbook: nginx

nginx というクックブックが site-cookbooks 以下に作られました。
ではnginx ディレクトリの中身を見てみましょう。

└── site-cookbooks
    └── nginx
        ├── CHANGELOG.md
        ├── README.md
        ├── attributes
        ├── definitions
        ├── files
        │   └── default
        ├── libraries
        ├── metadata.rb
        ├── providers
        ├── recipes
        │   └── default.rb
        ├── resources
        └── templates
            └── default

色々できていますが、まずは recipes/default.rb を編集してみましょう。

 $ vim site-cookbooks/nginx/recipes/default.rb
# Cookbook Name:: nginx
# Recipe:: default
#
# Copyright 2014, YOUR_COMPANY_NAME
#
# All rights reserved - Do Not Redistribute
#

# nginxをインストールしてある状態にする
package "nginx" do
  action :install
end

# nginxを起動して、OS起動時のサービスを有効化にしてある状態にする
service "nginx" do
  action [ :enable, :start ]
end

上記にある packageservice は Ruby の組み込み文法ではなく Chef の DSL でリソースと呼ばれます。
Chef の DSL は本当に沢山あるので興味のある人は確認してみてください。
http://docs.opscode.com/

お気づきの方もいるかもしれませんが、上記には Ubuntu にもかかわらず apt-get という記述が出てきません。Red Hat 系であろうがDebian 系であろうが書き方は変わりません。実はこの辺の OS の違いも Chef が吸収してくれます。素敵ツールです。

次にリモートホストにインストールするレシピを設定します。

$ vim nodes/schoolwith_server.json
{
    "run_list":[
        "recipe[nginx]"
    ]
}

リモートホストにレシピを反映させる

では準備が出来たのでリモートホストにレシピを反映させましょう。
ローカルホストで作ったクックブックをリモートホストに反映させてChef Soloを実行するコマンドknife soloの出番です。

$ knife solo cook schoolwith_server
Running Chef on schoolwith_server...
Checking Chef version...
Uploading the kitchen...
Generating solo config...
Running Chef...
Starting Chef Client, version 11.10.4
Compiling Cookbooks...
Converging 1 resources
Recipe: nginx::default
  * package[nginx] action install
    - install version 1.2.6-1ubuntu3.3 of package nginx
  * service[nginx] action enable
  * service[nginx] action start
    - start service service[nginx]

Running handlers:
Running handlers complete

Chef Client finished, 1/1 resources updated in 17.999435557 seconds

無事リモートホストに Nginx がインストールされ起動しました。
ブラウザで確認してみましょう。
→ http://192.168.33.10

ブラウザ

無事インストールされて起動しているようですね。

冪等性(べきとうせい idempotence)

Chef のレシピにおいて重要な考え方として「冪等性を保証する」というポリシーがあります。
冪等性とは数学なんかでよく使われる、ある操作を1回行っても複数回行っても結果が常に同じであることをいう概念です。
プログラムでいうと i++ ではなく i = 0 です。
ですので先ほどのコマンド

 $ knife solo cook schoolwith_server 

を何度実行しても Nginx がインストールされて起動した状態に収束し、何回も繰り返しインストールされたり、既にインストールされているからといってエラーになったりすることはありません。
ほとんどの場合、 Chef の動作は冪等性が保証されていますが、 Script や Execute などの DSL は書き方によっては冪等性が保証されないことがあります。
ですのでレシピを書く際は冪等性が保証されるように意識的に作り込んでください。

まとめ

駆け足で Chef Solo の触りをお話しました。Chef は本当に奥が深くて習得するのに結構な気合を入れないといけないのですが、一度覚えるとやみつきになりあらゆるもののセットアップを Chef で書かないと気持ち悪くなるぐらいになります。

最近 Chef 関連の日本語書籍も充実してきました。つい先日に発売された「Chef実践入門」は 日本の Chef スペシャリストの方々によって執筆された本で、初心者が確実にステップアップしていけるように考えられている構成です。かつ必ず詰まるであろうエラーメッセージの追い方やコマンドチートシートまであるので Chef を勉強するなら手元に置きたい一冊だと思います。
(※ ちなみにコチラの本の執筆フローがモダンですごくかっこいいです。→ 【いまどきの技術本執筆環境 – 「Chef実践入門」】

この記事が Chef を使うキッカケになれば幸いです。ではでは。

Chef実践入門 ~コードによるインフラ構成の自動化 (WEB+DB PRESS plus)
吉羽 龍太郎 安藤 祐介 伊藤 直也 菅井 祐太朗 並河 祐貴
技術評論社
売り上げランキング: 419
この記事を書いた人
鈴木 弦 エンジニア

サーバーサイドエンジニア。大手WEBポータル企業にてコマース開発に従事。企業向けシステム開発等に関わる。また100万DLを超えるiOSアプリのメイン開発担当。その後School Withにジョイン。好きなラーメンは鶏ガラ系醤油。

School With