平成 23 年度 研究レポート課題 サーバの構築作業や運用管理を自動化

平成 23 年度
研究レポート課題
サーバの構築作業や運用管理を自動化する
「Chef」を使うためのチュートリアル
サービスディベロップメントグループ
並河
祐貴
2011 年 8 月 31 日
1
概要
「Chef」は、Ruby製のシステム管理ツールで、サーバOSでのミドルウェアやア
プリケーションのインストール・OSやミドルウェアの設定・各稼動サービスの
状態管理等、諸々のシステム構築や運用作業を自動化してくれるツールで、オ
ープンソースソフトウェアとして公開されている。Chefは、世界中で主にサー
ビスプロバイダの運用基盤として利用されており、利用実績も出始めている。
本レポートでは、この「Chef」の概要やアーキテクチャ、セットアップ手順を
解説した上で、実際の設定の流れをチュートリアル形式で解説する。
2
第1章 はじめに
「Chef」は、Ruby製のシステム管理ツールで、サーバOSでのミドルウェアや
アプリケーションのインストール・OSやミドルウェアの設定・各稼動サービス
の状態管理等、諸々のシステム構築や運用作業を自動化してくれるツールで、
オープンソースソフトウェアとして公開されている。国外では、既に37signals
やEngine Yard、RightScaleといったサービスプロバイダの運用基盤として利用
されており、利用実績も出始めている。
ところで、Ruby製のシステム管理ツールといえば「Puppet」を思い浮かべる
方も多いのではないだろうか。ChefはPuppetの競合ソフトウェアとなる位置付
けで、これらのツールで出来ることだけ挙げると、特別大きな差はないと感じ
ているが、Puppetは基本的に外部DSLとして設定を記載するのに対し、Chefは内
部DSLで設定を記載できるというような、"使い方"の違いがある。個人的には、
Rubyのコードで、ある程度柔軟に設定を書いていけるような内部DSLの仕組みは
好みだが、人によっては好みの差があるので、システム管理者が使いやすいツ
ールを選択すれば良いのではないかと考えている。
■ サーバ構築・システム管理の自動化が必要な理由
筆者の担当するアメーバピグやピグライフというサービスは、現在(2011/08)
合計で約300台近くのサーバを利用している。管理するサーバが数台のうちは、
あまり運用コストを気にしなくて良いが、上記のような数十台・数百台といっ
たオーダーになると、サーバを運用・管理する上で以下のような様々な面倒事
が発生する。
・サーバ一台一台に対して、全て手作業でオペレーションを行うのは大変
・手作業でのオペレーションミスは防止が困難
・同じ役割のサーバごとで環境差異が発生
大規模なサービスになると、まとまった台数のサーバを投入することも良く
ある話で、その都度サーバのセットアップを1つ1つ手で構築することは大変で
あり、何より投入までのリードタイムが長くなることで、投入が遅れ、機会損
失を発生させることは事業的に避けたいと誰もが思うことだろう。
3
また、サーバを運用していると、特定の役割のサーバ数十台に対して、ある
設定を追加したい、といった作業もよく発生する。こういった作業についても、
自動化の仕組みを作っておくことで、設定+確認作業をミス無く実施(もしくは
間違いが発生しても複数台に即修正を反映できる)ことは、大きなメリットであ
るといえる。
そこで、これらの課題を解決する1つの解が「Chef」のようなシステム管理ツ
ールの利用になると考える。本レポートでは、Chefの概要やアーキテクチャの
説明、セットアップ手順から、読者が実際に設定して利用できるようにチュー
トリアル形式で使い方の解説を行う。
4
第2章 Chef の仕組み
Chefは、HTTP(S)通信でのやりとりを前提としたサーバ・クライアント式のモ
デルで、基本的にはクライアント側からサーバへ情報を取得するPULL型のシス
テムアーキテクチャとなる。尚、動作プラットフォームとしては、Linux、BSD、
MacOS、Solaris等がサポートされている。(現状、Windowsはサポートされてい
ない。)
クライアント・サーバ側のソフトウェア構成は以下となる。
図1: Chefのアーキテクチャ
上図では、全てオープンソースソフトウェアでの構成となっているため、Chef
の利用をはじめる上で、必要となるソフトウェア費用等は特に発生しない(各ソ
フトウェアの詳細については、今回は割愛する)。各ソフトウェアは各々HTTPで
REST形式のAPIを介して、JSON形式のデータのやり取り・連携を行うシンプルな
アーキテクチャモデルとなる。
5
主な処理の流れとしては、chef-clientといったクライアントソフトウェアが、
chef-serverから自分自身(クライアント)に必要な設定を確認し、必要なミドル
ウェアのインストールや設定をクライアント自身に実施するといった流れとな
る。
Chefでは、サーバがどのような状態であるべきかを記載した、Cookbookと呼
ばれる設定を書くことで、複数のプラットフォームの差を吸収してくれる仕組
みがあるため、CentOSやUbuntuといった、利用するOSディストリビューション
によって、インストールスクリプトや設定を書き直すといった面倒事がなくな
り、プラットフォームによる差異を意識せずに済むようになる。
■ Chefでの登場人物と役割
ここからは、Chefで行う設定について簡単に記す。以下は、Chefの全ての設
定がおさめられるリポジトリのディレクトリ構成の第一階層目となる。
chef-repo/
|-- Rakefile
|-- certificates
|-- config
|-- cookbooks
|-- data_bags
`-- roles
Chefの仕組みを読み解くと、ディレクトリの中で、まずcookbooksとrolesと
いった2種類の大きな設定がある。
cookbooksは、Chef側でシステムのあるべき形を定義する設定を記述するもの
である。rolesは、サーバ(Chefでいうとclient、またはnodeと呼ばれる)の役割
を定義した設定のことで、例えば"Webサーバ"や"DBサーバ"といった役割単位で
グルーピングしたい場合などは、このrolesを定義する。
次に、先ほど紹介したcookbooksの中にも、様々な設定項目があり、以下が
cookbooksディレクトリ内の構成となる。
6
cookbooks/
|-- attributes
|-- definitions
|-- files
|-- libraries
|-- metadata.rb
|-- providers
|-- recipes
|-- resources
`-- templates
この中で基本となる部分は、recipes、templates、atteributesの3つである。
それぞれについて以下で説明する。
recipesは、システムのあるべき姿、つまり設定内容を実際に記載したRubyス
クリプトである。例えば、Apacheのパッケージをインストールしたい場合は、
以下のようにrecipeに記述する。
package "apache2" do
action :install
end
また、あわせて以下のように記載すると、自動起動が有効になっているか、
およびサービスが起動しているかどうかの確認も行うよう設定される。(設定が
有効になっていない場合は有効に、サービスが起動していない場合は、サービ
スを起動することが可能。)
service "apache2" do
action [ :enable, :start ]
end
次に、templatesは、ERB形式で記述可能な、実際にサーバへ配置する設定フ
ァイルのテンプレートである。動的にパラメータを変更したい箇所など、各サ
ーバで、Chefを実行した際に、実際にそのサーバの役割にあった設定値をあて
はめる場合などで利用する。そこで、Chefでは、この実際にあてはめる設定値(パ
7
ラメータ)のことをattributesと呼んでいる。
例えば、Apacheがインストールされたサーバで、roles(役割)ごとに設定値を
変えたい場合、以下のようなports.fileのテンプレートを事前に作成しておく。
Listen <%= port %>
NameVirtualHost *:<%= port %>
実際の設定値(attributes)に関しては、roles(役割)ごとに設定したり、各サ
ーバ(node)ごとに設定することも出来る。また、rolesやnodeにattributesが設
定されていない場合は、default値を決めておくことも可能となる。
8
第3章 セットアップ方法
本章では、実際にChefが動く環境のセットアップ方法について記す。ここで
は、クライアント・サーバともにLinux(CentOS 5系)での構築を前提として、説
明を進める。
■ クライアント編
ChefはRuby製のため、まずRubyのインストールが必要となる。尚、CentOS 5
系では、パッケージ管理されているRubyのバージョンが古いため、外部リポジ
トリからのインストールを以下の手順で行う。
# wget -O /etc/yum.repos.d/aegis.repo http://rpm.aegisco.com/aegisco/el5/ae
gisco.repo
# yum install ruby-1.8.7.334-2.el5 ruby-devel-1.8.7.334-2.el5 ruby-ri-1.8.7.33
4-2.el5 ruby-rdoc-1.8.7.334-2.el5 ruby-static-1.8.7.334-2.el5 rubygems
次に、Chefのインストールを行う。今回利用したChefのバージョンは0.9.18
となる。
# gem install chef -v 0.9.18
その後、以下の手順でバージョン情報が表示されると、クライアントのイン
ストールは無事完了となる。
# chef-client -v
Chef: 0.9.18
■ サーバ編
まずは、先ほど記したクライアント編のセットアップと同じ手順を実施し、
chef-clientが実行できることを確認する。
次に、以下の手順で外部リポジトリから必要なパッケージをインストールす
9
る。
# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release
-5-4.noarch.rpm
# yum install ruby-shadow gcc gcc-c++ couchdb erlang rabbitmq-server jav
a libxml2-devel zlib-devel sqlite-devel
chef-Serverのバックエンドで必要となるCouchDBとRabbitMQを起動する。
# /etc/init.d/couchdb start
# /etc/init.d/rabbitmq-server start
RabbitMQをChefで使う設定を行う。
# rabbitmqctl add_vhost /chef
# rabbitmqctl add_user chef testing
# rabbitmqctl set_permissions -p /chef chef ".*" ".*" ".*"
chef-serverや、merb、chef-serverとの連携で利用するアダプタ等のインス
トールを行う。
# gem install chef-server -v 0.9.18
# gem install merb
# gem install sqlite3-ruby -v 1.2.5
尚、CentOS 5系でインストールできるsqliteのバージョンが古いため、
sqlite3-rubyパッケージだけはバージョンを指定する形でインストールを行う。
次に、JAVA_HOMEの環境変数およびPATHを通した後、chef-solr-indexerと、
chef-solrを起動する。
# export JAVA_HOME=/usr
# export PATH=$JAVA_HOME/bin:$PATH
# chef-solr-indexer &
# chef-solr &
10
尚、きちんとした運用をする際は、これらの起動/停止スクリプトを適宜作成
した方が良い。(本レポートでは、割愛する。)
次に、chef-Serverの設定ファイルを、"/etc/chef/server.rb"として以下の
内容で配置する。以下の内容は、Chefの公式サイトで公開されているため、実
際に利用する際は、以下リンク先からコピーすると良い。
http://wiki.opscode.com/display/chef/Manual+Chef+Server+Configuration#
ManualChefServerConfiguration-ConfigureChefServer
log_level
log_location
ssl_verify_mode
:info
STDOUT
:verify_none
chef_server_url
"http://xxx.xxx.xxx.xxx:4000"
signing_ca_path
"/var/chef/ca"
couchdb_database
'chef'
cookbook_path
[ "/var/chef/cookbooks", "/var/chef/site-cookbooks" ]
file_cache_path
"/var/chef/cache"
node_path
"/var/chef/nodes"
openid_store_path "/var/chef/openid/store"
openid_cstore_path "/var/chef/openid/cstore"
search_index_path "/var/chef/search_index"
role_path
"/var/chef/roles"
validation_client_name "chef-validator"
validation_key
"/etc/chef/validation.pem"
client_key
"/etc/chef/client.pem"
web_ui_client_name
"chef-webui"
web_ui_key
"/etc/chef/webui.pem"
web_ui_admin_user_name "admin"
web_ui_admin_default_password "somerandompasswordhere"
supportdir = "/srv/chef/support"
11
solr_jetty_path File.join(supportdir, "solr", "jetty")
solr_data_path File.join(supportdir, "solr", "data")
solr_home_path File.join(supportdir, "solr", "home")
solr_heap_size "256M"
umask 0022
Mixlib::Log::Formatter.show_time = false
最後に、chef-serverおよび、chef-serverのAPIにGUIでアクセス可能となる
chef-server-webuiを起動する。これらも必要に応じて、起動/停止スクリプト
を作っておくと良い。
# chef-server -N -e production
# chef-server-webui -p 4040 -e production
起動後、ブラウザで「http://(chef-serverのIPアドレス):4040」にアクセス
すると図2のログイン画面が表示される。
図2: chef-server-webui のログイン画面
ブラウザから、ユーザ名とパスワードを"/etc/chef/server.rb"の
"web_ui_admin_user_name"と"web_ui_admin_default_password"で設定したも
12
の( サンプルでは admin / somerandompasswordhere )を入力してログインする。
画面遷移した後、パスワードの変更が求められるとログインは成功となる。
■ ChefクライアントからChefサーバへのアクセス
まず、Chefサーバ内のファイル"/etc/chef/validation.pem"をChefクライア
ントの"/etc/chef"配下にscpコマンド等でコピーする。次に、Chefクライアン
トの"/etc/chef"配下に、"client.rb"というファイル名で、以下の内容を記述
する。
chef_server_url 'http://xxx.xxx.xxx.xxx:4000'
node_name 'chef-test01'
"chef_server_url"のxxx.xxx.xxx.xxxには、ChefサーバのIPアドレスを記述
する。また、"node_name"は任意の文字列を入力する。"node_name"はわかりや
すくホスト名などを付けると良い。今回はサンプルとしてchef-test01としてい
る。
次に、以下のコマンドを実行し、Chefサーバへアクセスする。
$ sudo chef-client
実行後、特にエラーも表示されず実行されていれば処理は成功となる。この
段階で、上記コマンドを実行したChefクライアントの情報が登録され、
"/etc/chef/"配下に"client.pem"という鍵ファイルが配置され、サーバに情報
が登録される。
■ knifeコマンドのセットアップ
knifeコマンドは、Chefサーバにアクセスするクライアントソフトウェアの1
つで、コマンドラインから様々な操作を実行することが可能である。尚、knife
コマンドはchefに同梱されている。
knifeコマンドのセットアップは、まず以下のコマンドを実行し、knifeコマ
ンドの初期設定を行う。
13
$ sudo knife configure
"knife configure"では、設定項目について以下のようにインタラクテイブに
入力する。
Where should I put the config file? [~/.chef/knife.rb]
Please enter the chef server URL: [http://localhost:4000] http://xxx.xxx.xxx.x
xx:4000
Please enter an existing username or clientname for the API: [username]
chef-test01
Please enter the validation clientname: [chef-validator]
Please enter the location of the validation key: [/etc/chef/validation.pem]
Please enter the path to a chef repository (or leave blank):
上記、2つ目の質問では、chefサーバのURL(IPアドレス:4000番ポート)を、3
つ目の質問では、chefクライアントのnode name(今回のサンプルでは
chef-test01)を、残りは基本的にデフォルトのまま(Enterを押すのみ)で問題な
い。
次に、以下のコマンドを実行し、先ほどchef-clientコマンドを実行した際に
発行された"client.pem"ファイルへのアクセスを有効にする。
$ sudo chmod 644 /etc/chef/client.pem
$ ln -s /etc/chef/client.pem ~/.chef/chef-test01.pem
ここまででknifeコマンドに関する最低限の設定は完了となる。次のコマンド
を実行し、登録済のnode(Chefクライアント)名が表示されれば、動作確認は完
了となる。
$ knife node list
[
"chef-test01"
]
14
第4章 Chef を使いこなすための第一歩
本章では、Chefを利用するためにまず覚える事項をチュートリアル形式で記
す。
■ Chefのディレクトリ一式を作成する
Chefに触れる上で、最初にやる事は、Chefのディレクトリ一式を作成するこ
とである。Chefの設定は、どのマシンで行っても良いが、今回はChefクライア
ントのマシンで設定を行う。
まずは、Chefクライアントのマシンの任意のワーキングディレクトリ(ここで
はサンプルとして、ホームディレクトリ配下とする)で、以下のコマンドを実行
する。
$ cd ~
$ wget --no-check-certificate -O ./chef-repo.tar.gz http://github.com/opscode/c
hef-repo/tarball/master
$ tar zxvf chef-repo.tar.gz
$ mv opscode-chef-repo-xxxxxx chef-repo
流れとしては、opscode(Chefの開発元)のgithubから、Chefのディレクトリ一
式(雛形)が入ったファイルをダウンロードした後に展開する。ここでは、サン
プルとして、そのディレクトリ一式をchef-repoとする。
■ Cookbookを作る
まず、Cookbookの雛形となるディレクトリをknifeコマンドで作成する。
今回は、サンプルとしてsampleという名前のCookbookを以下のコマンドで作成
する。
$ knife cookbook create sample -o ~/chef-repo/cookbooks
"~/chef-repo/cookbooks/sample"にCookbookの雛形となるディレクトリが作
成されていれば成功となる。
15
■ Recipeの例
Chefでは、様々なリソースがあらかじめ用意されており、それをRecipeに組
み合わせて記載したり、Rubyで処理ロジックを書くことで、そのサーバのある
べき姿を設定として定義する。
例えば、そのサーバで単純にApacheがインストールされ稼動している状態を
作りたい場合は、以下の内容をRecipeに記載する。
package "httpd" do
action :install
end
service "httpd" do
supports :status => true, :restart => true, :reload => true
action [ :enable, :start ]
end
1つ目のセクションのpackageリソースでは、"httpd"のパッケージをインスト
ールし、2つ目のセクションのserviceリソースでは、OSブート時の自動起動を
有効にした上で、httpdをstartさせている。(stopしている場合はstartし、既
にstartしている場合は何も行わない。)
尚、Chefで利用できるリソースについては、公式ドキュメント
( http://wiki.opscode.com/display/chef/Resources )に全項目の説明と利用
可能オプション、サンプルまで揃っているため、ChefのRecipeを書く際は、こ
のページをリファレンスとして確認しながら記述していくと良い。
■ 実際にRecipeを書く
ここから、簡単な例ではあるが、Templateを使ったRecipeとして、1つのテキ
ストファイルを特定の場所に配置する例を記す。このテキストファイルには、
Chefクライアントのサーバの簡単なシステム情報を出力させるようにする。
16
まず、"~/chef-repo/cookbooks/sample/recipes/default.rb"ファイルを開き、
以下の内容を記述し、保存する。
template "/tmp/chef-sample.txt" do
source "chef-sample.txt.erb"
mode 0644
end
次に、システム情報を出力するファイルのテンプレートとして、
"~/chef-repo/cookbooks/sample/templates/default/chef-sample.txt.erb"フ
ァイルを以下の内容で作成する。
Welcome to Chef!
CPU : <%= node[:cpu][:"0"][:model_name] %>
Memory: <%= node[:memory][:total] %>
OS
: <%= node[:platform] %> <%= node[:platform_version] %>
簡単な例ではあるが、これでRecipeとTemplateの記述が完了となる。
■ Chefサーバへの登録
作成したCookbook(RecipeやTemplateを含んだもの)をChefサーバへ登録する。
Chefサーバへの登録は、以下のknifeコマンドを実行する。
$ knife cookbook upload -a -o ~/chef-repo/cookbooks/
"-a"オプションを付けると、指定ディレクトリ配下のCookbook全てをアップ
ロードすることが可能となる。Cookbookのアップロード後、以下のコマンドを
実行することで、登録されたCookbookを確認できる。
$ knife cookbook list
[
"sample"
]
17
次に、先ほど作ったCookbook(sample)を適用するため、以下のコマンドを実
行し、node(Chefクライアントに)に紐付ける。
$ knife node run_list add chef-test01 'recipe[sample]'
chef-test01は今回利用しているnode(Chefクライアント)名であり、引数の最
後に'recipe[Cookbook名]'を記述している。
■ chefを実行して反映する
Chefクライアントのコンソールで以下のコマンドを実行して、Cookbookで設
定した内容を反映する。
$ sudo chef-client
エラーも無く無事に完了した場合、実際に配置されたテキストファイルを以
下コマンドで確認すると、chef-clientコマンドを実行したChefクライアントの
システム情報が表示されている。
$ cat /tmp/chef-sample.txt
Welcome to Chef!
CPU : Intel(R) Core(TM)2 Quad CPU
Memory: 4005864kB
OS
Q8400
@ 2.66GHz
: centos 5.4
■ Attributeを使う
Attributeは、Templateなどで実際に利用する設定値を格納する器のことで、
Cookbookでデフォルト値を定義したり、Role(nodeを"Webサーバ"などでグルー
ピングしたい場合に利用)での共通の設定値、またnodeごとに設定値を定義でき
る。
18
例えば、先ほどのsampleというCookbookでデフォルトのAttributeを設定する。
ここでは以下のように、
"~/chef-repo/cookbooks/sample/templates/default/chef-sample.txt.erb"の
最後に1行追記して、保存する。
Welcome to Chef!
CPU
: <%= node[:cpu][:"0"][:model_name] %>
Memory: <%= node[:memory][:total] %>
OS
: <%= node[:platform] %> <%= node[:platform_version] %>
Memo : <%= node[:memo] %>
次に、Cookbookでのデフォルト値を定義する
"~/chef-repo/cookbooks/sample/attributes/default.rb"ファイルを以下の内
容で作成する。
default[:memo] = "None."
ファイルの作成後、先ほど同様、以下のコマンドでCookbookをアップロード
する。
$ knife cookbook upload -a -o ~/chef-repo/cookbooks/
そして、Chefクライアントで再度、以下コマンドを実行する。
$ sudo chef-client
chef-clientの実行後、同様に配置されたファイルを確認すると、最後の行に
デフォルト値として設定したものが表示されている。
$ cat /tmp/chef-sample.txt
Welcome to Chef!
CPU
: Intel(R) Core(TM)2 Quad CPU
19
Q8400
@ 2.66GHz
Memory: 4005864kB
OS
: centos 5.4
Memo : None.
最後に、先ほどのデフォルト値を設定したまま、NodeのAttributeを設定する。
knifeコマンドでNodeのAttributeを編集する場合は、以下のコマンドを実行す
る。
$ EDITOR=vi knife node edit chef-test01
"EDITOR=vi"の部分は、好みのエディタを指定することが可能である。上記コ
マンドを実行すると、エディタでNodeのAttributeが編集できる。Attributeは
JSON形式になっており、以下のように、"normal"のkeyのvalueの中に、サンプ
ルとして「"memo": "test chef-node."」を入力する。
{
"normal": {
"tags": [
],
"memo": "This is a chef-node."
},
"name": "chef-test01",
"override": {
},
"default": {
"memo": "None."
},
・・・・・以下省略・・・・・
エディタを保存して終了すると、"Saved node[chef-test01]"と標準出力され、
Attributeの設定が完了する。
その後、これまでと同様の手順で、Cookbookをアップロードした後、
chef-clientコマンドを実行する。その後、配置されたファイルを確認すると、
20
最終行がNodeのAttributeに設定した値に置き換わっていることが確認できる。
$ cat /tmp/chef-sample.txt
Welcome to Chef!
CPU : Intel(R) Core(TM)2 Quad CPU
Memory: 4005864kB
OS
: centos 5.4
Memo
Q8400
@ 2.66GHz
: This is a chef-node.
このようにCookbookやRoleなどにデフォルトのAttributeを設定しておくこ
とで、基本的にそれらの値を反映させつつ、上記のようにNodeのAttributeを利
用し、特定のNodeについては、個別に値を反映させたり、特別な処理(Recipeに
記載しておく)を加えたりすることもできる。
21
第5章 まとめ
本レポートでは、Chefの概要、アーキテクチャの解説や、実際にCookbookを
作成し、基本となるRecipe、Template、Attributeを使った簡単なサンプルをチ
ュートリアル形式で解説した。
Chef自体は、アメーバピグやピグライフ、およびdkstatの一部で導入してお
り、アメーバのインフラとして、運用の過程で改善している段階である。同一
の環境とするべきサーバが複数台ある環境においては、間違いなく運用コスト
は下がると考える。アメーバでの運用過程で得られたこれらのノウハウについ
ては次回のレポートや社内外の勉強会で発信していく次第である。
Chef自体はまだ多くの機能があるため、もっと深く学ぶ場合は公式ドキュメ
ント(http://wiki.opscode.com/display/chef/Home)を読むことで多くの情報
を得ることができる。また、今回はknifeコマンドで多くの設定を行ったが、Role
やNodeの設定については、chef-serverのWebUIから設定を行うことが可能であ
る。ちょっとした確認や設定であれば、WebUIを使う方が視覚的にわかりやすい
面もあるため、一度触ってみると良いだろう。本レポートにより、エンジニア
がシステム管理ツールを導入するための第一歩目になれば幸いである。
22