わすれっぽいきみえ

みらいのじぶんにやさしくしてやる

vagrantの複数インスタンスをたてて遊んでみる

Vagrant Cloudを触るときに参考にした

Vagrant CloudのVagrant Shareを試してみたら凄すぎて鼻血出た - 憂鬱な世界にネコパンチ!

のリンクの最後に

https://github.com/tmknom/study-vagrant

というvagrantの入門者向けテキストへのリンクがあって、その中身を見てたら複数サーバを一発で立ち上げる方法が書かれてあった。Multi-Machine - Vagrant Documentationの存在もすっかり忘れていたので

vagrantインスタンスが複数たっている場合のvagrantの挙動」

を遊びながら調べてみる。24日目: windowsクリーンインストール その2 - わすれっぽいきみえでチャレンジしてみたいって言ってたしね。

vagrantで複数インスタンスを立ち上げてみる

vim Vagrantfile

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

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "chef/centos-6.5"
  config.vm.define "web_server" do |web|
    web.vm.network :private_network, ip: "192.168.33.10"
  end

  config.vm.define "db_server" do |db|
    db.vm.network :private_network, ip: "192.168.33.20"
  end
end

上記のようにVagrantfileを編集したら実際にvagrantを立ち上げてみる。

$ vagrant up
Bringing machine 'web_server' up with 'virtualbox' provider...
Bringing machine 'db_server' up with 'virtualbox' provider...
==> web_server: Importing base box 'chef/centos-6.5'...
==> web_server: Matching MAC address for NAT networking...
==> web_server: Checking if box 'chef/centos-6.5' is up to date...
==> web_server: Setting the name of the VM: centos65_web_server_1396764484965_96227
==> web_server: Clearing any previously set network interfaces...
==> web_server: Preparing network interfaces based on configuration...
    web_server: Adapter 1: nat
==> web_server: Forwarding ports...
    web_server: 22 => 2222 (adapter 1)
==> web_server: Booting VM...
==> web_server: Waiting for machine to boot. This may take a few minutes...
    web_server: SSH address: 127.0.0.1:2222
    web_server: SSH username: vagrant
    web_server: SSH auth method: private key
    web_server: Error: Connection timeout. Retrying...
==> web_server: Machine booted and ready!
(省略)
==> web_server: Checking for guest additions in VM...
==> web_server: Mounting shared folders...
    web_server: /vagrant => /Users/kimikimi714/Documents/vagrant/centos65
==> db_server: Importing base box 'chef/centos-6.5'...
==> db_server: Matching MAC address for NAT networking...
==> db_server: Checking if box 'chef/centos-6.5' is up to date...
==> db_server: Setting the name of the VM: centos65_db_server_1396764646844_69807
==> db_server: Fixed port collision for 22 => 2222. Now on port 2200.
==> db_server: Clearing any previously set network interfaces...
==> db_server: Preparing network interfaces based on configuration...
    db_server: Adapter 1: nat
==> db_server: Forwarding ports...
    db_server: 22 => 2200 (adapter 1)
==> db_server: Booting VM...
==> db_server: Waiting for machine to boot. This may take a few minutes...
    db_server: SSH address: 127.0.0.1:2200
    db_server: SSH username: vagrant
    db_server: SSH auth method: private key
    db_server: Error: Connection timeout. Retrying...
==> db_server: Machine booted and ready!
(省略)
==> db_server: Checking for guest additions in VM...
==> db_server: Mounting shared folders...
    db_server: /vagrant => /Users/kimikimi714/Documents/vagrant/centos65

$ vagrant status
Current machine states:

web_server                running (virtualbox)
db_server                 running (virtualbox)

This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.

ふむ。ここまでは特に問題なく動作した。

/vagrantフォルダの挙動

web_serverとdb_serverの/vagrant以下にはどんな風にファイルが共有されるんだろう。

