連載
» 2016年06月23日 05時00分 公開

実際に検証済み!OSS徹底比較(3)サーバ構築自動化【前編】:OSSのサーバ構築自動化ツール、4製品徹底検証 2016年版 (3/9)

[森元敏雄,TIS]

Chefのプロフィール

 「Chef」はChef Softwareが開発した製品で、2009年1月に最初のStable版がリリースされている。ライセンスはApache License Version 2.0で、現在の最新バージョンは2016年4月9日にリリースされたVer 12.9となっている。

 Chefにはサーバ内部で構築を行う「Chef-solo」、リモートからnode上の「Chef-solo」を遠隔操作して構築を行う「Knife-solo」、大規模環境で集中管理を行うための「Chef-server」が提供されている。各製品の機能概要と使い分けについては、クリエーションラインの技術ブログ「あなたに合ったChefはどれ? 〜おすすめ構成確認チャート」に非常に詳しく記載されているので、こちらをご一読することをお勧めする。

Chefのインストール

 今回の検証では、管理サーバからnodeに対して遠隔でのインストールを実施するため、Knife-soloを利用している。最新のChefをインストールするためには、Ruby 2.1以上が必要となる。CentOS 7.2の標準のリポジトリからインストールする場合、Ver 2.0.0でありインストールが行えないため、Rubyをソースからインストールすることになる。2016年4月現在、Rubyの最新バージョンは2.3.1だが、このバージョンを利用すると、インストール時、実行時に“`initialize': Object#timeout is deprecated, use Timeout.timeout instead.”のエラーメッセージが出力されてわずらわしいので、2.2系の最終版である2.2.4を選択している。(エラーが出力されるが、2.3系でも動作には支障はないようである)

1.インストール済みパッケージの更新

$ sudo yum update -y

2.追加パッケージのインストール

$ sudo yum install -y gcc zlib-devel openssl-devel sqlite sqlite-devel rsync

3.Rubyのインストール

$ sudo su root -c "curl  http://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.4.tar.gz | tar zx -C /usr/local/src"
$ sudo chown -R root:root /usr/local/src/ruby-2.2.4
$ cd /usr/local/src/ruby-2.2.4
$ sudo ./configure
$ sudo make
$ sudo make install
$ which ruby
/usr/local/bin/ruby
$ /usr/local/bin/ruby --version
ruby 2.2.4p230 (2015-12-16 revision 53155) [x86_64-linux]

4.Chefのインストール

$ sudo /usr/local/bin/gem i chef --no-ri --no-rdoc

5.Knifeの初期設定

 コマンド入力後の各設定は基本的に何も入力せずに行う形で問題ない。

$ cd ~
$ /usr/local/bin/knife configure
WARNING: No knife configuration file found
Where should I put the config file? [/home/maintain/.chef/knife.rb]
Please enter the chef server URL: [https://tissvv097:443]
Please enter an existing username or clientname for the API: [maintain]
Please enter the validation clientname: [chef-validator]
Please enter the location of the validation key: [/etc/chef-server/chef-validator.pem]
Please enter the path to a chef repository (or leave blank):
*****
You must place your client key in:
  /home/maintain/.chef/maintain.pem
Before running commands with Knife
*****
You must place your validation key in:
  /etc/chef-server/chef-validator.pem
Before generating instance data with Knife
*****
Configuration file written to /home/maintain/.chef/knife.rb

6.Knife-soloのインストール

$ sudo /usr/local/bin/gem i knife-solo --no-ri --no-rdoc

7.chef-repoフォルダの作成

$ /usr/local/bin/knife solo init chef-repo
$ ls -d1 ./chef-repo/*
./chef-repo/cookbooks
./chef-repo/data_bags
./chef-repo/environments
./chef-repo/nodes
./chef-repo/roles
./chef-repo/site-cookbooks

8.nodeに鍵認証でSSH接続可能であることを確認しておく

$ ssh -i ~/.ssh/id_rsa.pem tissvv096
$ exit

9.nodeにChef-soloをインストール

 コマンドを実行すると、node側にchef-soloがインストールされ、ローカルの./chef-repo/node以下にnodeの設定を登録するjsonファイルが作成される。

$ cd ~/chef-repo
$ knife solo prepare -i ~/.ssh/id_rsa.pem tissvv096
Bootstrapping Chef...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 19602  100 19602    0     0  20929      0 --:--:-- --:--:-- --:--:-- 20919
el 7 x86_64
Getting information for chef stable 12.9.38 for el...
downloading https://omnitruck-direct.chef.io/stable/chef/metadata?v=12.9.38&p=el&pv=7&m=x86_64
  to file /tmp/install.sh.4421/metadata.txt
trying curl...
sha1    5907edce1a3b0f7bd42359fe64960da8833385e9
sha256  1c3e680f106ab6829c3713307e447116f7bb3f2d9c30fd3943638b01d6246fe2
url     https://packages.chef.io/stable/el/7/chef-12.9.38-1.el7.x86_64.rpm
version 12.9.38
downloaded metadata file looks valid...
downloading https://packages.chef.io/stable/el/7/chef-12.9.38-1.el7.x86_64.rpm
  to file /tmp/install.sh.4421/chef-12.9.38-1.el7.x86_64.rpm
trying curl...
Comparing checksum with sha256sum...
Installing chef 12.9.38
installing with rpm...
警告: /tmp/install.sh.4421/chef-12.9.38-1.el7.x86_64.rpm: ヘッダー V4 DSA/SHA1 Signature、鍵 ID 83ef826a: NOKEY
準備しています...              ################################# [100%]
更新中 / インストール中...
   1:chef-12.9.38-1.el7               ################################# [100%]
Thank you for installing Chef!
Generating node config 'nodes/tissvv096.json'...

 これでマネージャー、nodeサーバともにインストールが完了となり、./chef-repo以下でサーバ構築と設定を行うcookbockを作成、実行することが可能となる。

WordPressインストール用のcookbookの作成

1.cookbookのテンプレートとなるフォルダとファイルを作成

$ cd ~/chef-repo
$ knife cookbook create wordpress_sample -o site-cookbooks
** Creating cookbook wordpress_sample in /root/chef-repo/site-cookbooks
** Creating README for cookbook: wordpress_sample
** Creating CHANGELOG for cookbook: wordpress_sample
** Creating metadata for cookbook: wordpress_sample

 上記のコマンドを実行すると、site-cookbooksフォルダ内にcookbookを作成するために必要となるフォルダやファイルが作成される。

$ ls -1d ./ site-cookbooks/wordpress_sample/*
site-cookbooks/wordpress_sample/CHANGELOG.md
site-cookbooks/wordpress_sample/README.md
site-cookbooks/wordpress_sample/attributes
site-cookbooks/wordpress_sample/definitions
site-cookbooks/wordpress_sample/files
site-cookbooks/wordpress_sample/libraries
site-cookbooks/wordpress_sample/metadata.rb
site-cookbooks/wordpress_sample/providers
site-cookbooks/wordpress_sample/recipes
site-cookbooks/wordpress_sample/resources
site-cookbooks/wordpress_sample/templates

2.cookbookを作成

 作成したcookbookは以下となる。各処理のTIPSは後ほど機能ごとに説明する。

(1)cookbookとして作成するファイルおよびフォルダの構成

$ tree chef-repo/
chef-repo/
├── .chef
│   └── knife.rb
├── nodes
│   └── tissvv096.json
└── site-cookbooks
    └── wordpress_sample
        ├── attributes
        │   └── default.rb
        ├── recipes
        │   ├── default.rb
        └── templates

(2)recipe本体

 実際にインストールや設定を行う処理を記述している。前述のシェルスクリプトと同一の処理を行う部分はコメントを一致させるようにしている。

$ vi ~/chef-repo/site-cookbooks/wordpress_sample/recipes/default.rb
#
# Cookbook Name:: wordpress_sample
# Parameter settings
hostname         = node['hostinfo']['hostname']
mysql_root_pass  = node['mariadb']['mysql_root_pass']
wordpress_latest = node['wordpress']['wordpress_latest']
wp_os_user       = node['wordpress']['wp_os_user']
wp_os_group      = node['wordpress']['wp_os_group']
wp_db_name       = node['wordpress']['wp_db_name']
wp_db_user       = node['wordpress']['wp_db_user']
wp_db_pass       = node['wordpress']['wp_db_pass']
wp_uniqe_phrse   = node['wordpress']['wp_uniqe_phrse']
# update packages
execute 'yum-update' do
  user 'root'
  command 'yum -y update'
  action :run
end
# install packages
yum_package [ 'mariadb-server', 'httpd', 'php', 'php-mysql' ] do 
  action :install
end
# start/enable mariadb
service 'mariadb' do
  supports :status => true, :restart => true, :reload => true
  action [:start, :enable]
end
# set mariadb root password + restart mariadb
execute 'set mariadb root password' do
  command <<-EOC
    /usr/bin/rm -f /root/.my.cnf
    mysql -u root -e "update mysql.user set password=password('#{mysql_root_pass}') where user = 'root'"
    systemctl restart mariadb
  EOC
  onlyvariables({
    :mysql_root_pass => mysql_root_pass
  })
  not_if { File.exists?('/root/.my.cnf') }
end
# mariadb logrotate setting
execute 'mariawp_db_logrotate' do
  command <<-EOC
    sed -i.bak -e '23,$ s/^#//' /etc/logrotate.d/mariadb
  EOC
  not_if { File.exists?('/etc/logrotate.d/mariadb.bak') }
end
# create wordpres db/user
bash 'create wordpres db/user' do
  exists = <<-EOH
    mysql -u root -p#{mysql_root_pass} -e 'show databases' | grep #{wp_db_name}
  EOH
  code <<-EOC
    mysql -vvv -u root -p#{mysql_root_pass} -e "create user '#{wp_db_user}'@'localhost' identified by '#{wp_db_pass}'"
    mysql -vvv -u root -p#{mysql_root_pass} -e "create database #{wp_db_name}"
    mysql -vvv -u root -p#{mysql_root_pass} -e "grant all privileges on #{wp_db_name}.* to '#{wp_db_user}'@'localhost'"
    mysql -vvv -u root -p#{mysql_root_pass} -e "flush privileges"
  EOC
  not_if exists
end
# install wordpress
execute 'install wordpress' do
  command <<-EOC
    curl #{wordpress_latest} | tar zx -C /var/www
  EOC
  not_if { File.exists?('/var/www/wordpress/index.php') }
end
# create wordpress config
bash 'create wordpress config' do
  code <<-EOC
    sed -e "s/\\(define.*'\\)database_name_here\\('.*\\)/\\1#{wp_db_name}\\2/" \
        -e "s/\\(define.*'\\)username_here\\('.*\\)/\\1#{wp_db_user}\\2/" \
        -e "s/\\(define.*'\\)password_here\\('.*\\)/\\1#{wp_db_pass}\\2/" \
        -e "s/\\(define.*'\\)put your unique phrase here\\('.*\\)/\\1#{wp_unique_phrase}\\2/" \
        /var/www/wordpress/wp-config-sample.php > /var/www/wordpress/wp-config.php
  EOC
  not_if { File.exists?('/var/www/wordpress/wp-config.php') }
end
# chown wordpress files
execute 'chown wordpress files' do
  command <<-EOC
    chown -R #{wp_os_user}:#{wp_os_group} /var/www/wordpress
  EOC
  not_if "test `find /var/www/wordpress -not -user #{wp_os_user} -or -not -group #{wp_os_group} | wc -l` == 0"
