Posted at
Quad incDay 16

Macにサーバと同じ環境を構築する 〜Chef編〜

More than 3 years have passed since last update.


1. はじめに

前回、Vagrant で Mac 上にサーバと同じ環境を構築しましたが、この記事ではシェルではなく Chef を使ってプロビジョンしてみたいと思います。プロビジョニングの前までは前回の記事を参照してください。

個人的にChefは覚えることが多く、とっつきにくいです。

詳しい話は使い方を少し覚えてからの方が理解しやすいと思うので、この記事では Vagrant のプロビジョニングを Chef で行うはじめの一歩になればと思っています。

前回までの状態


ディレクトリの構成

/sample

└ Vagrantfile


Vagrantfile

# -*- mode: ruby -*-

# vi: set ft=ruby :

Vagrant.configure(2) do |config|
config.vm.box = "rafacas/centos62-plain"

config.vm.network "forwarded_port", guest: 80, host: 8080

config.vm.network "private_network", ip: "192.168.33.10"

config.vm.synced_folder ".", "/var/www/html",
:create => true,
:owner => 'vagrant',
:group => 'vagrant',
:mount_options => ['dmode=777', 'fmode=666']

config.vm.provision "shell", inline: <<-SHELL
yum -y update

service iptables stop
chkconfig iptables off

# Apache
yum -y install httpd
service httpd start
chkconfig httpd on

# MySQL
yum -y install mysql mysql-server mysql-devel
service mysqld start
chkconfig mysqld on

# PHP
yum -y install php php-opcache php-devel php-mbstring php-mcrypt php-mysqlnd php-phpunit-PHPUnit php-pecl-xdebug php-pecl-xhprof

cp /etc/php.ini /etc/php.ini_org
sed -i -e "s|expose_php = On|expose_php = Off|" /etc/php.ini
sed -i -e "s|;date.timezone =|date.timezone = Asia/Tokyo|" /etc/php.ini
sed -i -e "s|display_errors = Off|display_errors = On|" /etc/php.ini
sed -i -e "s|;mbstring.language = Japanese|mbstring.language = Japanese|" /etc/php.ini

service httpd restart

# Git
yum install -y git

SHELL
end



2. ざっくり Chef について


Chef とは何か

Chef はサーバ構築を自動化するツールです。

Ruby で設定ファイルを記述し、コマンドを実行するとサーバが設定した状態でセットアップされます。

公式サイト

https://www.chef.io/chef/

Github

https://github.com/chef


Chef の種類

Chef には商用版とオープンソース版の2種類があります。今回使用するのは オープンソース版 の方です。


Chefの動作形態

動作形態には以下の2種類あります。


クライアント/サーバー型

Chef Server 上に設定ファイルを保持し、Chef Client に配布する形式です。

Chef Components

参照元:https://docs.chef.io/chef_overview.html


スタンドアロン型

Chef Server を必要とせずに動作する Chef Client です。この記事ではスタンドアロン型を使用します。

以前は Chef Solo という形で提供されていましたが、現在(Chef Client 11.8 以降)は Chef Zero と呼ばれる Chef Client のローカルモードを使用することが推奨されています。

ただ現状、日本語の情報は圧倒的に Chef Solo が多いので、最初に使うなら Chef Solo の方がいろいろと調べやすいと思います。この記事でも Chef Solo を使用します。


Chef の用語

ひとまず以下の単語を覚えてください。

単語
説明

recipe
レシピ。サーバ設定の手順が記述されたファイル。
Apacheのレシピ

cookbook
クックブック。レシピと必要なデータをまとめたもの。WEB上で公開されている コミュニティクックブック と独自に作成する サイトクックブック がある
Apacheのレシピとコピーするhttpd.conf

kitchen
キッチン。Chefのリポジトリのこと。複数のクックブックとChefの実行に必要なファイル群
ApacheのクックブックとMySQLのクックブック

knife
Chefリポジトリを操作するためのコマンド。多くのサブコマンドを持っています

