ツール

Vagrantの仮想マシンのネットワークについて詳しく説明する

更新日:

Vagrantで設定できるのネットワークの特徴とその設定方法についてまとめました。

環境はホストOSにMacOS、仮想環境(プロバイダ)にはVirtualBoxを使って確認しています。 そのためプロバイダについての記載はVirtualBoxに固有の内容が多くなっていますが、 その点はご容赦ください。

仮想マシンのネットワークの種類

Vagrantのマニュアルでは、 仮想マシンのネットワークの種類として次のものが紹介されています。

  • 明示的なネットワーク設定なし(デフォルト)
  • Private Network
  • Public Network

しかし、ここでは便宜上、VirtualBoxのネットワークの名前を借りて、 次のような種類に分けて説明していきたいと思います。

  • NAT
  • NAT+ホストオンリーアダプター
  • NAT+内部ネットワーク
  • NAT+ブリッジアダプター

VirtualBoxのネットワークについては以下のようなサイトで詳しく説明されています。 VirtualBoxのネットワークを知っていると、この後の説明も理解しやすいと思いますので参照して見てください。

仮想マシンはどこと通信できるのか?

どのネットワークを使用するか決めるのに必要なのは、おそらく仮想マシンがどこと通信できるのか? という情報でしょう。 例えばホストのWebブラウザから仮想マシンのWebサーバへアクセスしたい、 仮想マシン同士で通信が必要といった状況で、適切なネットワークを選ぶ必要があります。

ここでは仮想マシン間、仮想マシンととホストOS、仮想マシンと外部マシンのそれぞれで、 通信できるか見ていきます(下記の図の赤矢印の通信)。

Vagrantネットワークアクセス

それでは前述のネットワークの種類ごとに誰と通信できるか見てみましょう。

NAT

NATで通信できる相手をまとめたのが次の表です。 (左側の)縦に並んだマシンから、列のマシンにアクセスできれば「○」、 アクセスできなければ「×」です。 なお、縦の列の仮想マシンと横の列の仮想マシンば別々の仮想マシンです。

ホストOS 仮想マシン 外部マシン
ホストOS -×-
仮想マシン ×
外部マシン -×-

このように仮想マシンからホストOSと外部マシンへは通信できます。 その際はNATでIPアドレス変換されます。 これ以外とは通信できません。 これを使うのは主に仮想マシン単体で使う(他との通信は必要ない)場合でしょう。

NATはデフォルトで構成されるネットワークです。 他の種類のネットワークで「NAT+」と表現しているのは、 他のネットワークでも必ずこのNATのネットワークは作成されるからです。

NAT+ホストオンリーアダプター

NAT+ホストオンリーアダプターで通信できる相手は次の通りです。

ホストOS 仮想マシン 外部マシン
ホストOS --
仮想マシン
外部マシン -×-

NAT+ホストオンリーアダプターでは、ホストOSと仮想マシンは双方向に通信できます。 仮想マシン間でも通信ができます。 仮想マシンから外部マシンへ通信できるのはNATと同様です。

これを使うのは、ホストOSから仮想マシンにアクセスしたい場合でしょう。 例えば、ホストOSのWebブラウザから仮想マシンのWebサーバにアクセスしたい場合などです。

NAT+内部ネットワーク

NAT+内部ネットワークで通信できるのは次の通りです。

ホストOS 仮想マシン 外部マシン
ホストOS -×-
仮想マシン
外部マシン -×-

仮想マシンからホストOSや外部マシンへと通信できるのはNATと同様です。 加えて仮想マシン同士でも通信できます。 仮想マシン間で通信が必要な場合は、これを選ぶと良いでしょう。

NAT+ブリッジアダプター

NAT+ブリッジアダプターで通信できる相手は次の通りです。

ホストOS 仮想マシン 外部マシン
ホストOS --
仮想マシン
外部マシン --

ネットワーク上で仮想マシンは独自のIPアドレスを持つ通常のマシンのように見えますので、 誰とでも通信が可能になります。 ネットワーク上のマシンからもアクセスできるので、セキュリティには注意が必要です。

