売り上げランキング: 16
自動構成管理ツールChef(のスタンドアロン版であるChef Solo)の入門本である「入門Chef Solo - Infrastructure as Code」を読み始めました。
サーバ管理を1台でもやっていて、自動構成管理をしたことがない人は、間違いなく読む価値があります。
サーバの自動構成管理は、たった1台のサーバを管理するだけでも大いにやる価値があります。 もしも色々と手を加えてたくさんのサービスを動かしているサーバが壊れて、1から再構築しなおさなければならないときに、 前の状態まで間違いなく戻せる自信がありますか?僕はないです。 また、Chefのようにコードの形で構成情報を記述できるということは、 それをバージョン管理することでサーバの構成情報を時系列にトレースすることも可能となります。
自分のメールサーバを運用しているVPSとか、研究室の自分用ルータ兼CIサーバ兼gitレポジトリ用のマシンとか、 適当なシェルスクリプトと作業日誌でなんとかお茶を濁してきたのですが、 そろそろもっとスマートな方法で管理したいと思っていたところに、 ちょうどいい本が出てきたので早速買って読んでみました。 大体半分くらいは読み終わりました。
Chefというソフトウェアは、サーバの設定を一元管理するためにいろいろな概念を導入しているので、 いきなり全部を理解しようと思うとおそらく挫折してしまいます。 この本は、Chefを使い始める上で最初にどこからとりかかればよいのか、 とても丁寧に解説されていてまさに「入門」にうってつけです。
気になった点
代表的なレシピのサンプルとして chef-td-agent が紹介されていますが、
この中で参照している ohai の node['lsb']['codename']
はこのような使い方をするべきではないと思います。
(...)
case node['platform']
when "ubuntu"
dist = node['lsb']['codename']
(...)
apt_repository "treasure-data" do
uri source
distribution dist
(...)
end
(...)
chef-td-agentの例では上のようなコードでLinuxのディストロ名を取得して、それを元に td-agent の apt-line を構成します。
ここで、lsb_release
コマンド(lsb-release
パッケージ)がインストールされていない場合には、
ohaiはcodenameを取得できず、dist
の値はnil
になってしまいます。
結果として不正な apt-line が生成されて、td-agent
パッケージのインストールは失敗します。
lsb_release
がないなら、package
リソースで事前にインストールして ohai を reload すればええやん、
と思うのですが、実はこれでもうまくいきません。
package "lsb-release" do
action :install
end
ohai "reload" do
action :reload
end
(...)
case node['platform']
when "ubuntu"
dist = node['lsb']['codename']
(...)
apt_repository "treasure-data" do
uri source
distribution dist
(...)
end
(...)
コードで書くとこんな感じでしょうか。
見た目的には、上から逐次リソースの記述が評価されていけば、
dist =
にたどり着くときには ohai がリロードされて node['lsb']['codename']
に正しい値が設定されていそうに見えます。
しかし実際には、Chefのレシピは実行される前に一旦コンパイルされ、node['lsb']['codename']
はコンパイル時点の値に固定化されます。
そのため、上のようなレシピを書いても、lsb_release
が存在しない状態で作成されたohaiのnode
が参照され、dist
の値はnil
になり、
誤ったapt-lineが登録されてしまうため実行に失敗します。
ただし、2回目に実行したときにはlsb_release
コマンドが存在するので、
コンパイル時点でohaiはnode['lsb']['codename']
を正しく検出でき、今度は成功します。
そういうわけで、場合によっては1回目が失敗して2回目が成功するという、少しいやらしいレシピが出来上がってしまいます。裸のdebian squeezeではlsb_release
がないので、まさにこの問題ではまりました。
そういう意味で、キーサーバからキーを勝手に取得する等々便利な側面もありますが、apt
クックブックのapt_repository
はちょっと使いどころに困る代物です。
では、どうすればlsb_release
がインストールされていない状態から1発で成功するレシピを書くことができるか?
ベストな方法かどうかわかりませんが、template
リソースを使うことでとりあえずの問題は解決できます。
template
リソースで指定したテンプレートファイル中でのohaiの値はファイル生成時点で逐一評価されるため、ohaiのリロードが効きます。
あとは、ruby_block
リソースもohaiの値を実行時に評価できるので、コマンド実行とかはこちらに任せてしまえそうです。
余談
レシピのコンパイルというのは、実際のところレシピであるRubyプログラムが全て評価されて、Chefの内部的な実行プランみたいなものを生成して、 その生成されたプランが実行されることで初めてレシピに記述された処理が走るという仕組みになっているのだと思います。 イメージとしては、Lispのマクロ展開とコード実行に近い感じでしょうか。
レシピを実行する仮定でシステムの状態が更新されてゆき、それをohaiをリロードしながら拾って追随する、 というパターンの処理は、この評価の仕組みを理解していないときちんと記述するのは難しいです。
ツイート