chef-provisioningでお手軽にChef-zero対応してみる
Chef使いの皆さんなら、Chefから、Local Modeが使えるようになったので、Chef-Soloから乗り換えるといいよといったようなアナウンスを聞いているかと思います。
これは、普段Chef-soloを使っていた私からすると、次の手を探さないといけません。まだ方法は模索中ですが、chef-provisioningを使う方法がすんなり出来たのでその手順を共有したいと思います。とりあえず、簡単にサクッとやりたいんや!
- Chef-soloからChef-zeroへは甘くない
Chef-soloは便利でした。ChefServerなしで、レシピをプロビジョニングできるのでとてもお手軽でした。日本ではそのシンプルさから多くの人に好まれているようです。私も同じです。ところが、この度Local Modeが出来て、Chef-zeroという、ローカルで動作するインメモリのChefServerを使うような仕組みになっています。先のアナウンスでは、Local Modeは、Chef-soloのすべての機能を内包しているので、乗り換えな!といっているのですが、実はそんなに甘くないのです。
次の素晴らしいエントリでも解説されているように、Local Modeで使われる、Chef-zeroでつくられるローカルのサーバーは、プロビジョン先のサーバーからデータを取得しにくるようになるのです。ということは、普通に考えると、プロビジョン先のサーバーがvagrantでつくったものの場合、vagrantから、ホストコンピュータにアクセスできる必要があるのです。そのため、一工夫しないと、気軽に自分のつくったCookbookをプロビジョン先のサーバーにさっと渡すことができません。
Chefのローカルモードだけでリモートサーバを運用してみようと、Knife-Zeroを作った。Nodeの構成情報もとれるよ。
Chefとしては、Chef-soloは上記のアナウンスを見ても、いまいちな方法を思っているらしく、本番にはおそらくChef Serverをつかった方法で運用してほしいという意図が読み取れます。Chef-zeroにしても、実はテストの用途や、Chef-soloの用途と書いてあるけどセキュアでもないし、スケーラブルでもないし、永続的でもないと説明しています。
- Chef-soloからの移行の幾つかの手段
2.1. Knife-zero
真っ先に試してみたのが、knife-zeroです。これはknifeのプラグインで、chef-solo感覚で、Local Modeを使えるようにした素晴らしいツールです。もっともシンプルな記事はhttp://knowledge.sakura.ad.jp/tech/2708/ これが流行ってほしいとは思うのですが、私の方で試してみたところ、また若干枯れていないところがあるのと、私がミスをしているのかもしれませんが、knife zero chef-client
のオプションなどの指定が、vagrantを使っているときにいまいちどうしたらいいかわらなかったりしました。このツールが悪いというより、元々Chef-zeroという構造がややこしいので、試していないユースケースがあるといろいろ調整しないといけない段階なのだと思います。
こういうのも、だんだん情報がでてくると思うので、すぐに解消されるとは思います。エラーを報告したり、Pull Requestを送ったりして貢献しましょう!
2.2. Ansible
Chefの対抗で、シンプルさが売りのAnsibleです。チュートリアルをやりましたが、本当にシンプルですぐに開始することができました。しかし、私はRuby使いでPython使いではないことと、もう一度DSLを覚え直すのが面倒なこともあり、Chefからの鞍替えはできれば避けたいところです。
2.3. Chef-provisioning
さて、現状ではこれがいいかな。と思ったのはChef-privisioning。元々RubyのDSLで、複数のマシンをプロビジョニングするための、Chef-Metalというツールが名前が変わったものです。これはChefからリリースされているものなので、ある程度いろんなケースがテストされているようです。サポートされているプラットフォームは、vagrant, aws, Digital Ocean, Dockerなどなど。Azureは一応ありますが、まだ本番には使うなよって書いてありました。サクラとかの場合は自分でプラグインを書く必要があるかもしれません。(サクラ派ではないので試していません、、、w)ですので、それ以外のクラウド使いの人は向いていないかもしれません。
元々クラスタをプロビジョンするための仕組みなので、knife-zeroが充実する方が元々の意図をみたしやすいのでオススメですが、それまでの間、お手軽にできないんかいな!というときで、かつ上記のようなプラットフォームでしかレシピを流さない人は結構快適かもしれません。
ですので、Chef-soloの代替えという用途では、若干邪道ですが、結果として、快適なので、しばしこの方法でいってみたいと思います。(ただし、壁にぶつかるかもしれませんが、保証はいたしかねますw)
Chef Provisioning: Infrastructure As Code
- Chef-provisioningをつかったレシピ流し
だらだらといろいろ書きましたが、Chef-provisioningをつかったレシピ流しのためのチュートリアルを私含めた皆さんが慣れていないChefServerを扱う時のコマンド含めてご説明したいと思います。MacBookPro Yosemiteで動作確認しています。
3.1. Chefリポジトリの作成
最近はChefはChefDKというツールがリリースされています。これはdmgファイルになっていて、インストールすると、chefの各種ツールが入るようになっています。(実は私はあまりこの方法が好きではありません。Bundlerとかで柔軟に使える方がいいなと思います。実際それでもいいと思います。)
方法はともかく、chefをインストールすると、chefリポジトリを作成します。ここでは名前をchef-zeroにしてみました。この後gitの管理下に置くとかするといいと思います。
$ chef generate repo chef-zero
$ cd chef-zero
ここでできるディレクトリ構造はChefを使う人のための、最低限のRuby関連知識というエントリに昔まとめてみましみましたので、慣れていない人は読んでみてください。
3.2. Gemfileの設定
次にGemfileを書いてみましょう。
source 'https://rubygems.org'
gem 'chef'
gem 'chef-zero'
gem 'berkshelf'
gem 'chef-provisioning'
gem 'chef-provisioning-vagrant'
こんな感じで、書いておきます。そして、実行しておきます。
$ bundle install
3.3. Local Modeの設定
Knifeのローカルモードを設定するためにはどうしたらいいでしょう?例えばknifeコマンドだと、-z
コマンドでローカルモードになりますが、指定を忘れると謎挙動になりやすいとのことなので、ここは、.chef/knife.rb
に設定をしておきましょう。これで、このリポジトリのディレクトリにいるときは、knifeコマンドのオプション指定が不要になります。(後述のchef-clientでは必要なので注意)
$ echo "local_mode true" >> .chef/knife.rb
3.4. Cookbookの作成
サンプルのために、なんらかのCookbookが必要です。今回の趣旨はここではないので、面倒なので、Berkshefを使ってさっとつくってしまいます。
Berksfileはこんな感じ。まずzshのクックブックをとってきます。
source "https://api.berkshelf.com"
cookbook 'zsh'
このコマンドを実行します。これで、cookbooks配下にZshのCookbookが格納されました。
$ bundle exec berks vendor cookbooks
3.5. Chef-provisioningの準備
こいつを、Vagrantで仮想マシンを立ててプロビジョニングを決めてみることにします。まず実施することは、環境変数の設定です。
$ export CHEF_DRIVER=vagrant
ちなみに、vagrantはこうですが、AWSだと例えばここがfog:AWS
になったりします。詳しくは本家のページをごらんください。
次に、chef-provisioning用のファイルを書きます。
vagrantの場合は、2つ書きます。どこでもいいのですが、私はprovisionというサブディレクトリを掘ってその下に置きました。
$ mkdir provision
$ vim provision/vagrant_linux.rb
vagrant_linux.rb このファイルはvagrantの時は必要ですが、AWSの時は不要みたいです。
require 'chef/provisioning/vagrant_driver'
vagrant_box 'precise64' do
url 'http://files.vagrantup.com/precise64.box'
end
with_machine_options :vagrant_options => {
'vm.box' => 'precise64'
}
そして、プロビジョンをするマシンを記述するファイルです。ここではsample.rb
という名前にしてみました。この例では、sandayuuという名前の仮想マシンを1台立ち上げて、zshのレシピを流すというものです。タグ名もつけています。ちなみに、ここに複数台のマシンを書くことも当然可能です。
require 'chef/provisioning'
machine 'sandayuu' do
recipe 'zsh'
tag 'itsa_me'
converge true
end
3.6. プロビジョニング
さて、vagrantの仮想マシンを立ち上げてChefを打ち込んで、レシピを流しましょう。普段なら、仮想マシンをvagrantで起動して、vagrant ssh-config
をつかって、アクセスできるようにして、、、とかいろいろ面倒でしたが、これを使えば余裕です。
$ chef-client provision/vagrant.rb provision/sample.rb -z
はい、このコマンド一発で、provision/sample.rbの内容が反映されます。最後の -z
はLocal Mode指定ですね。自分は試していませんが、Vagrant+Chefの代表的謎挙動防止ポイントである、メモリ増やすとかの指定とかも、vagrant.rbとかの中の記述できっといけそうですね。
このコマンド一発で何が行われているかというと、、、
1. Chef-zeroのサーバーにレシピと、プロビジョニング先のマシンの情報を転送
2. Vagrantで仮想マシンを立ち上げ
3. 仮想マシンにsshで接続して、chefのクライアントをインストールする
4. 仮想マシンから、Chef-zeroサーバー(母艦で動作中)からレシピを取得
5. 仮想マシンで、レシピをchef-clientで実行して、プロビジョニング
という感じです。なんの問題もなくすんなり起動します。
もし、レシピとかにエラーがある場合も指示に従えばオッケーです。
ちなみに、現在Chef-zeroサーバーに対象の仮想マシンのノード(sandayuu)が登録されていることが、次のコマンドで確認できます。このコマンドはローカルのChef-zeroサーバーにアクセスしています。
$ knife node list
history.local
sandayuu
さらに、具体的な内容を見るためにはこんなコマンドです。
$ knife node show sandayuu
Node Name: sandayuu
Environment: _default
FQDN: sandayuu
IP: 10.0.2.15
Run List: recipe[zsh]
Roles:
Recipes: zsh
Platform: ubuntu 12.04
Tags: itsa_me
これは、chef-solo時代にはなかった感じですね。あくまでサーバーで管理されているのです。
ローカルのインメモリですが。
3.7. レシピの変更と流し直し
さらにもう一歩すすめて、プロビジョニングした後にレシピを変更した場合を想定してみましょう。
単純にapache2
のクックブックを追加してみるユースケースをやってみます。
最初に、Berksfileを変更して、クックブックを追加してみます。
source "https://api.berkshelf.com"
cookbook 'zsh'
cookbook 'apache2'
apache2を追加してみました。変更を反映しましょう。
$ bundle exec berks vendor cookbooks
これで、cookbooksの下にapache2のcookbookが追加になりました。こいつを反映してみます。
反映は簡単で、provision/sample.rbを変更しましょう。
require 'chef/provisioning'
machine 'sandayuu' do
recipe 'zsh'
recipe 'apache2'
tag 'itsa_me'
converge true
end
一行だけ追加しました。では、反映させましょう。先ほどと全く同じコマンドです。
$ chef-client provision/vagrant.rb provision/sample.rb -z
もうすでに仮想マシンは起動していますし、Chef-clientもインストールされていますので、変更部分のみが反映さてれいます。コンソールで確認できますが、念のためChef-zeroサーバーの情報も確認してみます。
$ knife node show sandayuu
Node Name: sandayuu
Environment: _default
FQDN: sandayuu
IP: 10.0.2.15
Run List: recipe[zsh], recipe[apache2]
Roles:
Recipes: zsh, apache2, zsh::default, apache2::default, apache2::mod_status, apache2::mod_alias, apache2::mod_auth_basic, apache2::mod_authn_core, apache2::mod_authn_file, apache2::mod_authz_core, apache2::mod_authz_groupfile, apache2::mod_authz_host, apache2::mod_authz_user, apache2::mod_autoindex, apache2::mod_dir, apache2::mod_env, apache2::mod_mime, apache2::mod_negotiation, apache2::mod_setenvif, apache2::mod_rewrite, apache2::mod_deflate, apache2::mod_headers
Platform: ubuntu 12.04
Tags: itsa_me
こりゃ楽だわ。
3.8. その他の話題
さて、トラブルシューティング系ですが、ちょっと試しただけなのでわかりませんが、あまり苦労はしていません。tipsとしては、レシピを追加して削除したときに、実際のレシピは削除されていても、Chef-zeroサーバーに残っていて、プロビジョン先の仮想サーバーに反映されてしまってたということがありました。その時は、knife node show
でChef-zeroサーバーの状態を確認して、knife node run_list remove
で削除すれば反映されました。knife nodeコマンドは、いろいろchef-zeroの状態が確認・編集できて便利なのでknife node --help
で使い方を確認するのをお勧めします。
$ knife node show sandayuu
Node Name: sandayuu
Environment: _default
FQDN: sandayuu
IP: 10.0.2.15
Run List: recipe[zsh], recipe[nginx], recipe[apache2]
Roles:
Recipes: zsh, nginx, apache2
Platform: ubuntu 12.04
Tags: itsa_me
$knife node run_list remove sandayuu recipe[nginx]
$ knife node show sandayuu
Node Name: sandayuu
Environment: _default
FQDN: sandayuu
IP: 10.0.2.15
Run List: recipe[zsh], recipe[apache2]
Roles:
Recipes: zsh, apache2
Platform: ubuntu 12.04
Tags: itsa_me
3.9. 仮想サーバーへのログイン
さて、chef-provisioningは非常に便利ですが、仮想サーバーを勝手につくってくれるのはいいのですが、こいつにログインするにはどうしたらいいでしょう?作成したChefリポジトリの下にこっそりファイルができています。
$ cd .chef/
history:.chef
$ ls
knife.rb local-mode-cache vms
$ cd vms/
$ ls
Vagrantfile sandayuu.vm
このディレクトリまで降りて行って
$ vagrant ssh
でオッケーです。ここにあるxxx.vmが自動で作成されるVagrantファイルの実態です。尚、普通のsshで接続したいという場合は、方法は私はまだ知りませんが、chef-client -zを実行時に -l debug
オプションをつけて実行するとsshで接続するポートとIPを見ることができます。
3.10. 作業ワークフローとテスト
Cookbookを作成中は、ChefDK Getting Startedにあるような感じで、testKitchenをつかってクックブックを個別にテストして作成が便利です。TestKitchenでも内部でChef-zeroが使われていますが、かなり快適に実行、テストができました。
その後実際にプロビジョンするときにChef-provisionを使います。まだ、試せていませんが、Chef-provisionで作ったクラスターを試すためのTestKitchenプラグインがあります。Kitchen-metalこれを使えば、クラスタごとテストが書けるので強力そうですね。またためしてみたいです。
- おわりに
さて、どうでしたか?Chef Provisioning: Infrastructure As Codeではさらに、複数マシンやロードバランサの書き方も載っていました。
codeでたくさんのマシンをコントロールするのは相当気持ちいですね!
では、良いお年を!