「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はどれ? 〜おすすめ構成確認チャート」に非常に詳しく記載されているので、こちらをご一読することをお勧めする。
今回の検証では、管理サーバから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系でも動作には支障はないようである)
$ sudo yum update -y
$ sudo yum install -y gcc zlib-devel openssl-devel sqlite sqlite-devel rsync
$ 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]
$ sudo /usr/local/bin/gem i chef --no-ri --no-rdoc
コマンド入力後の各設定は基本的に何も入力せずに行う形で問題ない。
$ 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
$ sudo /usr/local/bin/gem i knife-solo --no-ri --no-rdoc
$ /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
$ ssh -i ~/.ssh/id_rsa.pem tissvv096 $ exit
コマンドを実行すると、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を作成、実行することが可能となる。
$ 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
作成した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" } }
knife soloコマンドでcookbookを実行することになるが、最後に“--noop”オプションを付けると実行せずに、構文チェックのみが行われる。エラーが表示されなければ構文的には問題がない。
$ cd ~/chef-repo $ knife solo cook -i ~/.ssh/id_rsa.pem tissvv096 --why-run
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
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.