end
# create wordpres httpd config
template '/etc/httpd/conf.d/wordpress.conf' do
  owner 'root'
  group 'root'
  source 'wordpress.conf.erb'
  variables({
    :hostname => hostname
  })
  not_if { File.exists?('/etc/httpd/conf.d/wordpress.conf') }
end
# modify httpd config
execute 'httpd.conf' do
  command <<-EOC
    sed -i.bak -e 's/^#ServerName.*/ServerName #{hostname}/' /etc/httpd/conf/httpd.conf
  EOC
  not_if { File.exists?('/etc/httpd/conf/httpd.conf.bak') }
end
# start/enable httpd
service 'httpd' do
  supports :status => true, :restart => true, :reload => true
  action [:start, :enable]
end
# open httpd port in firewall
execute 'open httpd port in firewall' do
  command <<-EOC
    firewall-cmd --add-service=http --zone=public --permanent
    firewall-cmd --reload
  EOC
  only_if "test `firewall-cmd --list-service --zone=public | grep -c http` == 0"
end

(3)変数のdefault値の定義ファイル

 recipe内で使用する変数のdefault値を定義する。

$ vi ~/chef-repo/site-cookbooks/wordpress_sample/attributes/default.rb
# Paramaters default
default['hostinfo']['hostname']          = "localhost"
default['mariadb']['mysql_root_pass']    = "password"
default['wordpress']['wordpress_latest'] = "https://wordpress.org/latest.tar.gz"
default['wordpress']['wp_os_user']       = "root"
default['wordpress']['wp_os_group']      = "root"
default['wordpress']['wp_db_name']       = "wordpress"
default['wordpress']['wp_db_user']       = "wordpress"
default['wordpress']['wp_db_pass']       = "password"
default['wordpress']['wp_unique_phrase']  = "bMvc7W2eLuhKFewafVyirWJaXDhbSf"