knife-solo
knifeにサブコマンドを追加するGem。ローカルから仮想サーバ上の Chef Solo を操作可能になる


3. Chef をインストールする


Chef のインストール

インストールする方法がいくつかありますが、インストール方法によってインストールディレクトリが変わったり、Vagrant のプラグインが動かなかったりして苦労します。

現在、Chef が公式に推奨しているインストール方法は Chef Development Kit を使ったインストールです。

が、私の環境では Gem でインストールしているため、その前提で話を進めます。(ChefDK でインストールし直したいですが、締め切りの関係で断念しました。。。)


Chefのインストール

$ gem install chef


Chef をインストールすると、Chef Solo もインストールされます。

バージョンを確認してみましょう。


バージョン確認

$ chef-solo -v

Chef: 12.5.1


knife-soloのインストール

次に knife-solo をインストールします。


knife-soloのインストール

$ gem install knife-solo



Berkshelfについて

Chef で検索をすると多くの記事で cookbook の管理に Berkshelf という依存管理ツールを使用していると思います。

便利なツールを入れれば入れるほど、覚えることと障害ポイントが多くなって最初はつらいので、この記事では使用しません。


vagrant-omnibus のインストール

最後に仮想サーバに Chef をインストールするための Vagrant プラグインをインストールします。


vagrant-omnibusのインストール

$ vagrant plugin install vagrant-omnibus



Vagrantfile を変更

Vagrantfile に以下の1行を追記し、vagrant-omnibus プラグインを有効にします。

これで vagrant up すると、仮想サーバに Chef がインストールされているかを確認し、インストールされていない場合は最新版の Chef をインストールします。


Vagrantfile

config.omnibus.chef_version = :latest


また、プロビジョニングの設定を shell から chef_solo に書き換えます。


Vagrantfile

  config.vm.provision "shell", inline: <<-SHELL


SHELL

変更

config.vm.provision "chef_solo" do |chef|
# まだ中身は空でOKです
end



4. 設定する

さて、ここからが本番です。


Chef リポジトリを作成する

sample ディレクトリに Chef のリポジトリを追加します。

先ほどインストールした knife solo を使います。


Chefリポジトリの作成

$ cd sample

$ knife solo init .

コマンドを実行するとファイルが作成され、以下の状態になります。

$ tree -p

.
|-- [-rw-r--r--] Vagrantfile
|-- [drwxr-xr-x] cookbooks
|-- [drwxr-xr-x] data_bags
|-- [drwxr-xr-x] environments
|-- [drwxr-xr-x] nodes
|-- [drwxr-xr-x] roles
`-- [drwxr-xr-x] site-cookbooks

6 directories, 2 files

追加されたディレクトリの説明

名前
説明

cookbooks
WEBで公開されているコミュニティクックブックを配置する

data_bags
今回は使用しません。クックブックで利用するデータを格納する

environments
今回は使用しません。開発、ステージング、本番等、環境ごとに設定する値を定義するファイルを置きます

nodes
今回は使用しません。ホスト名等の node ごとに設定する値を定義するファイルを置きます

roles
今回は使用しません。WebサーバやDBサーバ等、サーバの役割ごとに設定する値を定義するファイルを置きます

site-cookbooks
自作のクックブックを配置する


コミュニティクックブックを入手する

Web上に公開されているコミュニティクックブックを利用します。

こちらのサイトで検索するか

https://supermarket.chef.io/

以下のコマンドで、どのような cookbook があるか調べることが可能です。

# 一覧

knife cookbook site list

# 名前を指定して検索
knife cookbook site search apache2

# クックブックの情報を見る
knife cookbook site show apache2


apache2

では、apache2 の cookbook を入手してみましょう。


apache2クックブックの入手

$ knife cookbook site download apache2

$ knife cookbook site install apache2

インストール時に初回は下記のようなエラーになるかもしれません。

$ knife cookbook site install apache2

Installing apache2 to sample/cookbooks
ERROR: The cookbook repo sample/cookbooks is not a git repository.
Use `git init` to initialize a git repo

エラーになった場合は sample ディレクトリに git リポジトリを作成します。

$ git init

$ git add -A
$ git commit -m

その後、もう一度インストールコマンドを実行してください。

すると cookbooks ディレクトリ配下にファイルが展開されます。


sample/cookbooks/apache2

$ tree -L 1 -p

.
|-- [-rw-r--r--] CHANGELOG.md
|-- [-rw-r--r--] README.md
|-- [drwxr-xr-x] attributes
|-- [drwxr-xr-x] definitions
|-- [drwxr-xr-x] files
|-- [-rw-r--r--] metadata.json
|-- [drwxr-xr-x] recipes
`-- [drwxr-xr-x] templates

