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


概要

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

前提

ほぼ前回の記事と同じだが、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用に利用

となっている。

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

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

こんな感じ。

作業の流れ

今回もInstallGuite に則って大体インストールしていくが、

  • 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ポートが表示されるため、やや気付きにくい。
これを回避するため、この情報と、この情報、およびこの辺の情報を参考に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はバッティングしない値にしておく。

/etc/sysconfig/network-scripts/ifcfg-eth1(Host1、2、3共通)
DEVICE=eth1
DEVICETYPE=ovs
TYPE=OVSPort
OVS_BRIDGE=br0
BOOTPROTO=none
ONBOOT=yes
HOTPLUG=no
/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
"
/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
"
/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を起動する。

Host1
$ service mysqld start
$ service redis start
$ ifup eth1
$ initctl start vnet-vnmgr
$ initctl start vnet-webapi
$ initctl start vnet-vna
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)から送出して相手に到達可能になるよう、ルーティングを設定している。
※ルー