2014年1月31日金曜日

Chefってなんじゃ?

「男もすなるChefといふものを、女もしてみむとてするなり。」
 −紀貫之

ということで、いまさらすぎますがChefです。

とっても有名な入門書「入門Chef Solo - Infrastructure as Code」にだいたいのことが書いてあります。

Chefはサーバーの設定をしたりソフトウェアをインストールしたりする管理ツールとのことで、rubyのDSLでレシピを書いて実行するとサーバーの状態が変更されるので、セットアップが自動化できるとのことです。

他にChef Serverというのもあるようですが、ここでは割愛してChef Soloだけで進めます。
まずはインストールです。
前回インストールしたvirtual box内のローカルにchef soloをインストールしてみます。


rbenvのインストール


今回はrbenvからrubyを入れるためrbenvからインストールします。
rubyを直接インストールする場合は、これは必要ありません。
また、全ユーザで参照できるように、/etc/profileにrbenvのパスを設定しておきます。
$ sudo yum install -y openssl-devel git vim tree
$ cd /usr/local/
$ sudo git clone git://github.com/sstephenson/rbenv.git rbenv
$ sudo groupadd staff
$ sudo chgrp -R staff rbenv
$ sudo chmod -R g+rwxXs rbenv
$ sudo mkdir /usr/local/rbenv/plugins
$ cd /usr/local/rbenv/plugins
$ sudo git clone git://github.com/sstephenson/ruby-build.git
$ sudo chgrp -R staff ruby-build
$ sudo chmod -R g+rwxs ruby-build
$ sudo su -
# vim /etc/profile.d/rbenv.sh
export RBENV_ROOT=/usr/local/rbenv
export PATH="$RBENV_ROOT/bin:$PATH"
eval "$(rbenv init -)"
# source /etc/profile



rubyのインストール


rubyをインストールします。
sudoでchefが呼び出せるように、/etc/sudoersにパスの設定をしておきます。
# rbenv install --list
# rbenv install -v 2.0.0-p353
# rbenv global 2.0.0-p353
# ruby -v
ruby 2.0.0p353 (2013-11-22 revision 43784) [x86_64-linux]
# exit
$ ruby -v
ruby 2.0.0p353 (2013-11-22 revision 43784) [x86_64-linux]
$ gem -v
2.0.14
$ sudo visudo -f /etc/sudoers.d/rbenv
Defaults !secure_path
Defaults env_keep += "PATH RBENV_ROOT"


chefとknife soloのインストール


gemでインストールします。
$ sudo gem install chef
$ sudo gem install knife-solo
$ sudo rbenv rehash



chefリポジトリの作成