(4)/etc/httpd/conf.d/wordpress.confのtemplateファイル

$ vi ~/chef-repo/site-cookbooks/wordpress_sample/templates/wordpress.conf.erb
<VirtualHost *:80>
  ServerName <%= @hostname %>;
  DocumentRoot /var/www/wordpress
  <Directory "/var/www/wordpress">
    AllowOverride All
    Options -Indexes
  </Directory>
  <Files wp-config.php>
    order allow,deny
    deny from all
  </Files>
</VirtualHost>

(5)/root/.my.cnfのtemplateファイル

$ vi ~/chef-repo/site-cookbooks/wordpress_sample/templates/my.cnf.erb
[client]
user = root
password = "<%= @mysql_root_pass %>"
[mysqladmin]
user = root
password = "<%= @mysql_root_pass %>"

(6)nodeの設定に使用するrecipeとパラメータの定義ファイル

$ vi ~/chef-repo/nodes/tissvv096.json
{
  "run_list": [
    "wordpress_sample"
  ],
  "mariadb" : {
    "mysql_root_pass" : "FM11AD2+"
  },
  "wordpress" : {
    "wordpress_latest" : "https://ja.wordpress.org/latest-ja.tar.gz",
    "wp_os_user"       : "root",
    "wp_os_group"      : "root",
    "wp_db_name"       : "WordPress",
    "wp_db_user"       : "wp_admin",
    "wp_db_pass"       : "HB-F1XDJ",
    "wp_unique_phrase"  : "FX702PFX801PPB100FX860PPB700PB500PB750PAI1000"
  },
  "hostinfo" : {
    "hostname" : "tissvv096"
  },
  "automatic": {
    "ipaddress": "10.255.202.96"
  }
}

