[http://wiki.opscode.com/display/chef/Chef+Basics:title=Chef Basics]を訳しました
Chefを使うならどのような機能をもっているか把握するべきです。このページでは機能の概要を説明し、それらの詳細のリンクがついています。
Modeling Your Infrastructure
Nodes
nodeはChef-clientを実行するhostです。Chefからみたnodeの主な役割は変数と実行リストを所持する事です。
NodeはRecipeとRoleで構成されたものです。あなたがNodeを好きなときに実行するときは以下の事をします。
- systemにRecipeを追加する
- 変数を更新する
Run List
最も簡単な場合、Run listはnodeが所持しているRecipeのリストです。Cookbookのmetadataが正しいと仮定するとrun listにRecipeを登録するだけでそれらは必要に応じて自動的に実行されるでしょう。
より進んだ使い方として、Runlistにはnodeが特定のnodeのレシピをRoleとして持つ事ができます。この場合Chef-clientを走らすと、roleに指定されたRecipeが"拡張された"listとして実行されます。
Node Attributes
NodeとRoleはattributesによって関連づけされています。attributesはnestされたkey-value形式の構造を持っています。NodeとRoleのAttributesはresource attributesの入力として共通に利用できます。例えば本番環境ではnginxのあるバージョンしか使いたくないが開発環境で最新版を入れたいときがあったとしましょう。nodeもしくはroleの変数を利用する事で一つのRecipeで両方の環境を実現する事ができます。
Chefではattributeファイルにセットされたattributeのみ有効です。Chefが実行されたときにnodeがattributeファイルを参照するコード及び変数はnode上に直接管理されます。Ruby上ではattributeファイルの中にselfで指定されたものがnodeです。attributeファイルを利用する事でnode上のデータが正しいと信頼することができます。
Chefのヘビーユーザはたくさんのnode上でattributeを管理しています。
Roles
Roleは似たようなnodeの似たような機能をグルーピングするものです。Webのscaleを行うときは何か一つに着目せずにnodeグループの設定を共通化しその設定部分を表現するためにRoleを使います。Roleはnode同様attributesとrun listを持っています。Chef-clientが実行されたとき、node自身のattributeとRoleのattributeがmergeされることになります。
Configuring Nodes
Cookbooks
cookbookはChefが設定したrecipe,resource definition, attribute, library, cookbook fileとtemplate fileとmetadataの集まりです。Cookbooksは一つのpackageやserviceの設定周りがまとまったものです。例えばclientとserver両方のRecipeを含んだMySQLのcookbookの場合それにattributesファイルが追加されることになります。
CookbooksはChef内で共有、配布される単位になります。Chefを利用する人のほとんどぽがCookbookを書く事になるでしょう。
Recipes
Recipesはあなたのresourcesが書かれているファイル群です。RecipesにはちょっとしたChefの文法を覚える必要があります。
Chefを実行する際は二つのプロセスがあります。一つ目は結合と呼ばれるプロセスです。二つ目はChef内の各Resourceでのactionを実行することです。単なるrubyコードは実行プロセスではなく結合プロセスで実行されます。Chefの実行プロセスで実行したい場合はRuby block resourceを利用するようにしてください。これより詳細は、anatomy of a chef runを参照してください。
Metadata
Cookbooksではよく必要な機能を他のcookbooksを信頼します。clientが利用しているcookbooksがどのサーバで稼働しているか知るためにcookbooksではある情報を見ています。それがcookbook metadataです。metadataにはauthorship, licening, cookbookの概要、cookbookがどのプラットフォームで動く事を期待しているかなどの情報が入っています。Chefは実際に動くときよりmetadataによっていろいろな値をもっていますが正確な依存情報を持つ事が本質であり情報が全て入ったから問いって必要な全てのcookbookが手に入るわけではないです。
Resources
resourceはhost上の設定差異を吸収します。たとえばpackages resourceなどプラットフォームによってコマンドが変わるところを吸収できます。
ResouceはRecipeやDefinitionsで利用できます。それらはChefで動く基本の単位です。
Actions
ActionはChef resourceで何をしたいか記述します。例えばあるパッケージをインストールするのかアップグレードするのかはたまた削除するのかといったことをResourceに記述します。
Providers
providerはプラットフォームに特化したresourceの概念です。RedhatはCentOSではpackage resourceはyumpackageを使ってインストールするでしょうしDebianやUbuntuではaptを利用するでしょう。Providerはその辺りを知的に行います。systemに関連するアクションがあった場合はそれに帯する責任を背負います。そして各パッケージは最初にコマンドに何が必要なのかチェックします。Chefを実行するさいProvierについて心配する事はありません。あなたが何かしてもChefはshortcut resourceを提供してくれます。例えばdpkg_packageやrpm_packageはファイルシステムから直接インストールすることを許します。
ProvidersはResource上のactionをとってきます。与えられたNodeは基本のProviderを指定しますがResourceで直接Providerを指定することもできます。
Search
SearchはChef serverによって構成され、データの検索にを行います。ほとんどの場合はrecipe内でsearch callsを経由して利用します。
Data bags
DatabagsはChef-server上にもつkey-value形式の構造化されたものです。DataBagは検索でき、かつrecipe内で名前を呼んで直接指定する事ができます。Chef全体で所持できる変数と考えるのがいいでしょう。
Anatomy of a Chef Runの訳
Anatomy of a Chef Runを訳しています。
Anatomy of a Chef Run
Chefを動かすならChef-clientの実行の仕組みは覚えておいた方がいいですよ。
Convergence
Chef-clientやChef-soloでプロセスを呼んだときは"Convergence"リソースを呼ぶ必要があります。
Convergenceはシステム内で自動的に"各動作を実行するときはシステムを正しい形でくださいね"ということを意味します。理想としてはChef-clientを一つのサーバで走らせるとき中途半端な状態ではなく完全な状態のシステムを利用できる事です。
うまく完了しなかった場合は続けてシステムに要求を送り続けます。
Chef-clientの実行
- Chef-Clientを実行
- Node作業
- 構築
- 登録
- 認証
- Cookbookの同期
- ライブラリを同期
- 変数を同期
- 定義を同期
- レシピを同期
- リソースをコンパイル
- ライブラリ読み込み
- 変数読み込み
- 定義読み込み
- レシピ読み込み
- Nodeを設定
- 保存
- Chef-client終了
Build, Register, and Authenticate the Node
Chef-clientもしくはChef-soloを実行する際、最初にNodeをたてます。Nodeは以下で構成されています。
- Ohai:OSから情報を持ってきます
- Chef-serverから前回のNode情報を持ってきます(Chef-solo使わないときのみ)
- JSONの変数とレシピを追加します
- Ohaiで取得してきた情報を追加します
一度Nodeが構築されるとChef-Clientは毎回/etc/chef/client.pemという非公開キーを参照するようになります。
それがない場合自身でそれを作ろうとします。それ自身を登録するときはChef-validaterを一意のものだと仮定します。Chef-validatorは特殊なクライアントでそれを利用する事で新しいユーザを作成することができます。Chef-validatorはデフォルトで/etc/chef/validation.pemに非公開キーを持ちます。一回作ってしまえば次回からは/etc/chef/client.pemを参照するようになります。
Synchronize Cookbooks
Chef-ClientはChef-Serverにライブラリ、変数、定義、レシピの一覧を取得しローカルのファイルキャッシュに溜め込みます。
Compile Resource Collection
COOKBOOKから情報を得た後、nodeに必要なリソースを収集します。
- ライブラリをロードする
- 言語拡張はRubyのクラスを使用可能にします
- 変数をロードする
- レシピやNodeの変数から変数をロードします
- 定義をロードする
- 定義はレシピの前に読み込まれている必要があり、それからリソースが生成されます
- レシピをロードする
Configure Node
Chefはこの時点でシステムとして設定できる準備ができています。
- Converge
- 各リソースはProviderにマッピングされます。ProviderとはChef上で動作可能なオブジェクトです。
- Save node
- Convergeした後Nodeを保存し、検索対象内にセットします。
- Run Notifications
- 最後には、設定した通知が動きます
Chef-Clientが失敗した場合exception handlerに登録した動作が実行されます。
Architectureの訳
Architectureを訳してみます。
Server Architecture
Chef-serverは以下の機能から成り立っています。
Chef-clientの訳
Chef-clientを訳してみます。
Chef Client
Chef-clientはChefができることを大体どこでも実行できます。Chef-clientは署名付きリクエストをREST形式でChef-serverに送り、COOKBOOKをコンパイルして実行します。
Clients do work for one or many Nodes
Chef-clientはNodeを利用して動きます。一つのChef-Clientで複数Nodeのレシピを実行できます。
Clients do all the work
Clientが全てのタスクを実行します。Chef-serverやChef-IndexerはChefに情報を供給するだけです。
You can run the client periodically
もしChef-clientをdaemonとして動かしたいなら以下のようにするとよいですよ。
$ chef-client -i 3600 -s 600
iオプションはNodeに聞きにいく間隔を、-sはプロセス一杯のときのランダムな間隔をあけるための設定です。
他に以下のようなオプションがあります。
指定表記 | オプション内容 |
-S, --server CHEFSERVERURL | Chef-serverのURLを指定 |
-k, --client_key KEY_FILE | Client keyファイルの場所を指定 |
-c, --config CONFIG | 設定ファイルを指定 |
-d, --daemonize | daemonで動かしたいときに指定 |
-g, --group GROUP | グループを指定 |
-i, --interval SECONDS | 継続的にChef-clientを実行するときの間隔を指定 |
-j JSON_ATTRIBS | jsonファイルを指定 |
-l, --log_level LEVEL | ログレベルを指定(debug, info, warn, error, fatal) |
-L, --logfile LOGLOCATION | ログファイルを指定(デフォルトは標準出力) |
-N, --node-name NODE_NAME | Nodeを指定 |
-P, --pid PIDFILE | pitファイルを指定(デフォルト:/tmp/chef-client.pid) |
-s, --splay SECONDS | 間隔を指定 |
-u, --user USER | ユーザを指定 |
-K, --validation_key KEY_FILE | validationファイルを指定 |
-V, --verbose | ログを標準出力にも表示する |
-v, --version | バージョンを表示する |
-h, --help | ヘルプを表示する |
APIの認証について
pemっていうファイルで認証しているのはなんとなくわかる。
このなんとなくを解消したいと思う。
本エントリはWikiの誤訳だと思ってほしいです。
API Clients
nodeデータはChef serverからの認証リクエストによって別々に管理されており、それはすなわちAPI Clientごとに管理されているということです。どのAPI Clientも公開/非公開キーを所持しています。
公開キーはChef server側で所持され、非公開キーはAPI Clientのほうで所持しています。nodeを実行したとき、非公開キーが自動的に/etc/chef/client.pem上に生成されます。knifeコマンドを利用するのが管理者の場合~/.chef/USERNAME.pemに非公開キーは生成されます。
全てのChef serverへのリクエストはHTTP headerに認証情報が入っています。署名はClient側のリクエストにClientの非公開キーを用いて暗号化したものを利用します。
The Validation Client
Chef Clientの初回アクセスはAPI Clientのキーをまだ生成できておらずChef serverへ認証リクエストを作る事ができません。
そこでデフォルトで"validation-client"という特殊なClientを使います。Chef clientが実行されて、最初にキーがなかったときChef serverに自分自身を登録するためvalidation-clientを一時的に借りるようにします。それをするために、validation clientの非公開キーをChef clientホストの/etc/chef/validation.pemにおくようにしてください。
一度Chef server側に登録できればこの特殊なClientは必要なくなります。一度validation clientを利用してChef serverに登録したらそのホストにおいてあるキーを削除する事をおすすめします。
Signed Header Authentication
APIの認証は基本的にリクエストごとに実施します。そしてそのリクエスト自体はClientがキーを利用して作成しています。つまるところ、結局HTTP headerに毎回ユニークな認証キーを作成しているだけです。リクエストは以下の項目を所持しています。
- The HTTP Method (GET/PUT/POST/DELETE)
- The Request Body in Base64
- A Timestamp
- Your Client ID
リクエストはClient側の非公開キーによって暗号化され、HTTP headerにセットされ、Chef server側でそれを解釈します。さらに受け取ったリクエストが本当にChef client側から送られてきたものなのかどうかをbodyがかわっていないかHTTP methodに変わりはないか必要な回数以内のリクエストなのかということから判断します。
全てのリクエストはHTTPS経由で行う事をお勧めします。
Chef Clientにはclient keyが発行されることになります。
Under the hood
新しいAPI Clientが作成されたとき、Chefは新しい公開/非公開キーを作成します。公開キーはChef serverで保持され、非公開キーはAPI Client側で保持されます。リクエストがきたときChef server側では以下のように検証を行います。(公開キーを利用します)
この検証は以下のメリットをもっています。
- 全てのリクエストで認証が必要
- Sessionを持たなくてよい
- リクエストを改ざんされても問題ありません
- end-to-endの認証なのでいかなるトランスポート層を通る事ができます
Chef Clientの認証の仕組みは以下の通りです。
- 最初にChef clientがclient keyを持っているか確認します
- もし持っていたら認証リクエストの発行を開始します
- もし持っていなかった場合validation keyをもっているか確認します
- もし持っていたらAPIを利用するためのリクエストを作成します
- もし持っていなかったら、失敗です。。。
- もしClient keyを作成できた場合、それを使って再度リクエストを作成します
The Web UI key
Chef web UIはChef APIのようなものです。違いはインストール時にキーが発行されることです。(同時にvalidation keyも発行されます)
Creating new API Client Keys with Knife
もしChef-server上にデフォルトのユーザでリクエストを送りたくなければ絶対に自分自身のキーを作った方がいいですよ。
API clientを生成する際は、まず以下のknifeコマンドを発行しましょう。
$ knife client create monkey INFO: Created (or updated) client[monkey]
これから利用する非公開キーが発行されます。さらに以下のコマンドを発行しましょう。
knife client create monkey -f /tmp/monkey.pem
この例でいえば/tmp/monkey.pemに非公開キーができるはずです。
まとめ
- Chef-serverは公開キー持ってればいい
- Chef-Clientは非公開キーが必要
- 上記のAPI Clientの作り方だと失敗したよ(僕の環境)
- でもChef-webuiから発行できるよ
- 発行したものをChef-clientサーバのpemファイルに保存すれば問題なく動きます
追記
API Clientの作り方失敗しませんでした
- Client上に/etc/chefディレクトリ作成
- /etc/chef/client.rbに最低限以下のものを設定したファイルをおく
- client_key
- chef_server_url
- /etc/chef/validation.pemに非公開キーをおく
- chef-clientを実行
- chef-validatorが新しいclient_keyを作成してくれる
- ~/.chef/knife.rbにclient.rbにnode_nameあたりを追加したものをコピー
- knife node listで出力確認
なんかApacheインストールするためだけのレシピ
%w(#{node[:apache][:work_dir]} #{node[:apache][:install_dir]}).each do |dir| directory dir do owner "root" group "root" mode 0644 action :create recirsive true end end cookbook_file File.join(node[:apache][:work_dir], "httpd.tar.gz") do source "httpd-2.2.17.tar.gz" action :create owner "root" group "root" mode 0644 end script "install apache" do interpreter 'bash' user 'root' cwd node[:apache][:work_dir] code <<-EOC tar -zxvf httpd.tar.gz cd httpd-2.2.17 ./configure #{node[:apahe][:install_options]} make make install EOC end