OpenVNetとDockerを組み合わせてみるデモ（L2延伸）


概要
----

* OpenVNetをdockerとあわせて動かしてみる。
* 今回もまだ既存ネットワークとは通信なしでVNET間もルーティングはしないが、前回のものに加え、アンダーレイが複数のセグメントに跨った状態で仮想ネットワークを構成。

前提
----

[ほぼ前回の記事](http://qiita.com/qb0c80aE/items/8bdd22d104b06657fd89)と同じだが、public networkを2つを作る点が異なる。

Dockerイメージは引き続きcentos_sshdを利用する。

### 環境

CentOS6.6のVM3台をホスト（Host1、Host2、Host3とする）として、Host1とHost2を同一セグメント内に、Host3を別セグメントに配置する。
※今回は6.6で試した。また、このCentOSを動かしているHypervisorはKVM

また、それぞれのホストにNICは2枚あり、

* Host1：
  * eth0：ssh、OpenVNetの管理で利用（192.168.122.50）
  * eth1：OpenVNetでPublic Network1用に利用
* Host2：
  * eth0：ssh、OpenVNetの管理で利用（192.168.122.51）
  * eth1：OpenVNetでPublic Network1用に利用
* Host3：
  * eth0：ssh、OpenVNetの管理で利用（192.168.122.52）
  * eth1：OpenVNetでPublic Network2用に利用

となっている。

文章だけだとわかりにくいので公式の図を引用すると、

![今回の構成](https://github.com/axsh/openvnet/wiki/images/scenario.jpg)

の、VM1～VM6がdockerのコンテナというもの。もうちょとわかりやすくすると、

![図1.png](https://qiita-image-store.s3.amazonaws.com/0/45715/1c604151-5ee6-9e7c-c983-14fa2609e329.png)

こんな感じ。

作業の流れ
---------

今回も[InstallGuite](https://github.com/axsh/openvnet/blob/master/docs/InstallGuide.md) に則って大体インストールしていくが、

* Host1はAll-in-One構成（vnmgr、webapi、vnaすべてが同じホストにある）
* Host2、Host3はvnaだけインストール
* Host1の上にVNET1に属するContainer1と、VNET2に属するContainer2を起動
* Host2の上にVNET1に属するContainer3と、VNET2に属するContainer4を起動
* Host3の上にVNET1に属するContainer5と、VNET2に属するContainer6を起動

という形態で動作させて、それぞれのVNET内のコンテナ同士が疎通できるか確かめる。
※Host1、2、3を動かしているHypervisorはKVM

ネットワークに関しては、前回同様docker0は放っておいてbr0をOVSでつくり、それを利用する形にする。コンテナのNIC追加は、pipeworkは使わず、netnsにvethを放り込む形にする。

2つのホストは同一セグメント、1つのホストは別セグメントに存在するが、MAC2MACとGREでお互いのホストのコンテナと通信ができれば良いので、Routerの設定は不要。

また、今回はCentOS6.6で動かしたと書いたが、CentOS6.5以上でInstallGuideに従ってOpenVNetをインストールした場合、/var/log/openvswitch/ovs-vswitchd.logに"Address family not supported by protocol. "が出力され、OVSにGREポートが作成できない。ovs-ofctl show brXで表示した場合はGREポートが表示されないが、ovs-vsctl showで見ると存在しないはずのGREポートが表示されるため、やや気付きにくい。
これを回避するため、[この情報](https://twitter.com/hansode/status/557218470719279104)と、[この情報](https://twitter.com/hansode/status/557218992192892929)、および[この辺の情報](https://twitter.com/hansode/status/557224784220549120)を参考にOpen vSwitchのバージョンを上げておく。

### OpenVNetのインストール（Host1）

Host1のインストール自体は前回と同様で、redisが外部から接続を受け付けるようにしておくこと。

```/etc/redis.conf
（省略）
bind 0.0.0.0
（省略）
```

```/etc/openvnet/vna.conf（Host1）
node {
  id "vna1"
  addr {
    protocol "tcp"
    host "192.168.122.51"
    port 9103
  }
}
```

vna.confのidは、一意の値にしておく。

### OpenVNetのインストール（Host2、Host3）

Host2、host3はvnaだけインストールすればいい。全部インストールした上でvnaしか使わない、としても良い。
こちらも設定を一部修正する。

```/etc/openvnet/vna.conf（Host2）
node {
  id "vna2"
  addr {
    protocol "tcp"
    host "192.168.122.51"
    port 9103
  }
}
```

```/etc/openvnet/vna.conf（Host3）
node {
  id "vna3"
  addr {
    protocol "tcp"
    host "192.168.122.52"
    port 9103
  }
}
```

同様に、idをバッティングしない値に変更しておく。

### br0の作成

ここも前回と同じように、eth1をbr0にOVSPortとして追加する形で設定する。
Host1のbr0とHost2のbr0のdatapath-id、hwaddrはバッティングしない値にしておく。

```bash:/etc/sysconfig/network-scripts/ifcfg-eth1（Host1、2、3共通）
DEVICE=eth1
DEVICETYPE=ovs
TYPE=OVSPort
OVS_BRIDGE=br0
BOOTPROTO=none
ONBOOT=yes
HOTPLUG=no
```

```bash:/etc/sysconfig/network-scripts/ifcfg-br0（Host1）
DEVICE=br0
DEVICETYPE=ovs
TYPE=OVSBridge
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.121.50
NETMASK=255.255.255.0
HOTPLUG=no
OVS_EXTRA="
 set bridge     ${DEVICE} protocols=OpenFlow10,OpenFlow12,OpenFlow13 --
 set bridge     ${DEVICE} other_config:disable-in-band=true --
 set bridge     ${DEVICE} other-config:datapath-id=0000000000000001 --
 set bridge     ${DEVICE} other-config:hwaddr=02:01:00:00:00:01 --
 set-fail-mode  ${DEVICE} standalone --
 set-controller ${DEVICE} tcp:127.0.0.1:6633
"
```

```bash:/etc/sysconfig/network-scripts/ifcfg-br0（Host2）
DEVICE=br0
DEVICETYPE=ovs
TYPE=OVSBridge
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.121.51
NETMASK=255.255.255.0
HOTPLUG=no
OVS_EXTRA="
 set bridge     ${DEVICE} protocols=OpenFlow10,OpenFlow12,OpenFlow13 --
 set bridge     ${DEVICE} other_config:disable-in-band=true --
 set bridge     ${DEVICE} other-config:datapath-id=0000000000000002 --
 set bridge     ${DEVICE} other-config:hwaddr=02:01:00:00:00:02 --
 set-fail-mode  ${DEVICE} standalone --
 set-controller ${DEVICE} tcp:127.0.0.1:6633
"
```

```bash:/etc/sysconfig/network-scripts/ifcfg-br0（Host3）
DEVICE=br0
DEVICETYPE=ovs
TYPE=OVSBridge
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.120.52
NETMASK=255.255.255.0
HOTPLUG=no
OVS_EXTRA="
 set bridge     ${DEVICE} protocols=OpenFlow10,OpenFlow12,OpenFlow13 --
 set bridge     ${DEVICE} other_config:disable-in-band=true --
 set bridge     ${DEVICE} other-config:datapath-id=0000000000000003 --
 set bridge     ${DEVICE} other-config:hwaddr=02:01:00:00:00:03 --
 set-fail-mode  ${DEVICE} standalone --
 set-controller ${DEVICE} tcp:127.0.0.1:6633
"
```


設定が完了したらそれぞれのホストのbr0を起動して、Host1ではvnmgr・webapi・vnaを、Host2、Host3ではvnaを起動する。

```bash:Host1
$ service mysqld start
$ service redis start
$ ifup eth1
$ initctl start vnet-vnmgr
$ initctl start vnet-webapi
$ initctl start vnet-vna
```

```bash:Host2、Host3
$ ifup eth1
$ initctl start vnet-vna
```
### コンテナの起動

Host1ではContainer1と2、Host2ではContainer3と4、Host3ではContainer5と6を起動する。

OpenVNetはセグメントの異なるホストの間をGREで繋いでくれる。このGREにはOVSのGREポートが利用されるが、このポートに対してoutputのflowが適用された場合、パケットはホストのLinuxのIPスタックを経て送出される形になる。そのため、br0（のeth1）から送出して相手に到達可能になるよう、ルーティングを設定している。
※ルー