3.cookbook実行前の構文の確認

 knife soloコマンドでcookbookを実行することになるが、最後に“--noop”オプションを付けると実行せずに、構文チェックのみが行われる。エラーが表示されなければ構文的には問題がない。

$ cd ~/chef-repo
$ knife solo cook -i ~/.ssh/id_rsa.pem tissvv096 --why-run

4.WordPressサーバ構築のcookbookを実行

 knifeコマンドは実行時のディレクトリ直下の.chef/knife.rbを参照して処理を実行する。chef-repoフォルダ以外で実行すると、cookbookの参照が行えず、処理が正常に行えない状態となる。

 コマンドを実行すると、node/[hostname].jsonに指定されたcookbookが実行される。

$ cd ~/chef-repo
$ knife solo cook -i ~/.ssh/id_rsa.pem tissvv096

 コマンドを実行すると、以下のログが出力され、nodeサーバの設定が行われる。

Running Chef on tissvv096...
Checking Chef version...
Uploading the kitchen...
Generating solo config...
Running Chef: sudo chef-solo -c ~/chef-solo/solo.rb -j ~/chef-solo/dna.json
Starting Chef Client, version 12.9.38
Installing Cookbook Gems:
Compiling Cookbooks...
Converging 14 resources
Recipe: wordpress_sample::default
  * execute[yum-update] action run
    - execute yum -y update
  * yum_package[mariadb-server, httpd, php, php-mysql] action install
    - install version 5.5.47-1.el7_2 of package mariadb-server
    - install version 2.4.6-40.el7.centos of package httpd
    - install version 5.4.16-36.el7_1 of package php
    - install version 5.4.16-36.el7_1 of package php-mysql
  * service[mariadb] action start
    - start service service[mariadb]
  * service[mariadb] action enable
    - enable service service[mariadb]
  * execute[set mariadb root password] action run
    - execute     /usr/bin/rm -f /root/.my.cnf
        mysql -u root -e "update mysql.user set password=password('FM11AD2+') where user = 'root'"
        systemctl restart mariadb
  
  * template[/root/.my.cnf] action create
    - create new file /root/.my.cnf
    - update content in file /root/.my.cnf from none to 8b2970
    --- /root/.my.cnf	2016-05-07 13:30:05.447532208 +0900
    +++ /root/.chef-.my.cnf20160507-2763-pjob7n	2016-05-07 13:30:05.447532208 +0900
    @@ -1 +1,8 @@
    +[client]
    +user = root
    +password = "FM11AD2+"
    +
    +[mysqladmin]
    +user = root
    +password = "FM11AD2+"
    - change mode from '' to '0600'
    - change owner from '' to 'root'
    - change group from '' to 'root'
  * execute[mariawp_db_logrotate] action run
    - execute     sed -i.bak -e '23,$ s/^#//' /etc/logrotate.d/mariadb
  
  * bash[create wordpres db/user] action run
    - execute "bash"  "/tmp/chef-script20160507-2763-1df3arv"
  * execute[install wordpress] action run
    - execute     curl https://ja.wordpress.org/latest-ja.tar.gz | tar zx -C /var/www
  
  * bash[create wordpress config] action run
    - execute "bash"  "/tmp/chef-script20160507-2763-kw4xvg"
  * execute[chown wordpress files] action run
    - execute     chown -R root:root /var/www/wordpress
  
  * template[/etc/httpd/conf.d/wordpress.conf] action create
    - create new file /etc/httpd/conf.d/wordpress.conf
    - update content in file /etc/httpd/conf.d/wordpress.conf from none to 127163
    --- /etc/httpd/conf.d/wordpress.conf	2016-05-07 13:30:08.358562342 +0900
    +++ /etc/httpd/conf.d/.chef-wordpress.conf20160507-2763-1p7qqgk	2016-05-07 13:30:08.358562342 +0900
    @@ -1 +1,14 @@
    +<VirtualHost *:80>
    +  ServerName tissvv096;
    +  DocumentRoot /var/www/wordpress
    +  <Directory "/var/www/wordpress">
    +    AllowOverride All
    +    Options -Indexes
    +  </Directory>
    +
    +  <Files wp-config.php>
    +    order allow,deny
    +    deny from all
    +  </Files>
    +</VirtualHost>
    - change owner from '' to 'root'
    - change group from '' to 'root'
  * execute[httpd.conf] action run
    - execute     sed -i.bak -e 's/^#ServerName.*/ServerName tissvv096/' /etc/httpd/conf/httpd.conf
  
  * service[httpd] action start
    - start service service[httpd]
  * service[httpd] action enable
    - enable service service[httpd]
  * execute[open httpd port in firewall] action run
    - execute     firewall-cmd --add-service=http --zone=public --permanent
        firewall-cmd --reload
  