上記の recipes ディレクトリの中にレシピファイルが格納されています。


php

同様に PHP クックブックも入手します。


phpクックブックの入手

$ knife cookbook site download php

$ knife cookbook site install php


git


gitクックブックの入手

$ knife cookbook site download git

$ knife cookbook site install git


Vagratnfile を変更する

下記のようにクックブックのパス設定と、使用するクックブックを追記します。


Vagrantfile

  config.vm.provision "chef_solo" do |chef|

chef.cookbooks_path = ["cookbooks"]

chef.add_recipe 'apache2'
chef.add_recipe 'php'
chef.add_recipe 'git'

end


変更後の Vagrantfile は以下のような状態になっているはずです。


Vagrantfile

# -*- mode: ruby -*-

# vi: set ft=ruby :

Vagrant.configure(2) do |config|
config.vm.box = "rafacas/centos62-plain"

config.vm.network "forwarded_port", guest: 80, host: 8080

config.vm.network "private_network", ip: "192.168.33.10"

config.vm.synced_folder ".", "/var/www/html",
:create => true,
:owner => 'vagrant',
:group => 'vagrant',
:mount_options => ['dmode=777', 'fmode=666']

config.omnibus.chef_version = :latest

config.vm.provision "chef_solo" do |chef|
chef.cookbooks_path = ["cookbooks"]

chef.add_recipe 'apache2'
chef.add_recipe 'php'
chef.add_recipe 'git'

end
end



5. Vagrant の起動

ファイルを書き換えたら Vagrant を起動しましょう。

以下の流れで、仮想サーバが構築されます。

1. Vagrant が仮想サーバを起動

2. ディレクトリが同期され cookbook が仮想サーバに転送される

3. vagrant-omnibus プラグインによって chef-solo が仮想サーバにインストールされる

4. 仮想サーバ上で cookbook の設定にもとづき chef-solo がアプリケーションをインストールする

前回 sample ディレクトリで起動した仮想サーバがある場合は、起動前に削除してください。


仮想サーバを削除

$ vagrant destroy


Vagrant を起動します。


仮想サーバを起動

$ vagrant up



==> default: Thank you for installing Chef!
==> default: Running provisioner: chef_solo...
==> default: Detected Chef (latest) is already installed

起動が完了したら、仮想サーバにログインして確認してみましょう。


インストールしたソフトのバージョン確認

$ vagrant ssh


$ chef-solo -v
Chef: 12.5.1

$ httpd -v
Server version: Apache/2.2.15 (Unix)
Server built: Dec 15 2015 15:50:14

$ php -v
PHP 5.3.3 (cli) (built: Jul 9 2015 17:39:00)
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies

$ git --version
git version 1.7.1


これが Chef の一番かんたんな部分の動きになります。

ここまでやってみると、「あれ? yum update はどうやるの?」とか「apache のバージョンは指定できないの?」とか「既存の httpd.conf を使えないか」とか「MySQL をインストールして、ユーザーとデータベースまで自動で作成したい」とか、いろいろやりたいことが出てくると思います。

全部できます。 やりたいことに合わせて、調べてみてください。