こんにちは。国平です。

前回の記事で、最後に「viの記事を書こうか」とか書いてましたが、個人的にもっと熱いネタが見つかったので急遽ネタを変更して、ChefとFabricを比較してみます。

目的

本記事の目的は、複数のサーバマシンで全く同じ環境を用意するためのツールの検証です。

Webサービスの開発/運用では、複数のサーバを用意して冗長化を図ります。 また、AWSのようなクラウドサーバを利用していると、サービスの拡大に合せて柔軟にスケールアウトする事が可能となります。

弊社でもこちらの記事にあるように、複数台のサーバでサービスを運用し、更に負荷状況に合せてサーバのスケールアウトが出来るように環境を用意しています。

当然、サービスのリリース時には全てのサーバが同じ設定で動くように用意されていますが、運用が長く続くと各サーバ環境が同じである事を保証するのが難しくなってきます。 例えば、あるサービスの初期リリースでは2台のサーバで運用し、サービスの拡大に合せて新たにサーバを追加する際などに、インストールするツールのバージョンが微妙に異なったり、微妙にパスの通し方やファイルのユーザ権限の設定がズレていたいたりといった問題が発生しがちです。

こういった問題を回避するために、各サーバで全く同じ環境を用意できるツールが必要になります。 そのツールとしてChefとFabricを取り上げ、比較を行ってみます。

Chefとは

http://www.opscode.com/chef/

Chefとは最近話題の構成管理ツールです。 Chefを利用する事により、サーバの環境構築を自動化する事が出来ます。 Ruby製のツールで、Rubyのコードでサーバの環境設定を設定ファイルにまとめる事が出来ます。 (※ Chefではこの設定をレシピと呼びますが、今回はFabricと比較するため設定ファイルと記述します。)

設定内容をソースコードとして残す事が出来るので、何度でもサーバを同じ状態に構築する事が出来ます。 設定内容はDDLとして用意されており、読みやすいだけでなく、Rubyになじんだ人なら拡張もしやすいかもしれません。

Chefの利用方法には2通りあります。 ひとつは単一マシン上で動作するChef-Soloで、環境構築を行いたいマシン上に設定ファイルを配備しそのマシン上でChefを実行します。そのため、各マシンに対して設定ファイルを配備して、Chefを実行することになります。

もうひとつはChef-Serverを利用する方法です。この方法では、設定ファイルを配備するChef-Serverマシンと、Chefを実行して環境構築するChef-Clientマシンを分離することができます。Chef-ClientはChef-Serverから自動的に設定ファイルを取得して実行します。この方法だと、複数のマシンに対する設定ファイルを一元管理できます。さらに、Chef-Serverの設定が変更されると、Chef-Clientは自動的に同期をとるので、変更の反映を各サーバに対し実行する必要がありません。

Chef-Solo、Chef-Server/Clientのどちらを利用するにしても、各マシンに対してChefのインストールが必要になります。

また、今回の調査の範囲に含んでいませんが、自動テストを書くこともできるようです。作成した設定ファイルを保守することを考えると、テスト可能であることは非常に重要ですね。

Fabricとは

http://docs.fabfile.org/en/1.6/

Fabricはアプリケーションのデプロイツールです。 Fabricも自動でサーバを操作する事の出来るツールで、リモートサーバに対して、ファイルの転送・コマンドの実行を行う事が出来ます。

Pythonで作られており、サーバに対する操作内容をPythonで記述します。 Fabricの設定ファイルは、シェルスクリプトに似たコマンド、もしくは直接シェルスクリプトを実行するため、シェルスクリプトを書いた事がある人はなじみやすいかもしれません。

Fabricは、Fabricの実行サーバから実際に環境を構築するリモートサーバにSSH接続を行い、設定ファイルに書かれた処理を実行します。 そのため、Fabricをインストールするマシンは1台だけで済みます。

ChefとFabric

共通点

ChefとFabricでは、どちらでも「サーバに対する操作をソースコードとして記述」するので、Gitなどでバージョン管理する事が可能です。 そのため、複数のサーバを用意する際、サーバ間の微妙な誤差をなくす事が出来ます。

異なる点

前述のように、Chefは構成管理ツール、Fabricはデプロイツールとそもそも対象とする領域が異なっています。

構成管理ツールではサーバ環境の構築を目的としており、デプロイツールではサーバ上にアプリケーションの配備を行う事を目的としています。 ただし、主目的が異なっているだけで、どちらでもそれぞれが得意とする事は実現可能となっています。

また、Chefによる環境構築を行うためには対象となるサーバ全てにChefをインストールする必要がありますが、Fabricでは1台にインストールすればリモートサーバにはインストールの必要がありません。

利用してみる

今回、ChefとFabricを比較するにあたって、試しにNginxのインストール手順をそれぞれのツールで書いてみました。 Nginxインストールの要件として、以下を設定しました。

  • Nginxをソースからビルドする
  • ビルドに必要なライブラリなどもインストールする(g++など)
  • nginx.confを配備する
  • nginx.confはテンプレートを用意し、本番環境/開発環境で設定内容を書き換えられるようにする