$ touch a
$ vagrant ssh web_server
Last login: Sun Apr  6 07:33:16 2014 from 10.0.2.2
[vagrant@web_server ~]$ ls -la /vagrant
合計 8
drwxr-xr-x.  1 vagrant vagrant  204  46 08:04 2014 .
dr-xr-xr-x. 23 root    root    4096  46 07:27 2014 ..
drwxr-xr-x.  1 vagrant vagrant  102  33 14:41 2014 .vagrant
-rw-r--r--.  1 vagrant vagrant  455  46 07:27 2014 Vagrantfile
-rw-r--r--.  1 vagrant vagrant    0  46 08:04 2014 a
drwxr-xr-x.  3 vagrant vagrant  102  4  5 16:05 nodes
[vagrant@web_server ~]$ touch /vagrant/b
[vagrant@web_server ~]$ exit
logout
Connection to 127.0.0.1 closed.
$ ls -la
total 8
drwxr-xr-x  7 kimikimi714  group  238  4  6 17:07 .
drwxr-xr-x  3 kimikimi714  group  102  4  6 13:57 ..
drwxr-xr-x  3 kimikimi714  group  102  3  3 23:41 .vagrant
-rw-r--r--  1 kimikimi714  group  455  4  6 16:27 Vagrantfile
-rw-r--r--  1 kimikimi714  group    0  4  6 17:04 a
-rw-r--r--  1 kimikimi714  group    0  4  6 17:07 b
drwxr-xr-x  3 kimikimi714  group  102  4  5 16:05 nodes
$ vagrant ssh db_server
Last login: Sun Apr  6 07:33:49 2014 from 10.0.2.2
[vagrant@localhost ~]$ ls -la /vagrant/
合計 8
drwxr-xr-x.  1 vagrant vagrant  238  46 08:07 2014 .
dr-xr-xr-x. 23 root    root    4096  46 07:29 2014 ..
drwxr-xr-x.  1 vagrant vagrant  102  33 14:41 2014 .vagrant
-rw-r--r--.  1 vagrant vagrant  455  46 07:27 2014 Vagrantfile
-rw-r--r--.  1 vagrant vagrant    0  46 08:04 2014 a
-rw-r--r--.  1 vagrant vagrant    0  46 08:07 2014 b
drwxr-xr-x.  1 vagrant vagrant  102  45 07:05 2014 nodes

ふむふむ。ホストのディレクトリとweb_serverの/vagrant、db_serverの/vagrantは同じファイルが同期されてる。
どちらかのゲストサーバにだけ同期させたいファイルがある場合にはshared_folderの設定を別途する必要がありそう。

sandboxモードをどちらかにだけ適応したい場合

saharaプラグインをどっちかのサーバにだけ適応したいと思ったときはどうしたらいいんだろう。

$ vagrant sandbox status
[db_server] Sandbox mode is off
[web_server] Sandbox mode is off
$ vagrant sandbox on
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
$ vagrant sandbox status
[db_server] Sandbox mode is on
[web_server] Sandbox mode is on
$ vagrant sandbox off
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
$ vagrant sandbox status
[db_server] Sandbox mode is off
[web_server] Sandbox mode is off
$ vagrant sandbox on web_server
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
$ vagrant sandbox status
[db_server] Sandbox mode is off
[web_server] Sandbox mode is on
$ vagrant sandbox off web_server
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
$ vagrant sandbox status
[db_server] Sandbox mode is off
[web_server] Sandbox mode is off

ふむふむ。どのサーバもsandboxモードにしたいならvagrant sandbox onで、サーバを指定したいときはvagrant sandbox on server_nameでいけるのね。vagrant sandbox statusはサーバを指定しないといけない場合が思い浮かばないから実験してない。

chefのレシピをどちらかのサーバにだけ適応したい場合

Vagrantfile 1つでまとめて立ち上げられたvagrantインスタンスに別々のレシピを流し込みたいときはどうしたらいいんだろう。
試しにvagrant ssh-configをたたいてみる。

$ vagrant ssh-config
This command requires a specific VM name to target in a multi-VM environment.

なるほど、db_serverweb_serverかを指定しないといけないのか。じゃあそれぞれvagrant ssh-configをたたいてみよう。

