概要
- OpenVNetをdockerとあわせて動かしてみる。
- 今回もまだ既存ネットワークとは通信なしでVNET間もルーティングはしないが、前回のものを拡張し、複数ホストのDockerコンテナ間で仮想ネットワークを構成。
前提
ほぼ前回の記事と同じだが、
- redisをすべてのホストから見えるようにしていたり
- vnaをそれぞれのホストで構成したり
- public networkを作ったり
- VMからbroadcastしてホストから出る時にunicastに変換される際のMACを定義したり
といった点が異なる。
Dockerイメージは引き続きcentos_sshdを利用する。
環境
CentOS6.5のVM2台をホスト(Host1、Host2とする)として、同一セグメント内に配置する。
※このCentOSを動かしているHypervisorはKVM
また、それぞれのホストにNICは2枚あり、
- Host1:
- eth0:ssh、OpenVNetの管理で利用(192.168.122.50)
- eth1:OpenVNetでPublic Network用に利用
- Host2:
- eth0:ssh、OpenVNetの管理で利用(192.168.122.51)
- eth1:OpenVNetでPublic Network用に利用
となっている。
作業の流れ
今回もInstallGuite に則って大体インストールしていくが、
- Host1はAll-in-One構成(vnmgr、webapi、vnaすべてが同じホストにある)
- Host2はvnaだけインストール
- Host1の上にVNET1に属するContainer1と、VNET2に属するContainer2を起動
- Host2の上にVNET1に属するContainer3と、VNET2に属するContainer4を起動
という形態で動作させて、それぞれのVNET内のコンテナ同士が疎通できるか確かめる。
※Host1、2を動かしているHypervisorはKVM
で動かす。
ネットワークに関しては、前回同様docker0は放っておいてbr0をOVSでつくり、それを利用する形にする。コンテナのNIC追加は、pipeworkは使わず、netnsにvethを放り込む形にする。
2つのホストは同一セグメントに存在し、MAC2MACで隣のホストのコンテナと通信ができれば良いので、Routerの設定は不要。
OpenVNetのインストール(Host1)
Host1のインストール自体は前回と大体同様だが、インストール後にいくつか設定を直すところがある。
(省略)
bind 0.0.0.0
(省略)
redisは他のvnaからも参照されるため、外から接続可能にしておく必要がある。
※mysqlとredisはvnmgrと同じホストに存在する必要はなく、外部に置いた場合はcommon.confで接続先を変更すれば良いが、mysqlはlocalhost以外から接続可能なようにユーザを設定する必要がある。
node {
id "vna1"
addr {
protocol "tcp"
host "192.168.122.51"
port 9103
}
}
vna.confのポイントはidで、名前の通り一意にしておく必要がある。
OpenVNetのインストール(Host2)
Host2はvnaだけインストールすればいい。全部インストールした上でvnaしか使わない、としても良い。
こちらも設定を一部修正する。
node {
id "vna2"
addr {
protocol "tcp"
host "192.168.122.51"
port 9103
}
}
同様に、idをバッティングしない値に変更しておく。
br0の作成
ここも前回と同じように、eth1をbr0にOVSPortとして追加する形で設定する。
Host1のbr0とHost2のbr0のdatapath-id、hwaddrはバッティングしない値にしておく。
DEVICE=eth1
DEVICETYPE=ovs
TYPE=OVSPort
OVS_BRIDGE=br0
BOOTPROTO=none
ONBOOT=yes
HOTPLUG=no
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
"
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
"
設定が完了したらそれぞれのホストのbr0を起動して、Host1ではvnmgr・webapi・vnaを、Host2ではvnaを起動する。
$ service mysqld start
$ service redis start
$ ifup eth1
$ initctl start vnet-vnmgr
$ initctl start vnet-webapi
$ initctl start vnet-vna
$ ifup eth1
$ initctl start vnet-vna
コンテナの起動
Host1ではContainer1と2、Host2ではContainer3と4を起動する。
#!/bin/sh
BRIDGE=br0
DOCKER_PID=`ps -ef | grep docker | grep -v grep | awk '{print $2}'`
DOCKER_IMAGE="centos_sshd"
IP_ADDRESSES=("10.102.0.10/24" "10.102.0.10/24")
rm -f ./netconfig.env
mkdir -p /var/run/netns/
for i in `seq 1 ${#IP_ADDRESSES[@]}`; do
let address_index=$i-1
CONTAINER_ID=`docker run --hostname="container${i}" --net="none" -i -t -d ${DOCKER_IMAGE} /bin/bash`
BASH_PID=`docker inspect --format {{.State.Pid}} ${CONTAINER_ID}`
ln -s /proc/${BASH_PID}/ns/net /var/run/netns/${BASH_PID}
ip link add veth${i}-1 type veth peer name veth${i}-2
ip link set veth${i}-1 up
ip link set veth${i}-2 netns ${BASH_PID}
ip netns exec ${BASH_PID} ip link set veth${i}-2 up
ip netns exec ${BASH_PID} ip addr add ${IP_ADDRESSES[${address_index}]} dev veth${i}-2
ovs-vsctl add-port ${BRIDGE} veth${i}-1
hwaddr=`ip netns exec ${BASH_PID} ip link show veth${i}-2 | awk 'NR==2' | awk '{print $2}'`
ipaddr=`echo "${IP_ADDRESSES[${address_index}]}" | awk -F/ '{print $1}'`
netmask=`echo "${IP_ADDRESSES[${address_index}]}" | awk -F/ '{print $2}'`
echo "veth${i}-2 ${IP_ADDRESSES[${address_index}]} ${hwaddr}"
echo "export mac_veth${i}2=${hwaddr}" >> ./netconfig.env
echo "export ip_veth${i}2=${ipaddr}" >> ./netconfig.env
echo "export netmask_veth${i}2=${netmask}" >> ./netconfig.env
done
#!/bin/sh
BRIDGE=br0
DOCKER_PID=`ps -ef | grep docker | grep -v grep | awk '{print $2}'`
DOCKER_IMAGE="centos_sshd"
IP_ADDRESSES=("10.102.0.11/24" "10.102.0.11/24")
rm -f ./netconfig.env
mkdir -p /var/run/netns/
for i in `seq 1 ${#IP_ADDRESSES[@]}`; do
let address_index=$i-1
let j=$i+2
CONTAINER_ID=`docker run --hostname="container${j}" --net="none" -i -t -d ${DOCKER_IMAGE} /bin/bash`
BASH_PID=`docker inspect --format {{.State.Pid}} ${CONTAINER_ID}`
ln -s /proc/${BASH_PID}/ns/net /var/run/netns/${BASH_PID}
ip link add veth${j}-1 type veth peer name veth${j}-2
ip link set veth${j}-1 up
ip link set veth${j}-2 netns ${BASH_PID}
ip netns exec ${BASH_PID} ip link set veth${j}-2 up
ip netns exec ${BASH_PID} ip addr add ${IP_ADDRESSES[${address_index}]} dev veth${j}-2
ovs-vsctl add-port ${BRIDGE} veth${j}-1
hwaddr=`ip netns exec ${BASH_PID} ip link show veth${j}-2 | awk 'NR==2' | awk '{print $2}'`
ipaddr=`echo "${IP_ADDRESSES[${address_index}]}" | awk -F/ '{print $1}'`
netmask=`echo "${IP_ADDRESSES[${address_index}]}" | awk -F/ '{print $2}'`
echo "veth${j}-2 ${IP_ADDRESSES[${address_index}]} ${hwaddr}"
echo "export mac_veth${j}2=${hwaddr}" >> ./netconfig.env
echo "export ip_veth${j}2=${ipaddr}" >> ./netconfig.env
echo "export netmask_veth${j}2=${netmask}" >> ./netconfig.env
done
シェルスクリプトをそれぞれのホストで実行すると、以下のような結果が出力される。
$ ./openvnet-demo-init.sh
veth1-2 10.102.0.10/24 32:92:dd:d4:b0:c4
veth2-2 10.102.0.10/24 a6:06:59:b2:99:da
$ ./openvnet-demo-init.sh
veth3-2 10.102.0.11/24 ca:9c:32:da:37:65
veth4-2 10.102.0.11/24 96:3e:bf:1d:ee:0a
netconfig.envの中身は、以下のようになる。
export mac_veth12=32:92:dd:d4:b0:c4
export ip_veth12=10.102.0.10
export netmask_veth12=24
export mac_veth22=a6:06:59:b2:99:da
export ip_veth22=10.102.0.10
export netmask_veth22=24
export mac_veth32=ca:9c:32:da:37:65
export ip_veth32=10.102.0.11
export netmask_veth32=24
export mac_veth42=96:3e:bf:1d:ee:0a
export ip_veth42=10.102.0.11
export netmask_veth42=24
OpenVNetのAPIで仮想ネットワーク設定
webapiを利用して仮想ネットワーク設定を行う。
今回のdb.shは以下のようになる。
#!/bin/sh
set -e
set -x
mysqladmin -f -uroot drop vnet
mysqladmin -uroot create vnet
(cd /opt/axsh/openvnet/vnet; bundle exec rake db:init)
export vnmgr_host=192.168.122.50
export vnmgr_port=9090
# 上記のコンテナを作成するシェルスクリプトで出力される、
# コンテナのNIC情報を出力したファイル
. ./netconfig.env
# datapaths
curl -X POST \
--data-urlencode uuid=dp-node1 \
--data-urlencode display_name="vna1" \
--data-urlencode dpid="0x0000000000000001" \
--data-urlencode node_id="vna1" \
http://${vnmgr_host}:${vnmgr_port}/api/datapaths
# networks
curl -s -X POST \
--data-urlencode uuid=nw-pub \
--data-urlencode display_name="nw-pub" \
--data-urlencode ipv4_network="192.168.121.0" \
--data-urlencode ipv4_prefix="24" \
--data-urlencode network_mode="physical" \
http://${vnmgr_host}:${vnmgr_port}/api/networks
curl -X POST \
--data-urlencode uuid=nw-vnet1 \
--data-urlencode display_name="nw-vnet1" \
--data-urlencode ipv4_network="10.100.0.0" \
--data-urlencode ipv4_prefix="24" \
--data-urlencode network_mode=