Vagrantで仮想マシンを建てるのは、一般にテストのためだと思いますので、 この構成を使うことは少ないでしょう。

Vagrantfileの設定方法

上述のネットワークを構成するためのVagrantfileの設定について見ていきましょう。

NATの設定

NATはデフォルトで構成されるネットワークなので、 Vagrantfileにネットワークに関する設定は必要ありません。 設定例を見て見ましょう。

Vagrant.configure("2") do |config|

  config.vm.define "guest1" do |a|
    a.vm.box = "centos/7"
    a.vm.hostname = "guest1"
  end

  config.vm.define "guest2" do |b|
    b.vm.box = "centos/7"
    b.vm.hostname = "guest2"
  end
end

このようにVagrantfileにはネットワークに関する設定はありません。 ここではboxファイルとホスト名を設定しているだけです。 仮想マシン間の通信を確認するため仮想マシンは2台用意しています。

NAT+ホストオンリーアダプターの設定

この構成ではスタティックにIPアドレスを割り当てることができます。 ただし、割り当てるIPアドレスはプライベートIPアドレスである必要があります。 DHCPを使って動的にIPアドレスを割り当てることもできます。

まず、スタティックにIPアドレスを割り当てるVagrantfileの設定です。 これは次のように記述します。

Vagrant.configure("2") do |config|

  config.vm.define "guest1" do |a|
    a.vm.box = "centos/7"
    a.vm.hostname = "guest1"
    a.vm.network "private_network", ip: "192.168.100.10"
  end

  config.vm.define "guest2" do |b|
    b.vm.box = "centos/7"
    b.vm.hostname = "guest2"
    b.vm.network "private_network", ip: "192.168.100.20"
  end
end

次の部分がNAT+ホストオンリーアダプターの設定とIPアドレスを指定している部分です。

a.vm.network "private_network", ip: "192.168.0.10"
b.vm.network "private_network", ip: "192.168.0.11"

DHCPでIPアドレスを割り当てるには、次のようにVagrantfileを記述します。

Vagrant.configure("2") do |config|

  config.vm.define "guest1" do |a|
    a.vm.box = "centos/6"
    a.vm.hostname = "guest1"
    a.vm.network "private_network", type: "dhcp"
  end

  config.vm.define "guest2" do |b|
    b.vm.box = "centos/6"
    b.vm.hostname = "guest2"
    b.vm.network "private_network", type: "dhcp"
  end
end

なお、この設定ではホストOSにvboxnet0のようなインターフェースが作成されます。 このインターフェースはvagrant destroyで仮想マシンを削除しても残ります。 削除方法などは後述します。

NAT+内部ネットワークの設定

プロバイダがVirtualBoxの場合、 VirtualBoxの内部ネットワークを構成するオプションが使えます。 仮想マシンにスタティックにIPアドレスを割り当てるには、Vagrantfileに次のように記述します。

Vagrant.configure("2") do |config|

  config.vm.define "guest1" do |a|
    a.vm.box = "centos/7"
    a.vm.hostname = "guest1"
    a.vm.network "private_network", ip: "192.168.100.30",
        virtualbox__intnet: "mynetwork"
  end

  config.vm.define "guest2" do |b|
    b.vm.box = "centos/7"
    b.vm.hostname = "guest2"
    b.vm.network "private_network", ip: "192.168.100.40",
        virtualbox__intnet: "mynetwork"
  end
end

DHCPでIPアドレスを割り当てるには次のようにします。

Vagrant.configure("2") do |config|

  config.vm.define "guest1" do |a|
    a.vm.box = "centos/7"
    a.vm.hostname = "guest1"
    a.vm.network "private_network", type: "dhcp"
        virtualbox__intnet: "mynetwork"
  end

  config.vm.define "guest2" do |b|
    b.vm.box = "centos/7"
    b.vm.hostname = "guest2"
    b.vm.network "private_network", type: "dhcp"
        virtualbox__intnet: "mynetwork"
  end
end

NAT+ブリッジアダプターの設定

NAT+ブリッジアダプターはVagrantfileに次のように記述します。

