ようへいの日々精進XP

よかろうもん

knife-xenserver で XenServer を三枚におろす一部始終(リターンズ)(2)

概要

  • 以前に試した knife-xensever を改めて試してみる
  • 前回は XenServer の調子が悪くて断念してしまったこともあり、改めて、knife-xenserver と chef を利用したサーバーの構築を行なってみたい

前回まで

  • knife-xenserver を利用して VM の作成したりテンプレートの一覧取得等を行った
  • 同様に knife-xenserver を利用して VM の削除を行った
  • knife-xenserver が XenServer とどのような通信をしているのかをちょっとだけ調べた

今回

  • node の初期設定(bootstrap)の挙動を確認する
  • Chef Server(Hosted Chef)を利用して VM に対して cookbook を適用してみる

node の初期設定について

対象の node に対して chef が利用出来る状態を準備するステップ(という認識でいる)が bootstrap。今回の knife-xenserver でももちろん、

        --bootstrap-version VERSION  The version of Chef to install
        --skip-bootstrap             Skip bootstrap process (Deploy only mode)

上記のように bootstrap に関するオプションが用意されている。前者が任意のバージョンの chef をインストールする、後者は bootstrap のステップをスキップするオプションで、基本的には knife xenserver vm create を実行した際には漏れ無く bootstrap は実行されるようだ。

では、knife-xenserver の中でどのように bootstrap が実行されているのかを見てみたい。(おそらく、このロジック自体は他のクラウド用プラグインでも同じ挙動かと思われる)

knife-xenserver の中の bootstrap

knife-xenserver/lib/chef/knife/xenserver_vm_create.rb の一部を抜粋してみる。

 28       deps do
 29         require 'readline'
 30         require 'chef/json_compat'
 31         require 'chef/knife/bootstrap'
 32         Chef::Knife::Bootstrap.load_deps
 33       end

冒頭で他のライブラリと合わせて require 'chef/knife/bootstrap' chef 自体の bootstrap ライブラリをロードしている。

318       def bootstrap_for_node(vm)
319         bootstrap = Chef::Knife::Bootstrap.new
320         bootstrap.name_args = [@ssh_ip]
321         bootstrap.config[:run_list] = config[:run_list]
-- 略 --
326         bootstrap.config[:distro] = locate_config_value(:distro)
327         # bootstrap will run as root...sudo (by default) also messes up Ohai on CentOS boxes
-- 略 --
333         bootstrap
334       end

同じように最後の部分で require した bootstrap ライブラリを利用して bootstrap_for_node を定義しているように読み取れる。うんでもって...

305           bootstrap_for_node(vm).run
306           puts "\n"
307           puts "#{ui.color("Name", :cyan)}: #{vm.name}"
308           puts "#{ui.color("IP Address", :cyan)}: #{@ssh_ip}"
309           puts "#{ui.color("Environment", :cyan)}: #{config[:environment] || '_default'}"
310           puts "#{ui.color("Run List", :cyan)}: #{config[:run_list].join(', ')}"
311           puts "#{ui.color("Done!", :green)}"
312         else
313           ui.warn "Skipping bootstrapping as requested."
314         end

ちょっと戻るけど bootstrap_for_node を run しているんだろうなあという理解。で、次に疑問に思ったのは chef 自体の bootstrap ライブラリって何しているんだろう...ということで...

chef の bootstrap ライブラリ

chef-11.4.4/lib/chef/knife/bootstrap.rb の一部を抜粋してみる。

130       def find_template(template=nil)
131         # Are we bootstrapping using an already shipped template?
132         if config[:template_file]
133           bootstrap_files = config[:template_file]
134         else
135           bootstrap_files = []
136           bootstrap_files << File.join(File.dirname(__FILE__), 'bootstrap', "#{config[:distro]}.erb")
137           bootstrap_files << File.join(Knife.chef_config_dir, "bootstrap", "#{config[:distro]}.erb") if Knife.chef_config_dir
-- 略 --
140           bootstrap_files.flatten!
141         end

んん? どうやら何かしらのテンプレートファイルを読み込んでいるみたい。 しかも :distro で何かを定義しているっぽいぞ...そして、chef-11.4.4/lib/chef/knife/ 以下に bootstrap というディレクトリあるので確認してみる。

$ tree
.
├── archlinux-gems.erb
├── centos5-gems.erb
├── chef-full.erb
├── fedora13-gems.erb
├── ubuntu10.04-apt.erb
├── ubuntu10.04-gems.erb
└── ubuntu12.04-gems.erb

幾つかの OS ごとの erb ファイルがある。centos5-gems.erb あたりを少し見てみる。

cat centos5-gems.erb
 17   wget <%= "--proxy=on " if knife_config[:bootstrap_proxy] %>http://production.cf.rubygems.org/rubygems/rubygems-1.6.2.tgz -O - | tar zxf -
 18   (cd rubygems-1.6.2 && ruby setup.rb --no-format-executable)
 19 
 20   popd
 21   rm -r "$tmp_dir"
 22 fi
 23 
 24 gem update --system
 25 gem update
 26 gem install ohai --no-rdoc --no-ri --verbose
 27 gem install chef --no-rdoc --no-ri --verbose <%= bootstrap_version_string %>
 28 
 29 mkdir -p /etc/chef

なにやら gem で chef をインストールしたり、/etc/chef にディレクトリ作ったり...ざっくり言うと chef を使えるようにしている。ということで、あらためて knife-xenserver を見てみる。

knife xenserver vm create -d ${distro}

何気なく knife xenserver vm create -h を眺めていて --distro ってオプションがあったものの特に意識はしていなかった。が、しかし、意外に重要なオプションであることに気づいた。

    -d, --distro DISTRO              Bootstrap a distro using a template; default is 'ubuntu10.04-gems'

特にこのオプションを指定しないまま knife xenserver vm create を実行しようとすると、OS が ubuntu10.04 であればおそらく何の問題は無いが、それ以外(ubuntu 系も大丈夫??)の OS の場合には下記のような状態になってしまい bootstrap は失敗してしまう。

Waiting for sshd... 
Trying to SSH to xxx.xx.xx.xx...  done
Bootstrapping Chef on xxx.xx.xx.xx
xxx.xx.xx.xx bash: line 3: apt-get: command not found
xxx.xx.xx.xx bash: line 4: apt-get: command not found
xxx.xx.xx.xx bash: line 5: wget: command not found
xxx.xx.xx.xx 
xxx.xx.xx.xx gzip: stdin: unexpected end of file
xxx.xx.xx.xx tar: Child returned status 1
xxx.xx.xx.xx tar: Error is not recoverable: exiting now
xxx.xx.xx.xx bash: line 6: cd: rubygems-1.6.2: No such file or directory
xxx.xx.xx.xx bash: line 9: gem: command not found
xxx.xx.xx.xx bash: line 10: gem: command not found
xxx.xx.xx.xx bash: line 11: gem: command not found
xxx.xx.xx.xx bash: line 62: chef-client: command not found

今回、検証で利用している OS は CentOS 6.4 で当然、apt-get は利用出来ない...ので、今回の検証では -d オプションに chef-full を指定することで正常に bootstrap を行うことが出来た!おそらく、OS の環境に合わせて bootstrap のテンプレートを自作することも可能な構造であると思われる。

まとめ

  • bootstrap も奥深い
  • --distro オプションは必須
  • また cookbook 適用まではたどりつけんかった...