Chefを利用する機会があり、体系的に知りたいと持って、Chef実践入門を読んだ。 自分用に、そのメモを残しておく。
概要
- 管理サーバを介するかどうかによって、2種類の動作形態がある。1つ目は、管理サーバとしてChef Serverを介するサーバクライアントモデル。ローカル端末と、管理対象ノードの他に、Chef Serverを必要とする。ローカル端末・Chef Server間、Chef Server・ノード(Chef Client)間でやり取りする。ノード数の増加に強い。2つ目は、Chef Soloを使ったスタンドアロンモデル。Chef ServerもChef Clientも不要。小規模な環境で使われることが多い。いずれもRubyで実装されているので、
gem install chef knife-solo berkshelf
のように、gem
によってインストールできる。 - リポジトリ(キッチン)、クックブック、レシピという階層構造を持つ。リポジトリは、Gitなどでバージョン管理をする。
site-cookbooks
に自作のクックブック、cookbooks
に外部クックブック、data_bags
にリポジトリ全体でグローバルなスコープのデータ、environments
にdev/prodなどの環境情報、nodes
にノードごとの設定情報(nodeオブジェクト)を配置する。また、Berksfile
に依存する外部クックブック一覧を記述する。
クックブックの実装
- 同一構成の複数ノードを管理する場合には、ノードをまとめたroleを定義する。
<repository>/roles/<role name>.json
を作り、run_list
などを書いていく。また、Attributesを上書きすることもできる。default_attributes
は定義されていないものを定義し、override_attributes
は強制的に上書きするもの。 - Attributeというkey-valueを管理する仕組みがある。自分で設定したり、システムから自動抽出することができる。自動抽出する場合には、
ohai
コマンドの結果が使われる。慣習的に、ohai
で取得したの値のキーに関してはnode[:platform]
のようにシンボルを利用し、Nodeオブジェクトで定義したキーに関しては、node["httpd"]["port"]
のように文字列を利用する。Attributeは、<cookbook name>/attributes/defaults.rb
にデフォルト値を定義できる。Attributeの優先順は、Nodeオブジェクト>ロール>Environment>レシピのAttribute>クックブックのAttribute。 cookbook_file
リソースは<cookbook name>/files
以下のファイルを転送し、file
リソースはファイルを新規作成するために使われる。ifconfig
、mount
、gem_package
、git
、http_request
、route
、ruby_block
リソースなどがある。もし、これらのリソースを使っても管理できないものがあれば、script
リソースを使う。ただ、not_if
、only_if
などをうまく使って、冪等性を自分で保証する必要がある。- 設定ファイルの配置後に、
notifies :reload, "service[httpd]"
のようにして、サービスのリロードできる。あるいは、subscribes :reload "template[/etc/httpd.conf]"
によって、逆方向で定義できる。どちらも動作は同じで、キューに詰め込まれてまとめて実行される。 if
文でインデントが深くなり可読性が下がってしまう場合には、only_if
などの条件付きアクションを使うと良い。- レシピに書かれたリソースはコンパイル後に収束のタイミングで実行されるが、その他のRubyコードはコンパイル時に実行される。収束のタイミングで実行されるRubyコードを書きたければ、
ruby_block
リソースを使う。 - 一連のリソースや処理は、
Definition
として、マクロのように実装できる。
Chef Solo
- Cookbookを開発するサーバと、管理対象ノードが同一の場合には、
knife cookbook create <cookbook name>
によりクックブックを作成し、chef-solo -o <cookbook name>
によりクックブックを実行する。こういう使い方はあまりしないのかな。 - 開発サーバと管理対象ノードが異なる場合には、開発サーバで
knife-solo
を使う。knife-solo
コマンドは、手元のクックブックをノードへ転送し、chef-solo
を実行する。まず、開発サーバで、knife solo init .
により、リポジトリを準備する。次に、knife solo prepare <hostname>
により、管理対象ノードにche-solo
をインストールする。続いて、knife cookbook create <cookbook name> -o <repository>/site-cookbooks
で、クックブックを作成する。その後、クックブックを編集して、<repository>/nodes/<hostname>.json
の中で{'run_list': ["recipe[<cookbook name>:<recipe name>]"]}
と記述する。<recipe name>
を省略すると、default.rb
が参照される。最後に、knife solo cook <hostname>
で、ノードをプロビジョニングする。なお、knife solo prepare <hostname>
とknife solo cook <hostname>
をまとめたknife solo bootstrap <hostname>
コマンドもある。また、chef-solo
にのみ依存するものはknife solo
を使い、それ以外のものはknife
を使う。
その他
Test Kitchen
を使って、クックブックを統合テストできる。Vagrant
などで、複数のOSを立ち上げる。テストの実行は、クックブックの適用後に、surverspec
によって行われる。実際にテストを適用せずに、振る舞いをテストしたければ、ChefSpec
を利用する。knife cookbook site search <cookbook name>
で外部のクックブックを検索して、Berksfile
にcookbook '<cookbook>'
追加する。その後、berks
コマンドで、cookbooks
ディレクトリにダウンロード、展開される。- Opscode、Basecamp、RiotGames、aws、engineyard、pivotal-sproutなどがコミュニティクックブックを公開している。
- Chef Serverは、新規clientの登録時に双方の
validation.pem
をチェックして、認証する。その後、クライアントに秘密鍵を発行する。 knife status
で最後にChef Clientが実行された時間を確認できる。- Chefの持つ冪等性と、緊急時のロールバックは相性が悪い。そのため、Chefによるアプリケーションのデプロイは理想的ではない。
- クックブックの適用忘れを防ぐためには、Chef Soloを定期実行するか、Server/Client構成にして自動適用する。
knife
コマンドやohai
コマンドのプラグインは、指定のディレクトリにRubyコードを配置することで、簡単に実装できる。