はじめに
knife-solo
で一台のホストをセットアップすることは出来ても同時に複数のホストをセットアップするのはちと難しい- でも
capistrano
とchef-solo
を使えば同時に複数のホストをセットアップすることは出来そう - ということで今更だけど
capistrano
とchef-solo
を組み合わせてみる - セットアップ後の確認は
serverspec
を使って確認する
早速試してみる
若干、課題はあるものの以下のような capistrano のレシピを使うことで実現出来た。
レシピ(chef のレシピでは無くて...)
以下のレシピを適当なファイル名で保存(例では setup.rb
)する。
role :servers, "","" # set :user, "" set :path_to, "" # set :chef_local_dir, "#{path_to}/chef-repo" set :chef_remote_dir, "" # namespace :chef do task :init, :roles => :servers do run "apt-get update && apt-get -y install sudo curl rsync" run "curl -L https://www.opscode.com/chef/install.sh | sudo bash" end task :sync, :roles => :servers do run "mkdir -p #{chef_remote_dir}/chef-repo/" find_servers_for_task(current_task).each do |server| if ( "#{server.port}" == nil ) `rsync -avz #{chef_local_dir}/ -e "ssh -p #{server.port}" root@#{server.host}:#{chef_remote_dir}/chef-repo/` else `rsync -avz #{chef_local_dir}/ #{user}@#{server.host}:#{chef_remote_dir}/chef-repo/` end end end task :deploy, :roles => :servers do find_servers_for_task(current_task).each do |server| run "chef-solo -j #{chef_remote_dir}/chef-repo/nodes/localhost.json -c #{chef_remote_dir}/chef-repo/solo.rb" end end end
ソースはこちら。
使い方
まず、以下を実行すると対象のノードに Omnibus installer
で chef
クライアントがインストールされる。
cap setup chef:init
task
の init
が実行される。但し、この init
は残念ながら apt-get
が処理として走るので Debian
や Ubuntu
限定になってしまっている。これは何らかの方法で OS
の判定を入れて処理を分岐する必要がある。*1
次に :sync
で、ローカルホストの chef-repo
が rsync
で対象ホストに丸っとコピーされる。
cap setup chef:sync
次に以下を実行すると対象ノードで cookbook
が適用される。
cap setup chef:deploy
run_list
が書かれた localhost.json
ファイルを利用して cookbook
が適用されることになる。また、find_servers_for_task
で role
に書かれたホストが適用されることになる。(ホスト名だけを取り出す場合には server.host
でポート番号を取り出す場合には server.port
を使う)
demo
docker
コンテナ二台に対してこちらの cookbook
を適用してみる。手順は上記の手順をそのまま踏襲し cap setup chef:deploy
して暫くすると...
** [out :: xxx.xxx.xxx.5] [2014-01-28T23:41:35+00:00] INFO: Processing execute[install_td-agent] action nothing (elasticsearch_cookbook::app_install line 39) ** [out :: xxx.xxx.xxx.5] [2014-01-28T23:41:35+00:00] INFO: Processing remote_file[/tmp/td-agent_1.1.17-1_amd64.deb] action create (elasticsearch_cookbook::app_install line 44) ** [out :: xxx.xxx.xxx.5] [2014-01-28T23:41:35+00:00] INFO: Processing gem_package[fluent-plugin-elasticsearch] action install (elasticsearch_cookbook::app_install line 51) ** [out :: xxx.xxx.xxx.5] [2014-01-28T23:41:35+00:00] INFO: Processing gem_package[fluent-plugin-typecast] action install (elasticsearch_cookbook::app_install line 51) ** [out :: xxx.xxx.xxx.5] [2014-01-28T23:41:35+00:00] INFO: Processing service[td-agent] action nothing (elasticsearch_cookbook::app_install line 58) ** [out :: xxx.xxx.xxx.5] [2014-01-28T23:41:35+00:00] INFO: Processing template[/etc/td-agent/td-agent.conf] action create (elasticsearch_cookbook::app_install line 63) ** [out :: xxx.xxx.xxx.5] [2014-01-28T23:41:35+00:00] INFO: Chef Run complete in 6.417893026 seconds ** [out :: xxx.xxx.xxx.5] [2014-01-28T23:41:35+00:00] INFO: Running report handlers ** [out :: xxx.xxx.xxx.5] [2014-01-28T23:41:35+00:00] INFO: Report handlers complete ** [out :: xxx.xxx.xxx.5] [2014-01-28T23:41:28+00:00] INFO: Forking chef instance to converge... command finished in 8330ms
上記のように見た感じは正常に終了したように見えるが、ちゃんと適用されたかは serverspec を使って確認をする。既に serverspec
はインストール済みの環境にて、以下のような spec
ファイルを各ホスト毎に用意して上げる。
require 'spec_helper' describe package('elasticsearch') do it { should be_installed } end describe package('td-agent') do it { should be_installed } end describe package('libssl0.9.8') do it { should be_installed } end describe command('/usr/lib/fluent/ruby/bin/gem list | grep fluent-plugin-elasticsearch') do it { should return_exit_status 0 } end describe command('/usr/lib/fluent/ruby/bin/gem list | grep fluent-plugin-typecast') do it { should return_exit_status 0 } end describe service ('td-agent') do it { should be_running } end describe service ('elasticsearch') do it { should be_running } end
そして、~/.ssh/config を以下のように設定する。
Host xxx.xxx.xxx.* User root Port 22
最後に rspec spec
を実行すると...
.............. Finished in 1.32 seconds 14 examples, 0 failures
上記の通り fail
が出ずに終了する。ということは見事に二台のホストに対して cookbook
が適用されていると判断出来る。
最後に
capistrano
を使えば長年*2の悩みだった複数ホストに対して並行してchef
を走らせることが出来た- 但し、ログの出力がホスト毎ではなくすべてのホストのログが混ざってしまうのと、
knife solo
に比べて出力が少ないのがちょっと残念 - やっぱ、ちゃんとやりたければ
Chef-Server
なのかなと思ってしまう - 最後に確認で使った
Serverspec
は簡単にspec
が書けたのは嬉しかった