Running handlers:
Running handlers complete
Chef Client finished, 16/16 resources updated in 26 seconds

5.ブラウザでWordPressの初期設定画面の起動を確認する

ALT 図3 WordPressの初期設定画面の起動を確認《クリックで拡大》

6.コマンドを再実行した場合、設定済の処理がスキップされる

Running Chef on tissvv096...
Checking Chef version...
Uploading the kitchen...
Generating solo config...
Running Chef: sudo chef-solo -c ~/chef-solo/solo.rb -j ~/chef-solo/dna.json
Starting Chef Client, version 12.9.38
Installing Cookbook Gems:
Compiling Cookbooks...
Converging 14 resources
Recipe: wordpress_sample::default
  * execute[yum-update] action run
    - execute yum -y update
  * yum_package[mariadb-server, httpd, php, php-mysql] action install (up to date)
  * service[mariadb] action start (up to date)
  * service[mariadb] action enable (up to date)
  * execute[set mariadb root password] action run (skipped due to only_if)
  * template[/root/.my.cnf] action create (skipped due to not_if)
  * execute[mariawp_db_logrotate] action run (skipped due to not_if)
  * bash[create wordpres db/user] action run (skipped due to not_if)
  * execute[install wordpress] action run (skipped due to not_if)
  * bash[create wordpress config] action run (skipped due to not_if)
  * execute[chown wordpress files] action run (skipped due to not_if)
  * template[/etc/httpd/conf.d/wordpress.conf] action create (skipped due to not_if)
  * execute[httpd.conf] action run (skipped due to not_if)
  * service[httpd] action start (up to date)
  * service[httpd] action enable (up to date)
  * execute[open httpd port in firewall] action run (skipped due to only_if)
Running handlers:
Running handlers complete
Chef Client finished, 1/16 resources updated in 07 seconds

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。