Help us understand the problem. What is going on with this article?

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

More than 5 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 をインストールして、ユーザーとデータベースまで自動で作成したい」とか、いろいろやりたいことが出てくると思います。
全部できます。 やりたいことに合わせて、調べてみてください。

quad
デザインとテクノロジーで新しい価値を作り出す。
https://quad.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away