openvswitchのvxlanで、KVM(libvirt)ホストの仮想ネットワークを接続する

ネタとしては全く今更な内容なのですが、自分用メモとして。

以下は、以前の私の自宅のネットワークの大雑把なイメージです。（必要な部分だけ）。

|![vxlan_1.png](https://qiita-image-store.s3.amazonaws.com/0/157891/94c02611-1897-05fe-9843-dfaecec5f3e4.png)|
|:-:|

各KVM Host内では、複数の仮想マシンが複数のVLANを使ってネットワークを作っています。この仮想マシンには、勉強（検証）用だけでなく、インターネットに接続するためのルータやFirewallも含まれてます。（書いてませんが、論理構成ではネットワークが分離されてます。）

これを、次のように変更しました。

|![vxlan_2.png](https://qiita-image-store.s3.amazonaws.com/0/157891/37338d28-80cb-2fdb-3069-12bdf0c14345.png)|
|:-:|

変更の多い（勉強用）仮想スイッチと、安定して動作させたい仮想スイッチを分け、前者についてはVXLANで接続します。
これで、勉強用にVLANを追加・変更したい際は、赤枠の仮想スイッチをいじれば良いだけとなりました。

このページでは、この構成変更を行った際の手順を記載します。

# 環境
KVM Host OS: CentOS 7.4
openvswitch: v2.6.1
libvirt: v3.2.0

# 手順
操作は、全て、両方のKVM Hostで行います。

## 仮想スイッチの作成

まず、現状の確認。

```bash
$ ovs-vsctl show 

    Bridge "ovsbr0"
　　　　　・
　　　　　・
　　　　　・
        Port "ovsbr0"
            Interface "ovsbr0"
                type: internal

```

現在、仮想スイッチは ovsbr0 のみ。

そこで、vxlan用に ovsvbr1 という名前の仮想スイッチを追加することにする。

```bash
$ ovs-vsctl add-br ovsbr1

```

仮想スイッチが作成されたことを確認する。

```bash
$ ovs-vsctl show 

    Bridge "ovsbr0"
　　　　　・
　　　　　・
　　　　　・
        Port "ovsbr0"
            Interface "ovsbr0"
                type: internal
    Bridge "ovsbr1"
        Port "ovsbr1"
            Interface "ovsbr1"
                type: internal

```

今後、再起動時には、起動時に自動的にこの仮想スイッチが作成されるよう network-scripts ファイルも作成する。

```bash
$ vi /etc/sysconfig/network-scripts/ifcfg-ovsbr1 
-------------
DEVICE=ovsbr1
NAME=ovsbr1
BOOTPROTO=none
ONBOOT=yes
DEVICETYPE=ovs
IPV6INIT=no
TYPE=OVSBridge
-------------

```

## vxlan用仮想ポートの作成
作成した仮想スイッチに、vxlan用の仮想ポートを作成する。

```bash
# (KVM Host1)

$ ovs-vsctl add-port ovsbr1 vxlan0 -- set Interface vxlan0 type=vxlan options:key=flow options:local_ip="KVM_Host1のIPアドレス" options:remote_ip="KVM_Host2のIPアドレス"

```

```bash
# (KVM Host2)

$ ovs-vsctl add-port ovsbr1 vxlan0 -- set Interface vxlan0 type=vxlan options:key=flow options:local_ip="KVM_Host2のIPアドレス" options:remote_ip="KVM_Host1のIPアドレス"

```

vxlan用ポート "vxlan0" が追加されたことを確認する。

```bash
# (以下のサンプルはKVM Host1のみ。KVM Host2でも同様に確認すること)

$ ovs-vsctl show 
    Bridge "ovsbr0"
　　　　　・
　　　　　・
　　　　　・
        Port "ovsbr0"
            Interface "ovsbr0"
                type: internal
    Bridge "ovsbr1"
        Port "vxlan0"
            Interface "vxlan0"
                type: vxlan
                options: {key=flow, local_ip="KVM_HOST1のIPアドレス", remote_ip="KVM_HOST2のIPアドレス"}
        Port "ovsbr1"
            Interface "ovsbr1"
                type: internal
```

## Firewalldの許可
CentOS標準のfirewalldが有効な場合、VXLANの通信（4879/udp）は許可されていないため、通信を許可する。

```bash
$ firewall-cmd --add-port=4789/udp --permanent
success

$ firewall-cmd --add-port=4789/udp 
success
```

## libvitdの仮想ネットワーク作成

作成する仮想ネットワークは、作成した仮想スイッチ（ovsbr1）とブリッジさせる。
まず、作成したい仮想ネットワークを定義したXMLファイルを用意する。

```bash

$ vi ovs-vxlan.xml 
--------------------------------------------
<network>
  <name>ovs-vxlan</name>
  <forward mode='bridge'/>
  <bridge name='ovsbr1'/>
  <virtualport type='openvswitch'/>
  <portgroup name='vlan_10'>
    <vlan>
      <tag id='10'/>
    </vlan>
  </portgroup>
  <portgroup name='vlan_20'>
    <vlan>
      <tag id='20'/>
    </vlan>
  </portgroup>
  <portgroup name='vlan_30'>
    <vlan>
      <tag id='30'/>
    </vlan>
  </portgroup>
  <portgroup name='vlan_40'>
    <vlan>
      <tag id='40'/>
    </vlan>
  </portgroup>
  <portgroup name='vlan_all'>
    <vlan trunk='yes'>
      <tag id='10'/>
      <tag id='20'/>
      <tag id='30'/>
      <tag id='40'/>
    </vlan>
  </portgroup>
</network>
--------------------------------------------
```

次に、作成したMLファイルを元に、仮想ネットワークを定義する。

```bash
$ virsh net-define ovs-vxlan.xml 

```

定義した仮想ネットワークを有効にする。

```bash
$ virsh net-start ovs-vxlan

```

設定はこれで完了。

# 確認
両方のKVM Hostで、vxlanで接続した仮想スイッチ内の同一VLANで通信ができることを確認する。

また、KVM Hostを再起動して、起動後、自動的に同じ設定になること、vxlanを通した通信が行えることを確認する。