Vagrant.configure("2") do |config|

  config.vm.define "guest1" do |a|
    a.vm.box = "centos/7"
    a.vm.hostname = "guest1"
    a.vm.network "public_network"
  end

  config.vm.define "guest2" do |b|
    b.vm.box = "centos/7"
    b.vm.hostname = "guest2"
    b.vm.network "public_network"
  end
end

それぞれのネットワーク詳細を確認する

ここからはそれぞれのネットワークをログや仮想マシンのインタフェース設定などから詳しく見ていきます。

NATの詳細

前述の通りVagrantfileに明示的なネットワークの設定が無いと、 VirtualBoxのNATとして環境が構成されます。NATの特徴は次の通りです。

  • 仮想マシンは外部マシンやホストOSへはNATを通してアクセスできる。 つまり、仮想マシンのIPアドレスはNATで変換されて外部マシンやホストOSと通信します。
  • ホストOS、外部マシン、他の仮想マシンからは仮想マシンへアクセスできない。

仮想マシンの起動ログを見る

vagrant upしたときのログを見てみます。これからといくつかのことがわかります。

$ vagrant up
...
==> guest1: Matching MAC address for NAT networking...
...
==> guest1: Clearing any previously set network interfaces...
==> guest1: Preparing network interfaces based on configuration...
    guest1: Adapter 1: nat
==> guest1: Forwarding ports...
    guest1: 22 (guest) => 2222 (host) (adapter 1)
==> guest1: Booting VM...
==> guest1: Waiting for machine to boot. This may take a few minutes...
    guest1: SSH address: 127.0.0.1:2222
    guest1: SSH username: vagrant
    guest1: SSH auth method: private key
...

上記は関連するところだけ抜粋しています。 ログを見ると「Adapter 1」がNATに設定されていることがわかります。 また、「vagrant ssh」のためのポートフォワーディングの設定がされているのも分かります (「Forwarding ports...」以降)。 これは1つ目の仮想マシン(guest1)設定時のログですが、 2つ目の仮想マシン(guest2)も同様です。

仮想マシンのアダプターがNATであることは、VirtualBoxのGUIからも確認できます。

VirtualBox GUI NAT

NICとIPアドレスを確認する

それぞれの仮想マシンのNICとIPアドレスは次の通り設定されていました。

[vagrant@guest1 ~]$ ip addr show
...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
    link/ether 52:54:00:4d:77:d3 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global noprefixroute dynamic eth0
...
      
[vagrant@guest2 ~]$ ifconfig
...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
    link/ether 52:54:00:4d:77:d3 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global noprefixroute dynamic eth0
...

仮想マシン(guest1とguest2)には、それぞれ eth0 が作成され、 プライベートIPアドレスが割り当てられています。 プライベートIPアドレスでは外部マシンと通信できませんので、 通信はNATされていることがこのことからもわかります。

また、どちらも同じIPアドレスとMACアドレスが設定されていることから、 お互いのネットワークは完全に分離されていると推測できます。 つまり、仮想マシン同士は通信できません。

次はホストOSのIPアドレスです。

$ ifconfig
...
en0: flags=8863&l5;UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> ...
...
      inet 192.168.1.8 netmask 0xffffff00 broadcast 192.168.1.255
...

ホストOSにはいくつかインターフェイスがありますが、使用しているのはen0です。 自宅PCでISP経由でインターネット接続していますので、 DHCPで「192.168.1.8(プライベートアドレス)」が割り当てられています。 ホストOSのIPアドレスは仮想マシンのネットワークと異なるので通信できません。

NAT+ホストオンリーアダプターの詳細

NAT+ホストオンリーアダプターは、VagrantではPrivate Networkとして説明されています。 Private Networkは仮想マシンを外部に公開しないネットワークです。 外部から仮想マシンにアクセスできないので仮想マシンのセキリティに気を使う必要がありません。

この構成はNATに加えて仮想マシンにホストオンリーアダプターが作成されます。 そのためNATの通信に加えて、ホストオンリーアダプターを使って通信もできます。

