KVMでゲストOSをブリッジ接続する

# 環境

- ホストOS : Lubuntu 18.04
- ゲストOS : CentOS 7.5

# ブリッジインターフェースの作成

KVMでデフォルトでvirbr0という名前のブリッジが作成されますが、NAT接続されているため、新しくbr0をいう名前のブリッジを作成してホストと同じネットワークに接続していきます。図の上の方の接続だったのを図の下の方に変更します。
![bridge_nat.png](https://qiita-image-store.s3.amazonaws.com/0/271649/f6a389a6-d6db-197a-f4f9-db6a04fb971e.png)

## ネットワークデバイスの確認

まずnmcli deviceコマンドでネットワークデバイスの確認を行います。物理インターフェースがenp7s0という名前で存在していて、コネクション名が有線接続 2ということがわかります。デフォルトのブリッジvirbr0があることも確認できます。

```
$ nmcli device 
DEVICE      TYPE      STATE     CONNECTION 
enp7s0      ethernet  接続済み  有線接続 2 
virbr0      bridge    接続済み  virbr0             
lo          loopback  管理無し  --         
virbr0-nic  tun       管理無し  --  
```

次にホストPCのIPアドレスを調べます。ここではenp7s0というデバイスに192.168.11.8が割当てられています。このアドレスは後で作成するブリッジに割り当てるので覚えておきます。

```
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp7s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 70:85:c2:69:67:9a brd ff:ff:ff:ff:ff:ff
    inet 192.168.11.8/24 brd 192.168.11.255 scope global dynamic noprefixroute enp7s0
       valid_lft 171445sec preferred_lft 171445sec
    inet6 2408:211:ba5:d600:2987:9797:d4e1:6fc0/64 scope global temporary dynamic 
       valid_lft 603456sec preferred_lft 84491sec
    inet6 2408:211:ba5:d600:7c3c:6da0:398e:9929/64 scope global dynamic mngtmpaddr noprefixroute 
       valid_lft 2591953sec preferred_lft 604753sec
    inet6 fe80::4050:8a3a:59aa:22a3/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 52:54:00:61:75:8c brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master virbr0 state DOWN group default qlen 1000
    link/ether 52:54:00:61:75:8c brd ff:ff:ff:ff:ff:ff
```

## nmcliによるブリッジ作成

現在ブリッジvirbr0しかありません。

```
$ brctl show
bridge name	bridge id		STP enabled	interfaces
virbr0		8000.52540061758c	yes		virbr0-nic
```

デバイス名br0というブリッジをnmcli c aコマンドで作成します。作成した後nmcli c sコマンドで確認するとbridge-br0が追加されています。作成したbridge-br0のスパニングツリーの設定を無効にします。そして、bridge-br0のIPアドレスを先程調べたIPアドレス192.168.11.8/24に設定し、ゲートウェイ、DNSサーバの設定をします。

```
# デバイス名br0というブリッジを作成
$ nmcli connection add type bridge ifname br0
接続 'bridge-br0' (ae86c45c-7740-4433-90f3-8e9f4354905b) が正常に追加されました。

# 接続情報の表示をすると、DEVICE名br0、接続名bridge-br0が追加されている。
$ nmcli connection show 
NAME        UUID                                  TYPE      DEVICE 
bridge-br0  ae86c45c-7740-4433-90f3-8e9f4354905b  bridge    br0    
virbr0      1244d4ca-0688-48ae-8bbf-bf199c197c1e  bridge    virbr0 
有線接続 2  551e08aa-0ff8-3fe9-8455-25410e3180a7  ethernet  enp7s0 
有線接続 1  2a187211-8139-31bf-9912-a99cab8752c3  ethernet  --  

# bridge-br0のスパニングツリーが有効になっている
$ nmcli connection show bridge-br0 | grep bridge.stp
bridge.stp:                             はい

# bridge-br0のスパニングツリーを無効にする
$ nmcli connection modify bridge-br0 bridge.stp no

# bridge-br0のスパニングツリーが無効になっている
$ nmcli connection show bridge-br0 | grep bridge.stp
bridge.stp:                             いいえ

# bridge-br0のIPアドレス、ゲートウェイ、DNSサーバの設定をします。
# IPアドレスは先程調べた値を指定します。
$ nmcli connection modify bridge-br0 ipv4.method manual ipv4.addresses "192.168.11.8/24" ipv4.gateway "192.168.11.1" ipv4.dns 192.168.11.1
```

ブリッジbridge-br0に物理インターフェースenp7s0を追加します。もともとenp7s0が接続していた有線接続2は削除してしまいます。

```
# ブリッジbridge-br0にデバイスenp7s0を接続タイプbridge-slaveとして追加する
$ nmcli connection add type bridge-slave ifname enp7s0 master bridge-br0
接続 'bridge-slave-enp7s0' (4686b212-a687-463f-ba8e-0f0d42bad827) が正常に追加されました

# 接続の一覧表示。bridge-br0が追加されています。
$ nmcli connection show 
NAME                 UUID                                  TYPE      DEVICE 
bridge-br0           ae86c45c-7740-4433-90f3-8e9f4354905b  bridge    br0    
virbr0               1244d4ca-0688-48ae-8bbf-bf199c197c1e  bridge    virbr0 
有線接続 2           551e08aa-0ff8-3fe9-8455-25410e3180a7  ethernet  enp7s0 
bridge-slave-enp7s0  4686b212-a687-463f-ba8e-0f0d42bad827  ethernet  --     
有線接続 1           2a187211-8139-31bf-9912-a99cab8752c3  ethernet  --    

# 不要になっ有線接続 2を削除します。
$ nmcli connection delete 有線接続\ 2 
接続 '有線接続 2' (551e08aa-0ff8-3fe9-8455-25410e3180a7) が正常に削除されました。

# bridge-slave-enp7s0という接続が出来ていて、enp7s0が接続されています。
$ nmcli connection show 
NAME                 UUID                                  TYPE      DEVICE 
bridge-br0           ae86c45c-7740-4433-90f3-8e9f4354905b  bridge    br0    
bridge-slave-enp7s0  4686b212-a687-463f-ba8e-0f0d42bad827  ethernet  enp7s0 
virbr0               1244d4ca-0688-48ae-8bbf-bf199c197c1e  bridge    virbr0 
有線接続 1           2a187211-8139-31bf-9912-a99cab8752c3  ethernet  --    
```

作成できたことの確認。

```
$ nmcli device 
DEVICE      TYPE      STATE     CONNECTION          
br0         bridge    接続済み  bridge-br0          
virbr0      bridge    接続済み  virbr0              
enp7s0      ethernet  接続済み  bridge-slave-enp7s0 
wlp6s0      wifi      切断済み  --                  
enp0s31f6   ethernet  利用不可  --                  
lo          loopback  管理無し  --                  
virbr0-nic  tun       管理無し  --                  

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp7s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br0 state UP group default qlen 1000
    link/ether 70:85:c2:69:67:9a brd ff:ff:ff:ff:ff:ff
3: enp0s31f6: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
    link/ether 70:85:c2:69:67:9c brd ff:ff:ff:ff:ff:ff
4: wlp6s0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
    link/ether 60:f6:77:a9:92:0a brd ff:ff:ff:ff:ff:ff
5: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 52:54:00:61:75:8c brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever
6: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master virbr0 state DOWN group default qlen 1000
    link/ether 52:54:00:61:75:8c brd ff:ff:ff:ff:ff:ff
7: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 70:85:c2:69:67:9a brd ff:ff:ff:ff:ff:ff
    inet 192.168.11.8/24 brd 192.168.11.255 scope global dynamic noprefixroute br0
       valid_lft 172707sec preferred_lft 172707sec
    inet6 2408:211:ba5:d600:b549:6323:c459:f7da/64 scope global temporary dynamic 
       valid_lft 604709sec preferred_lft 85766sec
    inet6 2408:211:ba5:d600:8ca7:6b74:9cac:5f58/64 scope global dynamic mngtmpaddr noprefixroute 
       valid_lft 2591909sec preferred_lft 604709sec
    inet6 fe80::f981:6edd:d21:845f/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

$ brctl show
bridge name	bridge id		STP enabled	interfaces
br0		8000.7085c269679a	yes		enp7s0
virbr0		8000.52540061758c	yes		virbr0-nic
```

## KVMのゲストOSをブリッジに接続する

現在のゲストOSのインターフェースvnet0はvirtbr0に接続されています。これをbr0に接続するように変更します。

```
$ brctl show
bridge name	bridge id		STP enabled	interfaces
br0		8000.7085c269679a	yes		enp7s0
virbr0		8000.52540061758c	yes		virbr0-nic
							vnet0
```

仮想マシンマネージャのメニューから編集-->仮想マシンの詳細を選択する。表示されたウィンドウのメニューの表示-->詳細を選択すると次のような画面になります。左のNICの項目を選択するとデフォルトではNAT接続されていることがわかります。これを先ほど作成したブリッジbr0に変更します。ネットワークソースを共有デバイス名を指定に変更して、ブリッジ名に先ほど作成したブリッジ名br0を指定して適用します。

![network_interface_setting.png](https://qiita-image-store.s3.amazonaws.com/0/271649/1bf98b55-9330-e330-ed89-f80dedfd5222.png)

![network_interface_setting2.png](https://qiita-image-store.s3.amazonaws.com/0/271649/25afee12-d0aa-1931-11f4-b40645648937.png)

もう一度ブリッジ情報を表示すると、vnet0がbr0に接続されたことが確認できます。

```
$ brctl show
bridge name	bridge id		STP enabled	interfaces
br0		8000.7085c269679a	yes		enp7s0
							vnet0
virbr0		8000.52540061758c	yes		virbr0-nic
```

# ゲストOS

ゲストOSからIPアドレスを確認するとホストPCと同じネットワークに接続されていることが確認できました。

```
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:2c:7f:3d brd ff:ff:ff:ff:ff:ff
    inet 192.168.11.10/24 brd 192.168.11.255 scope global noprefixroute dynamic eth0
       valid_lft 172756sec preferred_lft 172756sec
```