$ vagrant ssh-config web_server
Host web_server
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/kimikimi714/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL
$ vagrant ssh-config db_server
Host db_server
  HostName 127.0.0.1
  User vagrant
  Port 2200
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/kimikimi714/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL

おお、ポートがちがう。ということは異なるポートを指定して、それぞれ違うレシピが適応できそうだな。ひとまずknife soloを実行できる環境を作ろう。

$ vagrant ssh-config web_server >> ~/.ssh/config
$ vagrant ssh-config db_server >> ~/.ssh/config
$ knife solo prepare web_server
$ knife solo prepare db_serber

次に実際にレシピを適応してみる。
helloレシピとbyeレシピを以下のようにして用意しておく。

vim site-cookbooks/hello/recipes/default.rb

log "Hello World"

vim site-cookbooks/bye/recipes/default.rb

log "Good Bye"

で、それぞれのサーバで各レシピが呼べるようにしておく。

vim nodes/web_server.json

{
    "run_list":[
        "recipe[hello]"
    ]
}

vim nodes/db_server.json

{
    "run_list":[
        "recipe[bye]"
    ]
}

あとは料理するだけ

$ knife solo cook web_server
Running Chef on web_server...
Checking Chef version...
Uploading the kitchen...
Generating solo config...
Running Chef...
Starting Chef Client, version 11.10.4
Compiling Cookbooks...
Converging 1 resources
Recipe: hello::default
  * log[Hello World] action write


Running handlers:
Running handlers complete

Chef Client finished, 1/1 resources updated in 0.482467917 seconds
$ knife solo cook db_server
Running Chef on db_server...
Checking Chef version...
Uploading the kitchen...
Generating solo config...
Running Chef...
Starting Chef Client, version 11.10.4
Compiling Cookbooks...
Converging 1 resources
Recipe: bye::default
  * log[Good bye] action write


Running handlers:
Running handlers complete

Chef Client finished, 1/1 resources updated in 0.68323387 seconds

うん。ちゃんとそれぞれのサーバにレシピを適応できる。
どちらかのサーバにだけレシピを適応するのも簡単に出来た。

vagrantの複数インスタンスを一度に立ち上げるときにそれぞれ違うOSのバージョンで立ち上げる

$ vagrant box list
chef/centos-6.5 (virtualbox)
chef/debian-7.4 (virtualbox)

vagrantのboxが既に上記のような状態だったとして、どうやったら各インスタンスを違うOSで立ち上げられるか。
Multi-Machine - Vagrant Documentationの例に書かれたVagrantfileを参考にすると

vim Vagrantfile

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

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.define "web_server" do |web|
    web.vm.box = "chef/centos-6.5"
    web.vm.network :private_network, ip: "192.168.33.10"
  end

  config.vm.define "db_server" do |db|
    db.vm.box = "chef/debian-7.4"
    db.vm.network :private_network, ip: "192.168.33.20"
  end
end

この状態で一度vagrant destroyしておき、再びvagrant upを実行すると

$ vagrant up
Bringing machine 'web_server' up with 'virtualbox' provider...
Bringing machine 'db_server' up with 'virtualbox' provider...
==> web_server: Checking if box 'chef/centos-6.5' is up to date...
(省略)
==> db_server: Importing base box 'chef/debian-7.4'...
(省略)
$ vagrant ssh web_server
Last login: Mon Apr 21 14:18:53 2014 from 10.0.2.2
[vagrant@localhost ~]$ cat /etc/redhat-release
CentOS release 6.5 (Final)
[vagrant@localhost ~]$ exit
logout
Connection to 127.0.0.1 closed.
$ vagrant ssh db_server
Linux packer-debian-7 3.2.0-4-amd64 #1 SMP Debian 3.2.54-2 x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Mar 30 20:25:56 2014 from 10.0.2.2
vagrant@packer-debian-7:~$ cat /etc/debian_version
7.4
vagrant@packer-debian-7:~$ exit
logout
Connection to 127.0.0.1 closed.

いけた。web_serverはcentos、db_serverはdebianで作成できたぞ。
ていうかchef/debian-7.4のboxってそもそもpackerで作成されてたっぽい。知らなかったー。