chef-soloとknife-soloで手軽に環境構築をする

やってることは http://d.hatena.ne.jp/naoya/20130204/1359971408 の、よりしょぼい版です。 chef弱者なのでいろいろ調べてみてたんですが、chef-soloのサンプルやら説明やらをみてると、肝心の他のサーバーにどう展開させるのかのところがよくわからんなーと。 けっきょくのところは、chef-soloならrsyncならなんやらで自前で展開させるしかないみたいですが、それじゃあやっぱり面倒くさいじゃん。 でも実はそういうのを暗黙でやってくれる、knife-soloというナイスなknifeアドオンがいるので、それを試す。

前提

登場するサーバーは2つ。

  • MASTERくん chef-soloとknifeの実行母体のマシン, 192.168.7.11
  • CHILDくん 自動で設定される先のマシン, 192.168.7.12

どちらもVirtualBox上のVMで動かしてるので、相互に繋がるように、NIC2を内部ネットワークで設定。 OSはCentOS6で

  • yum groupinstall -y "Development tools"
  • yum -y upgrade
  • sshの公開鍵認証の設定

くらいまで終わってる感じ。 VirtualBoxのホストはMacだけど、それは出てこない。 Chefのバージョンは 11.4.0。バージョン変わるといろいろ変わりそうな気がする。

作業ユーザーはrootだけど、root以外でやる場合でもちゃんと動くんじゃないかと思う。

MASTERくんでの作業

下準備

rubyとgemのインストール

# yum -y install ruby
# yum -y install rubygems

chefとknife-soloのインストール

# gem install chef
# gem install knife-solo

試してたときのChefのバージョンは 11.4.0。

chefの設定など

chef-solo用の設定ファイル作る

とりあえず、cookbook_pathだけちゃんとしてればいいと思う。

# cat /etc/chef/solo.rb
file_cache_path "/var/chef/cache"
cookbook_path [ '/root/chef-repo/site-cookbooks', '/root/chef-repo/cookbooks' ]

knifeの設定ファイル作る

# knife configure

適当に答えるのでいいと思う。

# cat ~/.chef/knife.rb
log_level                :info
log_location             STDOUT
node_name                'root'
client_key               '/root/.chef/root.pem'
validation_client_name   'chef-validator'
validation_key           '/etc/chef/validation.pem'
chef_server_url          'http://localhost:4000'
syntax_check_cache_path  '/root/.chef/syntax_check_cache'
cookbook_path [ '/root/chef-repo/site-cookbooks', '/root/chef-repo/cookbooks' ]

作業場所を作る

以前はknife kitchenでやってたみたいだけど、今はknife solo initを使おう。

# knife solo init chef-repo

CHILDくんに展開する

まだなにもcookbookがないけど、この状態でもCHILDくんにchef環境をインストールさせてなにもしないのを実行させたりできる。

CHILDくんにchef環境をインストール

# knife solo prepare 192.168.7.12

自動でいろいろ入っていく。-VとかーVVをつけると細かい情報がいろいろみれる。

CHILDくん向けにcookbookを実行(まだなにもない)

実行先のサーバーの情報はnodesに入るけど、まだこんな感じで空っぽのはず。

# cat nodes/192.168.7.12.json 
{"run_list":[ ]}

空っぽだからなにもしないんだけど、とりあえず動くことを確認してみる。

# knife solo cook 192.168.7.12
Checking Chef version...
Starting Chef Client, version 11.4.0
Compiling Cookbooks...
Converging 0 resources
Chef Client finished, 0 resources updated

おっけー。

cookbookを作ってCHILDくんで実行してみる

cookbookを作る

# knife cookbook create funny -o ./site-cookbooks/
** Creating cookbook funny
** Creating README for cookbook: funny
** Creating CHANGELOG for cookbook: funny
** Creating metadata for cookbook: funny

recipe書く

適当に。

# cat site-cookbooks/funny/recipes/default.rb 
#
# Cookbook Name:: lesson
# Recipe:: default
#
# Copyright 2013, YOUR_COMPANY_NAME
#
# All rights reserved - Do Not Redistribute
#
log "message" do
    message "This is the message that will be added to the log."
    level :info
end

directory "/tmp/tmpdir" do
    mode "0755"
    action :create
end

実行対象として設定

# cat nodes/192.168.7.12.json 
{"run_list":[ "recipe[funny]" ]}

CHILDくん向けにcookbookを実行(実際に作業する)

# knife solo cook 192.168.7.12
Checking Chef version...
Starting Chef Client, version 11.4.0
Compiling Cookbooks...
Converging 2 resources
Recipe: funny::default
  * log[message] action write

  * directory[/tmp/tmpdir] action create
    - create new directory /tmp/tmpdir
    - change mode from '' to '0755'

Chef Client finished, 2 resources updated

やった!

CHILDくんで確認

# ls -la /tmp/
drwxrwxrwt.  6 root root  4096  3月  5 16:54 2013 .
dr-xr-xr-x. 21 root root  4096  3月  5 10:36 2013 ..
drwxr-xr-x.  2 root root  4096  3月  5 16:54 2013 tmpdir

できとる。

はまったところ

knife solo cookがこんな感じに失敗してた。

# knife solo cook 192.168.7.12 
Checking Chef version...
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/yajl-ruby-1.1.0/lib/yajl.rb:36:in `parse': lexical error: invalid char in json text. (Yajl::ParseError)
                          {"run_list":[funny]} 
                     (right here) ------^
    from /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/yajl-ruby-1.1.0/lib/yajl.rb:36:in `parse'
    from /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.4.0/lib/chef/json_compat.rb:55:in `from_json'
    from /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.4.0/lib/chef/application/solo.rb:198:in `reconfigure'
    from /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.4.0/lib/chef/application.rb:71:in `run'
    from /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.4.0/bin/chef-solo:25:in `<top (required)>'
    from /usr/bin/chef-solo:23:in `load'
    from /usr/bin/chef-solo:23:in `<main>'
ERROR: RuntimeError: chef-solo failed. See output above.

原因は試行錯誤してるときにchef-solo/solo.rbに変なパスを書いてしまったせい。

Vオプションつけて実行するとわかるけど、knife solo cookはchef-repo自体をまるっとCHILDくんの/tmpにrsyncしている。 で、そこをワーキングディレクトリとしてchef-soloを実行しているので、chef-solo/solo.rbに変なパスが書いてあると、実行を失敗する。

chef-solo/solo.rbはとくに修正する必要はないと思う。