Chef(Knife)+Berkshelfを使ってサーバを自動構築する手順
以下の記事で、Vagrantを使った開発環境を作る手順はまとめたのですが、
本番環境側の構築方法をまとめていなかったので、
この記事で、chef+Berkshelfでサーバを自動構築する手順をまとめておきます。
MacOS上にVagrant+chef(knife)+Berkshelfで開発環境を作る手順
http://takemikami.com/archives/1367
図の使い回しですが、
Knife Solo/Chef Solo/Berkshelfの役割は以下の通りになります。
Berkshelf:
公開されているCookbookの取得
Knife Solo:
①各ノードへのChef Soloセットアップ
②各ノードへのCookbookの転送
③Chef Soloの起動
Chef Solo:
レシピの実行(セットアップ実行)
この記事では、管理サーバをMacOSX、
各ノードをVMwareFusion上のCentOS6.4として説明します。
※AWS EC2などでも基本的な流れは同じになるはずです。
環境構築は次の流れで行います。
- Knife Soloのインストール
- CentOS6.4のセットアップ
- Knifeが利用できるようにCentOSの環境を設定
- BerkshelfにあるChefレシピの適用
- 自前Chefレシピの作成と適用
Knife Soloのインストール
# この手順は冒頭にリンクした記事と全く同じ(実際コピペ)です
MacOSX(管理サーバ側)で、
以下のコマンドで、Knife Soloの作業用ディレクトリを作成します。
$ mkdir ~/chef-repo
作業用ディレクトリに以下ファイルを作成します。
Gemfile
source 'https://rubygems.org'
gem 'chef'
gem 'knife-solo'
gem 'berkshelf'
Berksfile
site :opscode
cookbook 'nginx'
以下のコマンドで、KnifeSoloとBerkshelfをインストールします。
$ bundle install --path=vendor/bundle
以下のコマンドで、knifeのディレクトリ構成を作成します。
$ bundle exec knife solo init .
ここまでで、以下のような構成になります。
+ Berksfile
+ Gemfile
+ Gemfile.lock
+ cookbooks
+ data_bags
+ nodes
+ roles
+ site-cookbooks
+ vendor
ひとまず、このディレクトリ構成をgitにcommitしておきます。
# .gitignoreに「/vendor/」を追加しておいた方がよいです。
$ git init
$ git add .
$ git commit -a -m "initial commit"
以下のコマンドで、opscodeのリポジトリからnginxと依存するcookbookを取得します。
$ bundle exec berks --path=cookbooks
CentOS6.4のセットアップ
CentOSのサイトから近くのミラーを選んでminimalのISOイメージをダウンロードします。
CentOS
http://www.centos.org
ファイル:CentOS-6.4-x86_64-minimal.iso
VMware Fusionを起動し、ファイル→新規から新規仮想マシンを作成、
ダウンロードしたISOイメージをマウントしてインストールを行います。
ネットワークは有効にしておきます。
Knifeが利用できるようにCentOSの環境を設定
VMwareFusionから先ほどインストールしたCentOSを起動します。
MacOSX(管理サーバ側)からCentOS(対象ノード側)にSSH接続できるように、
rootユーザで以下のコマンドを実行し、CentOS側にユーザと公開鍵を追加します。
$ useradd <MacOSXでknifeSoloをインストールしたユーザ名> -G wheel
$ su - <MacOSXでknifeSoloをインストールしたユーザ名>
$ mkdir .ssh
$ chmod 700 .ssh
$ touch .ssh/authorized_keys
$ chmod 600 .ssh/authorized_keys
「.ssh/authorized_keys」に、
MacOSXの公開鍵「.ssh/id_rsa.pub」の内容を追記します。
# SSH認証用の鍵を未作成の場合は、
# MacOSX(管理サーバ側)で、「ssh-keygen -t rsa」コマンドを実行します。
作成したユーザがパスワード無しでroot化できるように、
rootユーザで「visudo」を実行し、次の行をコメントインし有効にします。
%wheel ALL=(ALL) NOPASSWD: ALL
BerkshelfにあるChefレシピの適用
MacOSX(管理サーバ側)で、
以下のコマンドを実行し、対象ノードにchefをインストールします。
$ bundle exec knife solo prepare <対象のIPアドレス>
Bootstrapping Chef...
※途中省略※
Thank you for installing Chef!
Generating node config 'nodes/<対象のIPアドレス>.json'...
nodesの下に「<対象のIPアドレス>.json」というファイルができるので、
このファイルを以下のように編集します。
{"run_list":["recipe[nginx]"]}
次のコマンドを実行し、Chefレシピの適用を行います。
$ bundle exec knife solo cook <対象のIPアドレス>
Running Chef on <対象のIPアドレス>...
Checking Chef version...
Installing Berkshelf cookbooks to 'cookbooks'...
※途中省略※
Recipe: nginx::default
* service[nginx] action start
- start service service[nginx]
* service[nginx] action reload
- reload service service[nginx]
Chef Client finished, 22 resources updated
CentOS(対象ノード側)にログインして以下のコマンドを実行すると、
nginxがセットアップされている事が確認できます。
$ ps -ef | grep nginx
しかし、この時点では、
iptableの設定でポート80のアクセスがブロックされているため、
MacOSXからSafariで対象ノードのnginxにアクセスしようとしてもできないはずです。
次に、自前のレシピを作成しiptableの設定をコントロールしてみます。
自前Chefレシピの作成と適用
MacOSX(管理サーバ側)で、
以下のコマンドを実行し、mycookbookというcookbookを作成します。
$ bundle exec knife cookbook create mycookbook -o site-cookbooks/
** Creating cookbook mycookbook
** Creating README for cookbook: mycookbook
** Creating CHANGELOG for cookbook: mycookbook
** Creating metadata for cookbook: mycookbook
site-cookbooks/mycookbook配下に、以下のディレクトリができます。
+ attributes
+ definitions
+ files
+ libraries
+ providers
+ recipes
+ resources
+ templates
mycookbook配下にポート開放用のレシピを作成します。
iptablesの設定ファイルと適用スクリプトの2ファイルです。
site-cookbooks/mycookbook/files/default/iptables
# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
site-cookbooks/mycookbook/recipes/nginx-port.rb
cookbook_file "/etc/sysconfig/iptables" do
source "iptables"
owner "root"
group "root"
mode "600"
end
service "iptables" do
supports :status => true, :restart => true, :reload => true
action [ :enable, :restart ]
end
対象ノードのjsonファイルを変更して、作成したレシピが適用されるようにします。
nodes/<対象のIPアドレス>.json
{"run_list":["recipe[nginx]","recipe[mycookbook::nginx-port]"]}
次のコマンドを実行し、Chefレシピの適用を行います。
$ bundle exec knife solo cook <対象のIPアドレス>
Running Chef on <対象のIPアドレス>...
Checking Chef version...
Installing Berkshelf cookbooks to 'cookbooks'...
※途中省略※
Recipe: mycookbook::nginx-port
* cookbook_file[/etc/sysconfig/iptables] action create (up to date)
* service[iptables] action enable (up to date)
* service[iptables] action restart
- restart service service[iptables]
Chef Client finished, 2 resources updated
これで、MacOSXからSafariで対象ノードのnginxにアクセスすると
「Welcome to nginx on EPEL!」
というページが表示されているはずです。
このように、
『レシピの修正』と『「knife solo cook」でのレシピ適用』を繰り返してレシピ開発、
そして、完成したレシピを
本番サーバに適用という流れで、環境構築を行う事になると思います。
# さらに言えばアプリケーション開発者は、
# そのレシピをVagrant upした環境で開発とテストを実施ですね。。