またホストOSにもvboxnet0のようなインターフェイスが作成され、 仮想マシンとの通信に利用されます。 そのため、この構成の特徴は次の通りになります。

  • NATを使った通信は前述の通りです。
  • 加えて仮想マシンのホストオンリーアダプターとホストOSのvboxnet0を使って双方向に通信が可能
  • vboxnet0を通して仮想マシン同士の通信も可能

仮想マシンの起動ログを見る

NAT+ホストオンリーアダプターのvagrant upのログを見てみましょう。

$ vagrant up
...
==> guest1: Preparing network interfaces based on configuration...
    guest1: Adapter 1: nat
    guest1: Adapter 2: hostonly
...
==> guest2: Preparing network interfaces based on configuration...
    guest2: Adapter 1: nat
    guest2: Adapter 2: hostonly
...

どちらの仮想マシンも「Adapter 1」のNATに加えて、 「Adapter 2」としてホストオンリーアダプターが追加されています。

NICとIPアドレスを確認する

仮想マシンのIPアドレスを確認します。

[vagrant@guest1 ~]$ ip addr show
...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
    link/ether 52:54:00:4d:77:d3 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global noprefixroute dynamic eth0
...
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
    link/ether 08:00:27:21:23:d3 brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.10/24 brd 192.168.100.255 scope global noprefixroute eth1
...
[vagrant@guest2 ~]$ ip addr show
...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
    link/ether 52:54:00:4d:77:d3 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global noprefixroute dynamic eth0
...
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
    link/ether 08:00:27:08:9e:85 brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.20/24 brd 192.168.100.255 scope global noprefixroute eth1
...

仮想マシンにはeth0に加えてeth1が追加されています。 これにはVagrantfileで指定したIPアドレスが設定されています。 eth0のIPアドレスとMACアドレスはデフォルトネットワーク時と同じです。

ホストOSのインターフェイスとIPアドレスも確認します。

$ ifconfig
...
vboxnet0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> ...
	ether 0a:00:27:00:00:00
	inet 192.168.100.1 netmask 0xffffff00 broadcast 192.168.100.255
...

ホストOSには新たにvboxnet0が作成されています。 IPアドレスは仮想マシンのホストオンリーアダプターと同じネットワークのIPアドレスが設定されています。 仮想マシンとホストOSはこのvboxnet0インターフェイスを通して通信できます。 仮想マシン間のvboxnet0を通して通信します。

ホストOSのvboxnetXを削除する

NAT+ホストオンリーアダプターを使用する場合、ホストOSにvboxnet0インターフェイスが作成されます。 vboxnet0は仮想マシンはvagrant destroyで破棄してもそのまま残ります。 そして、NAT+ホストオンリーアダプターの構成を使うたびに vboxnet1、vboxnet2、...のように複数作成されていきます。 そのため必要なくなったら削除しましょう。 削除するには次のコマンドを実行します。

VBoxManage hostonlyif remove vboxnet0

NAT+内部ネットワークの詳細

プロバイダがVirtualBoxの場合、内部ネットワークを構成するためのオプションが使えます。 NAT+内部ネットワークもVagrantのPrivate Networkの一種です。 これもPrivate Networkなのでやはり仮想マシンは外部へ公開されません。 この設定ではNATに加えて、内部ネットワークのアダプターが仮想マシンに作成されます。

NAT+内部ネットワークではホストOSにvboxnet0のようなインタフェースは作成されません。 仮想マシン同士は仮想環境内で直接接続されます。 そのため、この構成の特徴は次のようになります。

  • NATと同様の通信ができるのは今までと同じで、 仮想マシンからホストOSや外部マシンにアクセス可能。 ただし、ホストOSや外部マシンから仮想マシンへはアクセスできない。
  • 仮想マシン同士は通信可能。

仮想マシンの起動ログを見る

いつものように起動してログをます。

$ vagrant up
...
==> guest1: Preparing network interfaces based on configuration...
    guest1: Adapter 1: nat
    guest1: Adapter 2: intnet
...
==> guest2: Preparing network interfaces based on configuration...
    guest2: Adapter 1: nat
    guest2: Adapter 2: intnet
...

NATの「Adapter 1」に加えて、「Adapter 2」が内部ネットワークに設定されています。

