仮想マシンを外部ネットワークへ接続させる方法はいくつかあるみたいです。
- NATモード
- 初期状態だとこのモードです。仮想マシンはIPマスカレードされてホストのIPアドレスとして外へ出ていきます。外から仮想マシンへはアクセスするときは、一工夫必要になります。
- Routedモード
- ホストがルータとして動作します。仮想マシンは自身のIPアドレスで外へ出ていきます。外から仮想マシンへアクセスするときは、なんらかのルーティングが必要になります。
- ブリッジ
- libvirtの外側で設定されたブリッジデバイスに仮想マシンを接続します。
- ダイレクト-ブリッジ
- macvtapのbridgeモードを利用して直接ホストネットワークへ接続します。 @takehironet さんに教えてもらいました。Thanks 同一ホスト上の仮想マシン同士でやりとりする場合は、両方とも同じモードである必要があります。
- ダイレクト-プライベート
- macvtapのprivateモードを利用して直接ホストネットワークへ接続します。
- ダイレクト-vepa
- macvtapのvepaモードを利用して直接ホストネットワークへ接続します。vepa(Virtual Ethernet Port Aggregator)が使えるスイッチがないと使えません。
- ダイレクト-パススルー
- macvtapを利用して直接ホストネットワークへ接続します。物理インターフェースは一度に一つの仮装インターフェースからしか使えません。物理インターフェースに空きがないときはエラーが記録されます。
- ホストデバイス
- PCIネットワークデバイスを仮想マシンへ直接割り当てます。
ここではブリッジとダイレクト-プライベート、そしてダイレクト-ブリッジを試してみます。
やり方その1「ブリッジ」接続するときの作業手順
ここでは、物理デバイス名は「ens32」です。
(ステップ1) ブリッジコネクションを作成
「br0」というインターフェースに対してブリッジコネクションを作成します。
# nmcli con add type bridge ifname br0
Connection 'bridge-br0' (2ef66f6a-4079-4d07-9c1a-e9fdeecca8bd) successfully added.
こんなんできました。
# nmcli con show
NAME UUID TYPE DEVICE
vnet0 66568803-1d59-4dcf-b241-ff6cab294715 generic vnet0
ens32 461d3edc-1e6e-4334-b8dc-1ff3d691c03e 802-3-ethernet ens32
virbr0-nic 8d33a0ef-019a-4ce1-a8e8-71dc0c9bbe1e generic virbr0-nic
virbr0 4094d785-3de6-4acc-86bb-64cafc4d3deb bridge virbr0
bridge-br0 2ef66f6a-4079-4d07-9c1a-e9fdeecca8bd bridge br0
# nmcli dev
DEVICE TYPE STATE CONNECTION
virbr0 bridge connected virbr0
ens32 ethernet connected ens32
virbr0-nic tap connected virbr0-nic
vnet0 tap connected vnet0
br0 bridge connecting (getting IP configuration) bridge-br0
lo loopback unmanaged --
(ステップ2) ブリッジスレーブコネクションを作成
「bridge-br0」コネクションをマスターとして、「ens32」インターフェースをスレーブとするコネクションを作成します。
# nmcli con add type bridge-slave ifname ens32 master bridge-br0
Connection 'bridge-slave-ens32' (59ea6a01-af71-4f55-8433-eb7c49117578) successfully added.
こんなんできました。
# nmcli con
NAME UUID TYPE DEVICE
bridge-slave-ens32 59ea6a01-af71-4f55-8433-eb7c49117578 802-3-ethernet --
vnet0 66568803-1d59-4dcf-b241-ff6cab294715 generic vnet0
ens32 461d3edc-1e6e-4334-b8dc-1ff3d691c03e 802-3-ethernet ens32
virbr0-nic 8d33a0ef-019a-4ce1-a8e8-71dc0c9bbe1e generic virbr0-nic
virbr0 4094d785-3de6-4acc-86bb-64cafc4d3deb bridge virbr0
bridge-br0 2ef66f6a-4079-4d07-9c1a-e9fdeecca8bd bridge br0
# nmcli dev
DEVICE TYPE STATE CONNECTION
virbr0 bridge connected virbr0
ens32 ethernet connected ens32
virbr0-nic tap connected virbr0-nic
vnet0 tap connected vnet0
br0 bridge connecting (getting IP configuration) bridge-br0
lo loopback unmanaged --
(ステップ3) 既存コネクションを削除して再起動
ネットワーク接続が切れてしまうので、すかさず再起動してます。
# nmcli con delete ens32 && reboot
Connection 'ens32' (461d3edc-1e6e-4334-b8dc-1ff3d691c03e) successfully deleted.
うまくいけばこんな結果に。
# nmcli con
NAME UUID TYPE DEVICE
virbr0 89597488-c27c-4038-aeb9-ab426c19cfbe bridge virbr0
bridge-br0 2ef66f6a-4079-4d07-9c1a-e9fdeecca8bd bridge br0
bridge-slave-ens32 59ea6a01-af71-4f55-8433-eb7c49117578 802-3-ethernet ens32
virbr0-nic 9125d953-43f0-44c1-90a1-91db218a27b5 generic virbr0-nic
# nmcli dev
DEVICE TYPE STATE CONNECTION
br0 bridge connected bridge-br0
virbr0 bridge connected virbr0
ens32 ethernet connected bridge-slave-ens32
virbr0-nic tap connected virbr0-nic
lo loopback unmanaged --
# ip addr show br0
3: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 10:78:d2:e3:56:12 brd ff:ff:ff:ff:ff:ff
inet 172.27.51.121/24 brd 172.27.51.255 scope global dynamic br0
valid_lft 690988sec preferred_lft 690988sec
inet6 fe80::1278:d2ff:fee3:5612/64 scope link
valid_lft forever preferred_lft forever
(ステップ4) libvirtのネットワーク設定を作成
こんな内容のXMLファイルを作成します。
<network>
<name>host-bridge</name>
<forward mode="bridge" />
<bridge name="br0"/>
</network>
XMLの書式についてはこちら → http://libvirt.org/formatnetwork.html
virsh
コマンドで読み込みます。
# virsh net-define --file host-bridge.xml
Network host-bridge defined from host-bridge.xml
自動開始するようにします。
# virsh net-autostart host-bridge
Network host-bridge marked as autostarted
こんなんできました。
# virsh net-list --all
Name State Autostart Persistent
----------------------------------------------------------
default active yes yes
host-bridge inactive yes yes
(ステップ5) 既存仮想マシンのネットワーク接続を変更
<interface type='network'>
要素中身を変更します。
<source network='default'/>
<source network='host-bridge'/>
やり方その2「プライベート」接続するときの作業手順
(ステップ1) macvtapリンクを作成
# ip link add link ens32 name macvtap0 type macvtap mode private
状態がDOWNになっているので上げます。
# ip link set macvtap0 up
こんなんできました。
23: macvtap0@ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN mode DEFAULT qlen 500
link/ether 7e:f3:46:9c:f0:c1 brd ff:ff:ff:ff:ff:ff
(ステップ2) libvirtのネットワーク設定を作成
こんな内容のXMLファイルを作成します。
<network>
<name>vtap</name>
<forward mode="private">
<interface dev="macvtap0" />
</forward>
</network>
virsh
コマンドで読み込みます。
# virsh net-define --file net-private.xml
Network vtap defined from net-private.xml
自動開始するようにします。
# virsh net-autostart vtap
Network vtap marked as autostarted
こんなんできました。
# virsh net-list --all
Name State Autostart Persistent
----------------------------------------------------------
default active yes yes
vtap inactive yes yes
(ステップ3) 既存仮想マシンのネットワーク接続を変更
<interface type='network'>
要素の中身を変更します。
<source network='default'/>
<source network='vtap'/>
落穂拾(えない)
この方法だとホスト-VM間の通信ができません。VMにホストと通信するための別NICを追加する等の解決策があります。
作成したmacvtap0は再起動すると消えてしまいます。永続化の方法模索中。。。
やり方その3 「ダイレクト-ブリッジ」接続するときの作業手順
ここでは、物理デバイス名は「ens32」です。
既存仮想マシンのネットワーク接続を変更
<interface type='network'>
要素の中身を変更します。
<source network='default'/>
<source dev='ens32' mode='bridge'/>
新規インストール時にvirt-installで指定する場合
ネットワークのオプションを次のようにします。
--network type=direct,source=ens32,source_mode=bridge
source_modeを指定しないと、デフォルトのvepaになります。