Chefを用いると、各種ソフトウェアのインストールや設定ファイルの更新といった、従来であればサーバにログインして手動で行うしかなかった作業を自動化できます。ここではChefの基本を理解することを目的として、『VirtualBoxでWindowsのゲストOSとしてCentOSを動作させる』の手順で用意した、ほぼまっさらな状態のCentOSに対して、『rbenvおよびbundlerの基本的な使用方法』の手順を自動実行し、rbenvおよびbundlerをインストールします。なお、Chefはrubyで開発されており、環境構築や設定ファイルの記述にはrubyの知識が必要になります。この点がChefと同様にサーバ設定を自動化するPuppetとの違いのひとつであり、Puppetのように独自言語を習得する必要がありません。
自動化したい処理の実行方法が具体的に記述されたファイルです。
レシピを整理するための仕組みです。あるクックブックには、本質的に同じ処理を実行するレシピが一つ以上格納されています。
目的に応じで3種類のサーバ構成が可能です。ここでは準備が手軽である一方で実用性も高い「中規模な台数のサーバに自動設定が必要な場合」を採用します。
「ワークステーション」という、クックブックおよびレシピを作成するPCを人間が操作します。ワークステーションから "knife" というコマンドで指示を出すことで、自動設定が必要なサーバそれぞれを「Chefクライアント」として設定しておき、それらがクックブックおよびレシピを管理する「Chefサーバ」と通信できる状態を事前に準備しておきます。準備が完了すれば、Chefクライアントそれぞれに対し、一括してChefサーバからレシピを取得させ、自分自身に対してそのレシピを適用させることができます。登場人物が「ワークステーション」「Chefクライアント」「Chefサーバ」と多く、仕組みが大掛かりであるため準備は大変ですが、自動化の度合いは高いです。
自動必要なサーバに何らかの手段でクックブックおよびレシピをコピーしておきます。"chef-solo" というコマンドをインストールおよび実行することによって、レシピにしたがった内容を自分自身に自動で適用します。「ワークステーション」および「Chefサーバ」が不要であり仕組みがシンプルな一方で、自動設定が必要なサーバそれぞれに対してログインして "chef-solo" のインストールおよび実行を行う必要があり、自動化の度合いは低いです。
"大規模な場合" のワークステーションに相当するPCで、クックブックおよびレシピを作成しておきます。そのPCにおいて "knife solo" という内部でsshを利用するコマンドを実行することで、自動設定を行いたいサーバへのクックブックおよびレシピの遠隔コピー (rsync)・"chef-solo" の遠隔インストール・遠隔実行を行います。"大規模な場合" のワークステーションに相当するPCを用意しておく必要がある一方で、"小規模な場合" における手動部分を自動化できています。
作業用PCにおいてコマンドをインストールします。自動設定が必要なサーバへのインストールではないことにご注意ください。
$ gem install chef
によって "knife" および "chef-solo" コマンドがインストールされます。更に
$ gem install knife-solo
によって、"knife" のプラグインがインストールされ、"knife solo" が実行できるようになります。
「RubyInstaller for Windows」でインストールしたrubyを用いている場合、以下に示すいくつかの注意点を除き、本ページの手順をほぼそのままWindowsでも実行可能です。
特に Windows ユーザにとってありがたいことに Chef 関連のコマンド一式をまとめてインストールしてくれるソフトウェアが配布されています。例えば Windows: exe, OSX: dmg, Linux: rpm という形式での配布です。ChefDK (Chef Development Kit) とよばれており、公式サイトからダウンロードできます。
"chef" および "knife-solo" のGEMパッケージがインストールできたら
$ knife configure
によって初期設定を行ってください。すべて既定のものでよいです。
> Please enter the chef server URL: [https://localhost:443]
> Please enter an existing username or clientname for the API: [username]
> Please enter the validation clientname: [chef-validator]
> Please enter the location of the validation key: [/etc/chef-server/chef-validator.pem]
> Please enter the path to a chef repository (or leave blank):
...
Configuration file written to /home/username/.chef/knife.rb
生成された "knife solo" の設定ファイル "/home/username/.chef/knife.rb" を編集します。
$ vi ~/.chef/knife.rb
末尾に以下の二行を追記して保存してください。
....
cookbook_path ['/home/username/my_kitchen/cookbooks', '/home/username/my_kitchen/site-cookbooks']
ssl_verify_mode :verify_peer
一行目では、この後ホームディレクトリ直下に作成する予定のクックブックへのパスを配列で指定しています。ご自身の環境に応じで適宜パスの内容は変更してください。二行目では、以下の警告が表示されないように設定しています。
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
SSL validation of HTTPS requests is disabled. HTTPS connections are still
encrypted, but chef is not able to detect forged replies or man in the middle
attacks.
To fix this issue add an entry like this to your configuration file:
```
# Verify all HTTPS connections (recommended)
ssl_verify_mode :verify_peer
# OR, Verify only connections to chef-server
verify_api_cert true
```
To check your SSL configuration, or troubleshoot errors, you can use the
`knife ssl check` command like so:
```
knife ssl check -c /root/chef-solo/solo.rb
```
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
ちなみに、何かの拍子に「~/.chef」以外に例えば「~/kitchen/.chef」といったディレクトリが自動生成されてはまることがあります。knife.rb の設定変更が反映されない場合などにはこのことを疑ってみてください。
実際には、物理サーバ、AmazonEC2のクラウドの仮想インスタンス等何に対しても "knife solo" を実行できます。ここでは、無料でありスナップショットを利用すればレシピ適用のやり直しも可能な選択肢として、『VirtualBoxでWindowsのゲストOSとしてCentOSを動作させる』の手順で用意した、ほぼまっさらな状態のCentOSを採用します。「yum update」を含め上記リンク先の手順が完了したら、遠隔でrootにパスワードなしでsshするために以下の内容を実行します。
# passwd -d root ← パスワードを空にする
# vi /etc/ssh/sshd_config
> ...
> PermitRootLogin yes ← ルートでのログインを許可
> ...
> PermitEmptyPasswords yes ← 空パスワードでのログインを許可
> ...
# service sshd restart ← sshdを再起動して設定変更を反映
これは "knife solo" のための設定を簡易にするための措置ですが、実際の外部インターネットにさらされているサーバでは危険ですので絶対にこのようなことはせず、sudoが行える一般ユーザに公開鍵認証でsshログインすることによる "knife solo" の設定を行うべきです。ここではあくまでもローカルの仮想マシンを利用した練習なので分かりやすさを優先しています。
以下、一貫してパスワード入力を頻繁に求められる、という事態を避けつつセキュアな状況を実現しようとしています。
$ adduser username
パスワードは
$ passwd -d username
で削除してください。
$ visudo
...
root ALL=(ALL) ALL
username ALL=(ALL) ALL ← これを追記
...
$ su -l username
$ vi ~/.ssh/authorized_keys ← 公開鍵を登録
$ chmod 600 ~/.ssh/authorized_keys
$ chmod 700 ~/.ssh
$ ls -l ~/.ssh | grep authorized_keys
-rw-------. 1 username username 413 9月 16 00:21 2014 .ssh/authorized_keys
$ ls -la ~ | grep .ssh
drwx------. 2 username username 4096 9月 16 00:21 2014 .ssh
作業用PCで公開鍵を作成するときは、パスワードの不要な秘密鍵を使用するようにしてください。頻繁にパスワードを求められる事態に陥ってしまいます。
$ su -l
$ vi /etc/ssh/sshd_config
...
PermitRootLogin no ← rootでのログインを禁止
...
PubkeyAuthentication yes ← 公開鍵認証を有効化
...
PasswordAuthentication no ← パスワード認証を禁止
PermitEmptyPasswords no ← 空のパスワードでのログインを禁止
...
$ service sshd restart
以上で、一般ユーザに対して公開鍵認証を行っているためセキュアであるのと同時に、秘密鍵および一般ユーザにパスワードを設定していないため "knife solo" の際にパスワード入力を頻繁に求められない、という状況を実現できます。
まず作業用PCのホームディレクトリにおいて、クックブック等を格納するキッチンフォルダを作成しましょう。
$ knife solo init my_kitchen
environments, nodes, cookbooks... といったディレクトリが、my_kitchen/* に自動生成されます。
my_kitchenにcdで移動してから、以下のコマンドでクックブックの雛形を作成しましょう。
$ cd my_kitchen
$ knife cookbook create create-user -o site-cookbooks
"-o" を省略すると、環境に依存した何処かのディレクトリにクックブックの雛形が生成されます。「cookbooks」ディレクトリはサードパーティのクックブックをインターネットからダウンロードして保存する用途で使用されるのが一般的です。自作するクックブックは「site-cookbooks」に保存するようにしましょう。
自動生成されたクックブック内のレシピファイルを編集しましょう。
$ vi site-cookbooks/create-user/recipes/default.rb
default.rb
group "sample_group" do
gid 1000
action :create
end
user "sample_user" do
home "/home/sample_user"
password '$6$0Z9RqkR6IEq/UgbB$GW9AlRLjmNfqFAvJ3c1dzPMN.NJXlkTkJLpkF64rn91aUsOsr9.FmJERzRyYd0FautHOjvUplsV.0SX6T2kTf/'
shell "/bin/bash"
uid 1000
gid "sample_group"
action :create
end
userのpasswordには
$ grub-crypt --sha-512
で生成したパスワードのハッシュ値を指定してください。レシピの内容としては "sample_group" を作成し、新規作成した "sample_user" をそのグループに所属させています。詳細な公式ドキュメントはそれぞれ以下のページです。
ちなみに、公式ドキュメントの目次は http://docs.getchef.com/ です。特にリソース関連の目次は http://docs.getchef.com/resource.html です。
別のクックブックを遠隔実行した際に、既にchef-soloコマンドが遠隔インストール済みである場合はこの作業は不要です。このクックブックが初めての適用であり、chef-soloが遠隔設定対象のサーバにインストールされていない場合は、以下のコマンドを実行します。IPアドレスは適宜ご自身の環境のものに読み替えてください。
$ knife solo prepare root@192.168.56.11
しばらく待つと "Thank you for installing Chef!" と表示されます。実際に遠隔インストールされたことを確認してみましょう。
$ ssh root@192.168.56.11
$ ls /opt/chef/bin | grep chef
chef-apply
chef-client
chef-service-manager
chef-shell
chef-solo
chef-zero
と同時に、ローカルの作業用PCには
nodes/192.168.56.11.json
というファイルが自動生成されていることも確認できます。
自動生成されたノードの設定ファイルを編集し、適用するレシピを指定します。
$ vi nodes/192.168.56.11.json
{
"run_list": [
"recipe[create-user]" ← これを追記
],
"automatic": {
"ipaddress": "192.168.56.11"
}
}
以下のコマンドで、rsyncによるクックブックの遠隔コピー、および遠隔での "chef-solo" の実行を行います。
$ knife solo cook root@192.168.56.11
実行が完了したら、確かに新規ユーザが作成されていることを確認しましょう。
先程の例1で生成したキッチン内に、同様の手順でクックブックを生成しましょう。
$ knife cookbook create rbenv -o site-cookbooks
続いて、後で利用することになるテンプレートファイルを作成しておきましょう。
$ vi site-cookbooks/rbenv/templates/default/rbenv.sh.erb
export RBENV_ROOT=/usr/local/rbenv
export PATH=/usr/local/rbenv/bin:$PATH
eval "$(rbenv init -)"
最後に、レシピファイルを『rbenvおよびbundlerの基本的な使用方法』の内容を自動実行できるように編集しましょう。
$ vi site-cookbooks/rbenv/recipes/default.rb
default.rb
# 必要なパッケージのインストール (yum等、何を使用するかは環境依存)
# http://docs.getchef.com/resource_package.html
%w{git gcc openssl-devel}.each do |pkg|
package pkg do
action :install
end
end
# rbenvのダウンロード
# http://docs.getchef.com/resource_git.html
git "/usr/local/rbenv" do
repository "https://github.com/sstephenson/rbenv.git"
revision "master"
action :sync
end
# プラグインディレクトリの作成
# http://docs.getchef.com/resource_directory.html
directory "/usr/local/rbenv/plugins" do
action :create
end
# ruby-buildプラグインのダウンロード
git "/usr/local/rbenv/plugins/ruby-build" do
repository "https://github.com/sstephenson/ruby-build.git"
revision "master"
action :sync
end
# bashの環境設定を行うシェルスクリプトの設置 (先程作成したテンプレートファイルを利用)
# http://docs.getchef.com/resource_template.html
template "/etc/profile.d/rbenv.sh" do
source "rbenv.sh.erb"
action :create
end
# rubyのインストール
# http://docs.getchef.com/resource_bash.html
bash "install-ruby-with-rbenv" do
code "source /etc/profile.d/rbenv.sh && rbenv install 2.0.0-p481 && rbenv rehash"
action :run
not_if { File.exists?('/usr/local/rbenv/versions/2.0.0-p481') }
end
# bundlerのインストール
bash "install-bundler" do
code "source /etc/profile.d/rbenv.sh && rbenv global 2.0.0-p481 && rbenv exec gem install bundler && rbenv rehash"
action :run
end
以上のレシピ編集が終わったら、ノード設定ファイルを編集します。
$ vi nodes/192.168.56.11.json
{
"run_list": [
"recipe[create-user]", ← ',' カンマを忘れずに追記
"recipe[rbenv]" ← これを追記
],
"automatic": {
"ipaddress": "192.168.56.11"
}
}
遠隔コピーおよびインストールを行いましょう。
$ knife solo cook root@192.168.56.11
rbenvおよびruby,bundlerが無事インストールされれば完了です。
クックブックは世界中の開発者によって公開されています。それらを利用する手段には現時点で「Berkshelf」および「Librarian-Chef」の二つがあります。いずれも、インターネットからクックブックをダウンロードして "chef-solo" が利用できるようにするツールです。ここでは後者の「Librarian-Chef」を利用して "cpan" のクックブックをダウンロードしてみます。
$ gem install librarian-chef
$ cd ~/my_kitchen
$ librarian-chef init
$ vi Cheffile
Cheffile
#!/usr/bin/env ruby
#^syntax detection
site 'https://supermarket.getchef.com/api/v1'
cookbook 'cpan'
$ librarian-chef install ← Windowsでは環境によっては証明書エラーが発生するかもしれません (その場合、VMで行うのが無難)
確かにダウンロードできたことを確認します。
$ ls cookbooks/
cpan
data_bags/DATA_BAG_NAME/ITEM_NAME.json
を対象としたコマンド例です。knife data bag をもとにしています。
暗号化
knife data bag from file --secret-file mysecret.key DATA_BAG_NAME ITEM_NAME.json
復号
knife data bag show --secret-file mysecret.key DATA_BAG_NAME ITEM_NAME