NICとIPアドレスを確認する

仮想マシンのIPアドレスを確認します。

[vagrant@guest1 ~]$ ip addr show
...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
    link/ether 52:54:00:4d:77:d3 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global noprefixroute dynamic eth0
...
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
    link/ether 08:00:27:1d:6a:17 brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.30/24 brd 192.168.100.255 scope global noprefixroute eth1
...
[vagrant@guest2 ~]$ ip addr show
...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
    link/ether 52:54:00:4d:77:d3 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global noprefixroute dynamic eth0
...
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
    link/ether 08:00:27:bd:84:d2 brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.40/24 brd 192.168.100.255 scope global noprefixroute eth1
...

eth0のIPアドレスは今までと同じです。 eth1はVagrantfileで指定されたIPアドレスが設定されています。

ホストOSはNAT+ホストオンリーアダプターと異なり、 新たにvboxnet0のようなインターフェイスが追加されることはありません。

NAT+ブリッジアダプターの詳細

NAT+ブリッジアダプターはVagrantではPublic Networkと呼ばれます。 仮想マシンは外部からホストOSとば別のマシンのように見えます。

この構成ではNATアダブターに加えて、ブリッジアダプターが仮想マシンに作成されます。 特徴は次の通りです。

  • NATと同様の通信ができるのは今までと同じ。
  • 外部からは独自のIPアドレスを持つ、ホストOSとは別のマシンに見える。

仮想マシンの起動ログを見てみる

$ vagrant up
...
==> guest1: Available bridged network interfaces:
1) en0: Ethernet
2) en6: USB Ethernet(?)
3) ap1
4) en1: Wi-Fi (Wireless)
5) en4: Thunderbolt 3
6) en5: Thunderbolt 4
7) en2: Thunderbolt 1
8) en3: Thunderbolt 2
9) bridge0
==> guest1: When choosing an interface, it is usually the one that is
==> guest1: being used to connect to the internet.
==> guest1:
    guest1: Which interface should the network bridge to? 1
==> guest1: Preparing network interfaces based on configuration...
    guest1: Adapter 1: nat
    guest1: Adapter 2: bridged
...

ホスト側に複数のインターフェイスがある場合(だけだと思います)、 どのインターフェイスをブリッジに使用するか確認されます。 guest2も同様に確認を求められます。 そして仮想マシンにはNATとブリッジアダプターの2つのインターフェイスが作成されます。

IPアドレスを確認する

IPアドレスを確認を確認してみます。

[vagrant@guest1 ~]$ ip addr show
...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
    link/ether 52:54:00:4d:77:d3 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global noprefixroute dynamic eth0
...
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
    link/ether 08:00:27:9a:16:67 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.24/24 brd 192.168.1.255 scope global noprefixroute dynamic eth1
...
[vagrant@guest2 ~]$ ip addr show
...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
    link/ether 52:54:00:4d:77:d3 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global noprefixroute dynamic eth0
...
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
    link/ether 08:00:27:db:56:d6 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.26/24 brd 192.168.1.255 scope global noprefixroute dynamic eth1
...

eth0の設定はいつも通りです。 そしてeth1にはプライペートIPアドレスがそれぞれ設定されています。 これはホストOSと同じネットワークのIPアドレスです。 今回の自宅LAN内ですので、 ホストOSと仮想マシンにはDHCPに割り振られたプライペートIPアドレスがそれぞれ設定されています。 LAN内の他のマシンから見れば、ホストOS、guest1、guest2はそれぞれ別のマシンのように見えます。

まとめ

この記事では仮想マシンが誰と通信できるかまとめました。 ここでは説明できませんでしたが、 VagrantのForwarded Portを使って仮想マシンにアクセスできるようにすることもできます。 vagrant sshで仮想マシンログインできるのもForwarded Portで設定しているからです。 是非、Forwarded Portも活用して見てください。

さて、ちょっと調べるつもりがだいぶ長くなってしまいました。 最後までお付き合いいただき誠にありがとうございます。

-ツール
-

Copyright© アナグマのモノローグ , 2021 All Rights Reserved Powered by STINGER.