みんなの「作ってみた」

Virtualbox + Vagrant + AnsibleでWeb, DBサーバ環境をつくる

2017/01/31

seihmd
seihmd

本エントリの目的

ローカル環境で開発をしているとデータベースやその他諸々のサービスをlocalhostで参照できて設定が楽というメリットはありますが、WebサーバとDBサーバの分かれた本番環境と構成が異なるのが気になります。

せめて本番にデプロイする前にステージング環境で確認をしておきたいところですが、個人開発ではお金を節約したいのでわざわざ本番サーバと同じVPSやAWSは使いたくありません。そこでVirtualboxの仮想マシンにVagrantとAnsibleを使って環境を構築することにします。

  • Virtualbox、Vagrant、Ansibleのインストール方法、使い方などは説明しません。
  • 使用したファイルはGithubに上げています。

https://github.com/seihmd/vagrant-multiserver-example

環境

  • ホストマシン: MacOSX El Capitan
  • Vagrant v1.9.1
  • Ansible v2.0.2.0
  • Virtualbox v5.0.24 r108355

仮想マシン構成・要件

仮想マシン構成

  • Webサーバ
    • DBサーバにアクセス可能
  • DBサーバ
    • mysqlを稼働
    • Webサーバからアクセス可能

上記2サーバを"ゲスト"と呼ぶのに対し、仮想環境を構築するマシンを"ホスト"と呼びます。

要件

  • ホストはゲストにSSH接続可能
    • DBサーバのDBにもアクセス可能
  • ゲストWebサーバのポート80はポートフォワーディングでホストから接続可能
    • 要はWebサーバで動かしているアプリをホストのブラウザから見られるようにする
  • サーバ構築はAnsibleで行う

ディレクトリ構成

  • :page_facing_up: Vagrantfile
  • :file_folder: groupvars
    • :page_facing_up: all.yml
  • :file_folder: roles
    • :file_folder: mysql
  • :page_facing_up: staging   // inventoryファイル
  • :page_facing_up: site.yml  // vagrantから実行するplaybook
  • :page_facing_up: dbservers.yml  // DBサーバ用playbook

Vagrantfileはディレクトリでvagrant initコマンド実行で作成されるものです
その他はansibleで使用するファイルですが、このあたりの構成は人によって異なると思います。

今回ansibleはDBサーバにmysqlを立てるためにしか使わないのでだいぶ簡略化しています。
groupvars/all.ymlにはmysqlのユーザ作成に使用するための値を設定しています。
roles/mysqlはこちらのリポジトリから拝借して自分用に適当に改変したものです。
ともかく、ansibleファイルの構成はinventoryファイルを本番環境用のものに差し替えればそのまま同じように実行できることが重要だと思います。

VagrantFileの記述

Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

    VAGRANT_VM_PROVIDER = "virtualbox"
    machineNames = ["example.com.web", "example.com.db"]
    config.vm.box = "centos/7"

    N = 1

    (0..N).each do |index|
        config.vm.define machineNames[index] do |machine|

            # 仮想マシンのネットワーク設定
            machine.vm.hostname = machineNames[index]
            machine.vm.network "forwarded_port", guest: 80, host: 10020 + index, guest_ip: "192.168.33.#{10+index}"
            machine.vm.network "private_network", ip: "192.168.33.#{10+index}",  virtualbox__intnet: "example.com"
            machine.vm.network "private_network", ip: "192.168.33.#{10+index}"

            # ansibleでのprovisioning. ループの最後で実行される
            if index == N
                machine.vm.provision :ansible do |ansible|
                    ansible.limit = "all"
                    ansible.playbook = "site.yml"
                    ansible.inventory_path = "staging"
                end
            end
        end
    end
end

Vagrantのドキュメントを参考にループを回してWeb, DBサーバそれぞれに異なるIPアドレスを割り当てています。

仮想マシンのネットワーク設定の部分ではゲストで実行するアプリをホスト側で確認するためのforwarded_port、仮想マシン間で通信するためのprivate_networkを設定しています。

Vagrant up してみる

ansible以外の仮想マシン構築タスクがうまく動作確認するためにとりあえず vagrant up してみましょう。Vagrantとansibleを使うと途中でエラーになっても再実行が簡単なので楽です。

Vagrantによる仮想マシン構築はうまく行ったのでansibleのタスクだけ実行したいという場合は vagrant provision コマンドが使えます。

なんか変になったので仮想マシンごと削除したい場合は vagrant destroy コマンドです。一回のコマンドで各サーバについて削除するか聞かれます。

    example.com.db: Are you sure you want to destroy the 'example.com.db' VM? [y/N] y
==> example.com.db: Forcing shutdown of VM...
==> example.com.db: Destroying VM and associated drives...
    example.com.web: Are you sure you want to destroy the 'example.com.web' VM? [y/N] y
==> example.com.web: Forcing shutdown of VM...
==> example.com.web: Destroying VM and associated drives...

vagrant destroy example.com.web のように指定することも可能です。

ホストでWebアプリの稼働を確認する

疎通確認のためワンライナーでサーバを起動します。
ポート80を指定しているのはVagrantfileでforwarded_portにしているからです。

# Webサーバで実行
sudo python -m SimpleHTTPServer 80

ホストのブラウザで http://localhost:10020 にアクセスしてみます。

Screen Shot 0029-01-29 at 19.32.26.png

Webサーバ側でもアクセスが来ているのがわかります。
Screen Shot 0029-01-29 at 19.37.08.png

ホストからDBに接続する

Sequel ProからDBに接続するときの設定です。
SSH Keyには.vagrantフォルダ配下にあるキーを指定します。
.vagrant/machines/example.com.db/virtualbox/private_key

Screen Shot 0029-01-29 at 14.06.08.png

ゲストサーバ間でアクセスする

Vagrantfileのprivate_networkに指定したipアドレスでアクセスすることができます。
とりあえず簡易的にpingが通るかどうかで確認してみます。

Screen Shot 0029-01-29 at 21.04.58.png

トラブルシューティング

本エントリの元にした個人プロジェクト用環境をセットアップしたときはなかったのですが、記事を執筆するために手順を再現しているとうまくいかないことがありました。詳しくないので原因ははっきりしていません。

1. ホストのブラウザから localhost:10020 につながらない

まずVirtualboxのマシン一覧からWebサーバ → setting → network → Adaptor3 を確認します。
Screen Shot 0029-01-29 at 21.13.50.png

ここで指定されているNetwork Adaptor(ここではvboxnet4)をVirtualboxの環境設定で確認します。
Screen Shot 0029-01-29 at 21.16.10.png

上の画像は問題が解決したあとの設定です。解決する前はvboxnet4のIPv4 Addressが別の値になっていました(記録し忘れました)。

2. ゲストサーバ間でpingが通らない

原因ははっきりしませんが再起動をかけると直ったりします。