Vagrant では、一つの BASE BOX イメージから、複数の VMを起動することができるようになってえらくステキです。
勿論、複数のイメージファイルを指定することもできますけれども、BASE BOX は素の状態にしておいて、各サーバは Chef の Role を使って識別して、構成できるようにするのが宗教的理由により優れていると判断しましたので、そのように構成してみようと至ったわけです。
今は、たまたま、ZABBIX2.2の環境を構成しようとしているのですが、ZABBIX の Webフロントエンドと、ZABBIX本体(+DB)を別々のサーバにして構成してみようというところから、この考えに至ったというか、今朝、入門Chef Solo - Infrastructure as Codeを読んでいたら、「Vagrant で、複数のVMを管理できるのか!!( ゚д゚ )クワッ!! Vagrant やべぇ!!」となったので、試してみただけです。
宗教的とかいってゴメンなさい、思いつきです。
1.正攻法で複数のVMをVagrantで制御する方法
まず、まっとうに、複数の BOXを元にして、それぞれの VMを起動する方法です。
めでたいことに VagrantのdocumentとしてMULTI-MACHINEのところに、その記述があります。
Vagrant.configure("2") do |config|
config.vm.provision "shell", inline: "echo Hello"
config.vm.define "web" do |web|
web.vm.box = "apache"
end
config.vm.define "db" do |db|
db.vm.box = "mysql"
end
end
複数定義しているところは、config.vm.define
部分ですね。それぞれ、web
と db
と関連づけられた VMを指定するようにしてあります。対象は次のとおりです。分かりやすいですね。
定義名 | 対象VM |
---|---|
web | apache |
db | mysql |
このように指定することで、複数の VMを vagrantで制御できるようになります。
この時、vagrant up
すると、全ての VMが起動します。
vagrant は command
+ 定義名
で個別の制御が可能です。従って、vagrant up web
とすれば、apache
VM のみを、vagrant up db
とすれば mysql
VM のみを起動することができます。ssh
や halt
も同様です。
sshの定義
みなさまご存じの通り、vagrant では vagrant ssh-config
にて、ssh の構成を自動的に作ってくれる、便利な機能がありやんす。
これのお陰で、~/.ssh/config
が溢れんばかりになっているクズもいることでしょうが、これほど便利な機能もありません。コレのために vagrant を使っていると言っても過言ではありません。ウソです。
さて、このように複数VMの場合ではどうすれば良いか。
同じです。
vagrant ssh-config web
とすれば、おめでたい感じで出てきますが、--host
をつけると、対象の定義名を変更して割り当てることもできます。
例えば、vagrant ssh-config web --host web.oshiire.to
なんていう風にすれば、このようになります。
Host web.oshiire.to
HostName 127.0.0.1
User vagrant
Port 2222
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
PasswordAuthentication no
IdentityFile /Users/sho/.vagrant.d/insecure_private_key
IdentitiesOnly yes
LogLevel FATAL
(Mavericks使用:sho
ユーザの場合)
このようなおめでたい定義を、ssh コマンドで利用できるよう、vagrant ssh-config web --host web.oshiire.to >> ~/.ssh/config
としておくと、knife
をぶん回すときにも、knife solo cook web.oshiire.to
なんて感じで使うことができて便利です。やったね、たえちゃん。
2.一つのboxから、複数の VMをVagrant で制御する方法
今日のメインはコレです。
実際に構成ファイルを見てもらった方が良いでしょう。どうぞ。
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "debian-7.4_c64"
config.vm.define :web do | web |
end
config.vm.define :zabbix do | zabbix |
end
もろに我が家での構成ファイルですが、config.vm.define
の外で、config.vm.box
を指定することで、この vm.boxを元に、必要なVMの数だけ VMがコピーされて利用できるようになります。
今回は 2つだけですが、4個も 10個も書けば、その分の VMが起動されて、あなたのマシンのリソースがなくなって大変なことになるでしょう。ぜひ、お試しください。
##VM間通信をできるようにするには
ぶっちゃけ、ここまでの話はどうでも良かったんです。そこら中に書いてあるので。
私がはまったのは、この先です。困ったことに、private_network 同士のVM間で通信できないのです。
イロイロと資料を見る限り、xx.vm.network
で hostonly
のネットワークを作れば、VM間での通信ができると、入門Chef にも多くのblogでも散見されました。しかし、うまくいかない。
どうしたもんかと、結局、Vagrant本家のPRIVATE NETWORKSを見てみると、書いてあるじゃないですか。virtualbox__intnet: true
しろよって。
ただ、これだけじゃあかんのですわ。
virtualbox__
(ご丁寧に、安駄婆(あんだばあ)は二つって注釈付) prefix のものは、その指定した内容を、vitualbox provider へ送ることができるらしいです。んで、private な内部ネットワークを作る場合、virtualbox では、その 内部ネットワーク名
を指定する必要があるんです。で、その同一のネットワークでは疎通が可能になる「みたい」です。
従って、VM同士でネットワークをつなげたい場合、virtualbox__intnet: "xxxx"
と共通の名前を付けましょうというのが、今日の一大事です。覚えて帰りましょう。
結果、我が家では次のように指定しています。みなさまも、どうぞご健勝ください。
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# All Vagrant configuration is done here. The most common configuration
# options are documented and commented below. For a complete reference,
# please see the online documentation at vagrantup.com.
# Every Vagrant virtual environment requires a box to build off of.
config.vm.box = "debian-7.4_c64"
config.vm.define :web do | web |
web.vm.hostname = "web"
web.vm.network :private_network, ip: "192.168.33.10", virtualbox__intnet: "intnet"
end
config.vm.define :zabbix do | zabbix |
zabbix.vm.hostname = "zabbix"
zabbix.vm.network :private_network, ip: "192.168.33.20", virtualbox__intnet: "intnet"
end
ついでなので、各VM に xxx.vm.hostname
を使って、host名も定義しています。これで host名も変更されてステキです。どうぞ、ご利用ください。
※ 当環境は vagrant 1.4.3 + virtualbox 4.3.6 においてで、今後のversionによっては変更がなされるやも知れません。