8
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

OpenVNetとDockerを組み合わせてみるデモ(分散vna)

Last updated at Posted at 2015-01-11

概要

  • 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のインストール自体は前回と大体同様だが、インストール後にいくつか設定を直すところがある。

/etc/redis.conf
(省略)
bind 0.0.0.0
(省略)

redisは他のvnaからも参照されるため、外から接続可能にしておく必要がある。
※mysqlとredisはvnmgrと同じホストに存在する必要はなく、外部に置いた場合はcommon.confで接続先を変更すれば良いが、mysqlはlocalhost以外から接続可能なようにユーザを設定する必要がある。

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

vna.confのポイントはidで、名前の通り一意にしておく必要がある。

OpenVNetのインストール(Host2)

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

/etc/openvnet/vna.conf
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はバッティングしない値にしておく。

/etc/sysconfig/network-scripts/ifcfg-eth1(Host1、2共通)
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
"

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

Host1
$ service mysqld start
$ service redis start
$ ifup eth1
$ initctl start vnet-vnmgr
$ initctl start vnet-webapi
$ initctl start vnet-vna
Host2
$ ifup eth1
$ initctl start vnet-vna

コンテナの起動

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

openvnet-demo-init.sh(Host1)
#!/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
openvnet-demo-init.sh(Host2)
#!/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

シェルスクリプトをそれぞれのホストで実行すると、以下のような結果が出力される。

Host1
$ ./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
Host2
$ ./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の中身は、以下のようになる。

netconfig.env(Host1)
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
netconfig.env(Host2)
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は以下のようになる。

db.sh(Host1)
#!/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=
8
8
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?