Vagrant: 仮想マシンのコピーとネットワーク

ZeroMQで遊んでいたらPub/Subに限りトランスポートプロトコルにPGM(RFC3208)を選択できる事を知った。

PGMUDPと同じトランスポートレイヤのプロトコルで動作するマルチキャストを提供する実験的なプロトコルで、 実装にはOpenPGMがある。 Blackduckをみると2011年頃には開発が止まっている。

EPGMはPGMUDP埋め込んだプロトコル

PGMの利用にはマルチキャストをサポートするデバイスを使って通信する必要がある。 だがループバックデバイスはマルチキャストをサポートしていない。

ifconfigで確認している図。マルチキャストはサポートされていなかった。 ifconfigで確認している図。マルチキャストはサポートされていなかった。

しかし他の仮想デバイス(enp0s9, …)はサポートしていた。 そこで現在のVMをコピーして内部ネットワーク内に2台起動している状態を作る事にした。 今の設定の時点で"public_network“を使っているため単純に2台起動するだけで仮想マシン間で通信可能になるが、別の機会に活かすためプライベートネットワークの設定も調べた。

これによりZeroMQ over PGMを試せる状態になった。 しかし手数が多いわりに、開発も停止した古い実験的なプロトコル上でZeroMQが稼働するのを観察するだけ。。 (自分も含めて)誰得作業に突き進んでいて末法って感じがする。 しかも別の機会に書くけど(e)pgm上でZeroMQ を動かせずに終わった。。

Vagrantについては下を参考にコマンドとモデルを知っておく

だいたい下を眺めた。ただしリストの最後の2つでVagrantのネットワークに関する説明が読めるけど整理が不完全な気配がある。

仮想内部ネットワークはVirtualBoxの用語だし、ホストオンリーアダプタは内部ネットワークを提供するVirtualBoxの用語になる。 簡単にはVagrantのホストオンリーアダプタという用語は見つけられなかった。

Qiita記事などによるとホストオンリーアダプタは仮想ネットワークインタフェースを作成してホストとゲストに閉じたネットワークを構築するらしい。 プロバイダがVirtualBoxの場合しか確認していないものの、その様なネットワークは構築されない。

プロバイダがVirtualBoxの場合、ゲストOSはデフォルトでNATを経由し外部ネットワークに接続する。 VirtualBoxのオプションでポートフォワードを設定できる様になっておりVagrantはデフォルトでssh用にポートフォワードを設定している。 これによりホストからゲストへsshが可能になるが、ホスト・ゲストのみが所属するネットワークが構成されるわけではない。 (この辺を調べるのに下のコマンドを利用した)

1
2
# in OSX版 `netstat -tnpa`
$ lsof -nP -iTCP

ref. Linuxと挙動がちがってて使いにくいOSXのコマンド(top/ps/netstat)の代替)

現在のVMを増やす手順

やった作業は下になる。

  1. 利用中VMのスナップショットをboxファイルにパッケージ化
  2. boxファイルをboxリストに登録
  3. Vagrantファイルを書き換えて内部ネットワークを共有する設定に変更
  4. 新規ノードを立ち上げる
  5. ファイアウォールを停止

1, 2 スナップショットのboxリスト登録まで

下のコマンドで完了。改めてVagrantは便利。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$ vagrant package --output snapshot.box
==> default: Attempting graceful shutdown of VM...
==> default: Clearing any previously set forwarded ports...
==> default: Exporting VM...
load: 3.74  cmd: VBoxManage 58502 waiting 0.35u 0.44s
==> default: Compressing package to: /Users/masumi/works/in_linux/snapshot.box
$ vagrant box add test-zeromq {$snapshot}.box
==> box: Adding box 'test-zeromq' (v0) for provider:
    box: Downloading: file:///Users/masumi/works/in_linux/snapshot.box
==> box: Successfully added box 'test-zeromq' (v0) for 'virtualbox'!

$ vagrant box list
centos70    (virtualbox, 0)
test-zeromq (virtualbox, 0)

3 Vagrantファイル書き換えまで

Vagrantファイルはずいぶん前にAnsibleのプロビジョニングを設定していたものを利用していた。 今回、下の様に書き換えた。ポイントは3つ。

  • 既存ノードはdefaultとして名前も設定も維持する
  • 新規ノード(fortest)を定義、boxには作ったスナップショットを利用する
  • 通信に使うプライベートネットワークはVirtualBoxの仮想内部ネットワークを利用する
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# -*- mode: ruby -*-
# vi: set ft=ruby :

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure(2) do |config|

  config.vm.define :default do |node|
    node.vm.box = "centos70"
    node.vm.box_url = "https://github.com/tommy-muehle/puppet-vagrant-boxes/releases/download/1.1.0/centos-7.0-x86_64.box"

    node.vm.hostname = "pit"
    node.vm.network "private_network", ip: "192.168.33.10", virtualbox__intnet: "test_net"
    node.vm.network "public_network"

    node.vm.provision "ansible" do |ansible|
      ansible.playbook = "provisioning/playground.yml"
      # ansible.inventory_path = "provisioning/hosts"
      ansible.limit = 'all'
    end
  end

  config.vm.define :fortest do |node|
    node.vm.box = "test-zeromq"
    node.vm.hostname = "for.test"
    node.vm.network "private_network", ip: "192.168.33.11", virtualbox__intnet: "test_net"
    node.vm.network "public_network"
  end
end

4,5 新規ノードを立ち上げてファイアーウォールを停止する

以下のようにfortest ノードを立ち上げる。 (打ちミスしてdefault ノードを破壊してもスナップショットがあるので問題ないので気楽)

1
$ vagrant up fortest

内部ネットワークを共有する2台のVMを立ち上げられた事になる。 疎通確認としてはpingを利用する。またICMP以外が通過しなかったのでとりあえずファイアーウォールを停止した。

1
2
3
4
(in host)$ vagrant ssh default
(in default)$ systemctl stop firewalld
(in host)$ vagrant ssh fortest
(in fortest)$ systemctl stop firewalld

とりあえず以上でスナップショットを使った簡単VM複製(内部ネットワークで通信可能)は完了する。 確認したところ、ここまで実施したらTCP上でZeroMQを利用できた。

comments powered by Disqus