knife configureコマンドでknife設定を初期化します。これは初回だけでOKです。
そのあとknife solo initで初期ディレクトリ群を作成し、ついでにgit管理しておきます。
$ knife configure
$ knife solo init myfirstkitchen
$ tree myfirstkitchen/
myfirstkitchen/
|-- cookbooks
|-- data_bags
|-- environments
|-- nodes
|-- roles
`-- site-cookbooks

6 directories, 0 files
$ cd myfirstkitchen/
$ git init
$ git add .
$ git commit -m 'first commit'



クックブックの作成


knife cookbook createで新規にクックブック(レシピ集)を作成します。
自分のクックブックはsite-cookbooks内に置くのが習わしのようです。
$ knife cookbook create myfirstcookbook -o site-cookbooks
** Creating cookbook myfirstcookbook
** Creating README for cookbook: myfirstcookbook
** Creating CHANGELOG for cookbook: myfirstcookbook
** Creating metadata for cookbook: myfirstcookbook
$ tree .
.
|-- cookbooks
|-- data_bags
|-- environments
|-- nodes
|-- roles
`-- site-cookbooks
    `-- myfirstcookbook
        |-- CHANGELOG.md
        |-- README.md
        |-- attributes
        |-- definitions
        |-- files
        |   `-- default
        |-- libraries
        |-- metadata.rb
        |-- providers
        |-- recipes
        |   `-- default.rb
        |-- resources
        `-- templates
            `-- default



レシピの作成


まずは設定。chef-soloの実行時に、クックブックの場所がわかるように以下の内容をファイルに記述します。
クックブックの場所はcookbooksとsite-cookbooksを指定します。
$ cat ./solo.rb
file_cache_path "/tmp/chef-solo"
cookbook_path ["/home/vagrant/myfirstkitchen/cookbooks", "/home/vagrant/myfirstkitchen/site-cookbooks"]

次に実行時にどのクックブックのレシピを実行するかをjsonファイルで指定できます。
$ cat localhost.json
{
  "run_list": [
    "recipe[myfirstcookbook]"
  ]
}

やっとレシピの作成に入ります。空のdefaultレシピが配置されているので、ここに記述します。
httpdとphpをインストールし、サービス起動するように設定します。
$vim site-cookbooks/myfirstcookbook/recipes/default.rb
# Cookbook Name:: myfirstcookbook
# Recipe:: default
#
# Copyright 2014, YOUR_COMPANY_NAME
#
# All rights reserved - Do Not Redistribute
#

# install httpd & php
%w{httpd php}.each do |pkg|
  package pkg do
    action :install
  end
end

# make /etc/init.d/httd and start httpd
service "httpd" do
  supports :status => true, :restart => true, :reload => true
  action [ :enable, :start ]
end



実行


それでは実行です。実行時に、先ほど作ったsolo.rbとlocalhost.jsonを指定します。
$ sudo chef-solo -c solo.rb -j localhost.json
Starting Chef Client, version 11.8.2
Compiling Cookbooks...
Converging 3 resources
Recipe: myfirstcookbook::default
  * package[httpd] action install
    - install version 2.2.15-29.el6.centos of package httpd

  * package[php] action install
    - install version 5.3.3-27.el6_5 of package php

  * service[httpd] action enable
    - enable service service[httpd]

  * service[httpd] action start
    - start service service[httpd]

Chef Client finished, 4 resources updated

実行が正常に終わったようです。



確認


/etc/httpdにインストールされています。
$ ls -l /etc/httpd/
total 8
drwxr-xr-x 2 root root 4096 Jan 31 06:08 conf
drwxr-xr-x 2 root root 4096 Jan 31 06:09 conf.d
lrwxrwxrwx 1 root root   19 Jan 31 06:08 logs -> ../../var/log/httpd
lrwxrwxrwx 1 root root   29 Jan 31 06:08 modules -> ../../usr/lib64/httpd/modules
lrwxrwxrwx 1 root root   19 Jan 31 06:08 run -> ../../var/run/httpd


/etc/init.d/httpdがつくられています。
$ ls -l /etc/init.d/httpd
-rwxr-xr-x 1 root root 3371 Aug 13 17:30 /etc/init.d/httpd

起動しています!
$ ps -ax | grep httpd
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
25266 ?        Ss     0:00 /usr/sbin/httpd
25268 ?        S      0:00 /usr/sbin/httpd
25269 ?        S      0:00 /usr/sbin/httpd
25270 ?        S      0:00 /usr/sbin/httpd
25271 ?        S      0:00 /usr/sbin/httpd
25272 ?        S      0:00 /usr/sbin/httpd
25273 ?        S      0:00 /usr/sbin/httpd
25274 ?        S      0:00 /usr/sbin/httpd
25275 ?        S      0:00 /usr/sbin/httpd
25356 pts/0    S+     0:00 grep httpd

どうやらyumでインストールされたようです。
$ sudo yum list installed | grep httpd
Failed to set locale, defaulting to C
httpd.x86_64          2.2.15-29.el6.centos
httpd-tools.x86_64    2.2.15-29.el6.centos


PHPのindexをつくってみます。
# vim /var/www/html/index.php
<?php phpinfo();?>



ブラウザで確認すると、、、


おお、ちゃんとphpも動いてます!



保存


ここまでできたら、再度コミットしておきます。
$ git add .
$ git commit -am "add httpd&php"



このように、レシピを追加して、その状態をgit管理することでサーバーの状態をバージョン管理することができて便利なのだそうです。
今後もっとchefに触れていきたいと思います。以上です。