本番環境と開発環境でサーバのマシンスペックが異なるということはよくあると思います。 nginxのチューニングでは、マシンのCPU数に合わせてworker_processを設定します。 (Nginx+Play2.0利用時のNginxとAkkaのパフォーマンスチューニング)

ここでは環境に合わせてconfファイルを書き換えて配備できるようにしてみます。 想定しているサーバのマシンスペックは、開発環境がコア数1、本番環境がコア数2を想定しています。 (AWS EC2インスタンスの、m1.smallとm1.largeインスタンスをイメージしています)

ちなみに、nginxをインストールするマシン環境は前回の記事で紹介したVagrantを使って用意しました。 やっぱりVagrantは便利ですね。

Chef

今回、Chef-Serverを用意するのが面倒だったので、Chef-Soloを利用しました。 そのため、1つのサーバですべての作業が完結しています。

設定ファイル

Chefの設定ファイル群の構成は下記の通りです。

これらのうち、主要な部分をgistに載せました。実行は、_run chef-soloのシェルになります。 https://gist.github.com/Kuchitama/5547882

Fabric

Chefは1サーバで完結しましたが、こちらは折角なのでFabricをインストールしたサーバ(サーバA)とNginxをインストールするサーバ(サーバB)を分割しました。 サーバA上でFabricのタスクを実行すれば、サーバBにNginxがインストールされます。

設定ファイル

gistはこちらです。 _run fabricのシェルで実行できます。 https://gist.github.com/Kuchitama/5548125

使った上での比較

実は、どちらのツールでもNginxのインストール設定は既に公開されているのですが、今回は比較のため自分の手を動かして設定ファイルを全て書いてみました。 公開されている設定は下記になります。

私は、RubyもPythonもなじみが無かったのですが、ドキュメントを漁りながら書いて行く事でどちらも2,3時間で作成出来ました。

Chefについて

メリット

実際に触ってみたChefのメリットは以下の点が挙げられます。

  • べき等性が保証される
  • 公開されている設定ファイル(レシピ)が豊富
  • 日本語の資料が多い

べき等性とは、何度実行しても同じ結果になるということです。 複数のマシン上でChefを実行しても同じ設定で動作させれば同じ状態になることが保障されています。

今回は、設定ファイルを自作しましたが、主だったツール、アプリケーションのインストール設定ファイルはGitHubなどで公開されていて、CloneしてChefを実行するだけで環境構築を行うことも可能です。

また、Chefはここ最近で非常に注目を浴びているツールなので日本語の情報も多くあります。

はまりポイント

触ってみてハマったポイントとして、現状のChefではRuby2系に対応していない点です。 今回、rvmを利用してRubyの最新バージョンをインストールしてから利用したのですが、エラーが発生してChefが動作しませんでした。

あと、設定の記述がRubyのDSLのため、慣れるまでは読み書きがしづらいかもしれません。

Fabricについて

メリット

  • インストールするマシンが1台で良い
  • シェルスクリプトの知識がそのまま使える

FabricはPush型の構成になっているので、リモートマシンが増えた際の対応手順が少なく済みます。

また、いくつかのコマンドはPythonの関数として用意されていますが、ほとんどシェルを書くのと同じ感覚で記述できます。 そのため、初期の学習コストはかなり少なくできると思います。 新しく設定ファイルを作成するのも、既にあるシェルスクリプトを元に設定ファイルを作成するのも、それほど難しくはないと思います。

はまりポイント

今回初めてPythonを触ったのですが、FabricのインストールについてはPythonからインストールしなくてはならず、Chefのインストール以上に手間取りました。

ただ、1台にインストールしてしまえば、リモートサーバにはインストールの必要が無いので、全体としてはそれほど手間がかかるということもないのかもしれません。

また、ツールとしてべき等性が保証されているわけではないので、設定ファイルの作成者が保証するか、Fabricの実行者が手順を守る必要があります。

今回作成した設定ファイルですと、g++が既にインストールされていた場合について考慮されていないので、g++のインストールタスクが複数回実行されると予期しない動作を起こしてしまいます。

比較表

項目 Chef Fabric
構成 Chef-Solo Fabricサーバ → リモートマシン
言語 Ruby(1.9系) Python(2.5~)
設定ファイル DSLで記述 Pythonで記述(シェルライク)
日本語ドキュメント 豊富 少ない
サンプル 豊富 少ない
サーバ追加の作業 多少多い: Chefインストールの手間がかかる 少ない:タスクの実行先を追加するだけ

まとめ

今回、ChefとFabricをそれぞれ利用して、比較してみました。 どちらも1度設定を書いたら実行するだけで、がりがりとインストールが進むのが楽しかったです。

使ってみた所感ですが、それぞれの向き不向きとして、Chefはツールなどのインストールに強く、Fabricはシェルコマンドの実行に強いという印象でした。

それぞれを試してみる前は、今後の利用をどちらか一方に絞るつもりでしたが、両方を使い分けるのもいいかもしれません。

どちらにしても、サーバに対する作業内容をソースコードとして管理できるのは非常にメリットが大きく、サーバの運用工数の削減につながると思います。