OpenFlowは、1台のOpenFlowコントローラで複数のOpenFlowスイッチを制御する
仕組みです。OpenFlowスイッチは転送機能を提供します。OpenFlowコントロー
ラは経路制御をまとめて行います。OpenFlowスイッチは必要に応じて経路情報
をOpenFlowコントローラに問い合わせる形となります。OpenFlowコントローラ
とOpenFlowスイッチ間はOpenFlowプロトコルで通信が行われます。
Open vSwitchはオープンソースの仮想ソフトウェアスイッチで、XenServer,
KVM, VirtualBoxなどの仮想化プラットフォームでも使用されています。
Open vSwitchは仮想化プラットフォームと組み合わせなくても普通のLinux上で
動作可能です。Linux上で動作させる場合はユーザ空間でのパケット転送処理の
他にカーネルモジュールを利用して高速にパケット転送処理を行うことも可能
です。
またOpen vSwitchは設定によりOpenFlowに対応したOpenFlowスイッチとしての
動作も可能となっています。
◆動向/必要性
OpenFlow 1.0仕様は2009年12月、OpenFlow 1.1仕様は2011年2月にそれぞれリリー
スされました。2011年12月にIPv6のサポートなどが追加されたOpenFlow 1.2仕
様がONF(Open Networking Foundation)で承認されました。1.2はまだ出たばか
りなので現状では1.0/1.1が主流となっています。
OpenFlowは技術的には比較的新しく、またセキュリティ上の懸念なども議論さ
れていたりなどまだ実用段階には至っていません。一方、集中制御できること
から大規模データセンターなどでの利用が期待されています。
このようにOpenFlowは大規模データセンターなどをおもなターゲットとして検
討されているようですが、L2〜L4の情報に基いて細かい制御が可能ということ
で比較的小規模のネットワーク環境で効果的に使える可能性も考えられます。
Open vSwitchではバージョン1.4.0(2012年1月リリース)でOpenFlow 1.0
に加え、OpenFlow 1.1/1.2の一部の機能(IPv6など)に対応しています。
◆Open vSwitch導入
OpenBlockS 600DにOpen vSwitchを導入してみます。
まずはOpenBlockS 600Dでセルフ開発環境を整えます。
今回は、ファームウェア、および開発環境として以下を用いました。
ftp://ftp.plathome.co.jp/pub/OBS600/debian/files/squeeze/2.6.29-4/uImage.initrd.squeezeパッケージはaptitude upgradeで2012年2月21日時点での最新版にしました。
ftp://ftp.plathome.co.jp/pub/OBS600/debian/files/squeeze/obs600d_squeeze_develop_edition_20110726.tgz
# aptitude updateまたopenvswitchコンパイルのための準備としてlibssl-dev, pkg-configパッケー
# aptitude safe-upgrade
ジを追加しました。
# aptitude install libssl-dev pkg-configopenvswitchでは、転送処理をカーネル(モジュール)で行う方法とユーザランド
で行う方法の2通りがありコンパイル時に選択します。今回は準備が多少面倒で
すが性能が出るであろう前者のカーネルモジュールを選択することにします。
カーネルモジュールを作成するためにモジュール生成のための環境が必要とな
るので、まずはその準備をします。
開発環境でカーネルのソースはすでに入っていますが、最新のファームと同じ
環境にするために、最新ファーム用のカーネルソースを取得します。
# cd /usr/srcモジュール生成時にはautoconf.h等が必要になるためその準備をします。今回
# wget ftp://ftp.plathome.co.jp/pub/OBS600/debian/linux/linux-2.6.29-20111128-00.tgz
# mv linux-2.6.29 linux-2.6.29.old
# tar xvf linux-2.6.29-20111128-00.tgz
はモジュールシンボル(Module.symvers)も生成したかったのでmake modulesま
で行いました。make vmlinux modulesは数時間を要します。確認はしていませ
んがmake prepareまで行えばopenvswitchはコンパイル可能かもしれません。
# cd /usr/src/linuxさて、これで準備は整ったのでようやくopenvswitchソフトウェアのコンパイル
# wget -O /usr/src/linux/.config ftp://ftp.plathome.co.jp/pub/OBS600/debian/files/lenny/LATEST/dot.config
# cd /usr/src/linux/include
# rm asm
# ln -s /usr/src/linux/arch/powerpc/include/asm .
# make oldconfig
# make prepare
# make vmlinux modules
にうつります。まずは2012年2月21日時点での最新版(1.4.0)のソースを取得し
展開します。
# wget http://openvswitch.org/releases/openvswitch-1.4.0.tar.gzpowerpcではオリジナルのままだと一ヶ所だけ関数未定義でコンパイルを通らな
# tar zxvf openvswitch-1.4.0.tar.gz
い箇所があるため以下の修正を加えました。
--- datapath/tunnel.c.orig 2012-01-31 16:08:18.000000000 +0900次にopenvswitchのmakeを行う。
+++ datapath/tunnel.c 2012-02-22 17:53:23.000000000 +0900
@@ -38,6 +38,7 @@
#include <net/ip.h>
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
#include <net/ipv6.h>
+#include <net/ip6_checksum.h>
#endif
#include <net/route.h>
#include <net/xfrm.h>
# cd openvswitch-1.4.0makeが問題なく通ったらmake installを行います。デフォルトでは/usr/local
# ./configure --with-linux=/lib/modules/`uname -r`/build
# make
以下にインストールされます。さらに作成したモジュールをinsmodします。
# make install特にエラーメッセージ等が出なければ準備完了となります。
# insmod datapath/linux/openvswitch_mod.ko
◆構成と設定ファイル初期化
各種設定は設定用のデータベースで管理されます。データベースへのアクセス
はデータベースアクセス用デーモン(ovsdb-server) を通してアクセスされます。
その他のツールはovsdb-serverと通信して動作を行います。今回はunix domainsocketを用いる設定にしました。
ovs-vswitchdはスイッチのデータパスの設定等を行うメインのデーモンです。
ovs-vsctlはスイッチ関連の各種設定を行うコマンドです。
まずは、初期化を行います。
設定ファイル用のディレクトリを作成し、データベースを新たに作成します。
データベースはovsdb-toolコマンドを用いて生成します。
# mkdir -p /usr/local/etc/openvswitch次にデータベースを操作するためのサーバを起動します。
# ovsdb-tool create /usr/local/etc/openvswitch/conf.db vswitchd/vswitch.ovsschema
Feb 22 09:50:54|00001|lockfile|INFO|/usr/local/etc/openvswitch/.conf.db.~lock~: lock file does not exist, creating
データベースサーバへはunix domain socket(db.sock)を通してアクセスします。
# ovsdb-server --remote=punix:/usr/local/var/run/openvswitch/db.sock \ovs-vsctlコマンドでデータベースの初期化を行います。
--remote=db:Open_vSwitch,manager_options \
--private-key=db:SSL,private_key \
--certificate=db:SSL,certificate \
--bootstrap-ca-cert=db:SSL,ca_cert \
--pidfile --detach
# ovs-vsctl --no-wait initopen vswitchのメインサーバ ovs-vswitchdを起動します。
# ovs-vswitchd --pidfile --detach
Feb 22 09:54:27|00001|reconnect|INFO|unix:/usr/local/var/run/openvswitch/db.sock: connecting...
Feb 22 09:54:27|00002|reconnect|INFO|unix:/usr/local/var/run/openvswitch/db.sock: connected
◆Open vSwitch基本動作確認
最も単純なeth0, eth1 をブリッジさせる動作を確認します。
まずはブリッジデバイスを作成します。
# ovs-vsctl add-br br0次に、eth0, eth1 をこのブリッジのポートして追加します。
device br0 entered promiscuous mode
# ifconfig br0
br0 Link encap:Ethernet HWaddr fe:b2:9d:a2:84:45
BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
# ovs-vsctl add-port br0 eth0br0をupするとブリッジ動作を行うようになります。
device eth0 entered promiscuous mode
# ovs-vsctl add-port br0 eth1
device eth1 entered promiscuous mode
# ifconfig br0 upovs-vsctlコマンドでブリッジの情報を確認できます。
# ovs-vsctl showなお、注意点としてopenvswitchを導入したマシンでsshなどのIP通信を行うに
a54365a7-c6a5-43b0-b920-bf56e53f37f5
Bridge "br0"
Port "eth1"
Interface "eth1"
Port "br0"
Interface "br0"
type: internal
Port "eth0"
Interface "eth0"
は、eth0, eth1ではなくbr0にIPアドレスをふる必要があります。
試しにDHCPでアドレスをふってみます。
# dhclient br0動作確認のため3台のOpenBlockS 600D(OBS600D)を用いて以下のネットワークを構成しました。
# ifconfig br0
br0 Link encap:Ethernet HWaddr 00:0a:85:04:15:5f
inet addr:192.168.100.211 Bcast:192.168.100.255 Mask:255.255.255.0
inet6 addr: fe80::20a:85ff:fe04:155f/64 Scope:Link
UP BROADCAST RUNNING ALLMULTI MULTICAST MTU:1500 Metric:1
RX packets:833632 errors:0 dropped:0 overruns:0 frame:0
TX packets:52700 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:90350673 (86.1 MiB) TX bytes:18998763 (18.1 MiB)
obs600-3は上記でopenvswitchを導入済のマシンです。
openvswitchのブリッジが動作をしているかをobs600-1からobs600-2へのpingで
確認します。
obs600-1# ping 192.168.100.219openvswitchでは一方向のデータパスのテーブルをもとにスイッチングを行って
PING 192.168.100.219 (192.168.100.219) 56(84) bytes of data.
64 bytes from 192.168.100.219: icmp_req=1 ttl=64 time=116 ms
64 bytes from 192.168.100.219: icmp_req=2 ttl=64 time=0.366 ms
64 bytes from 192.168.100.219: icmp_req=3 ttl=64 time=0.307 ms
64 bytes from 192.168.100.219: icmp_req=4 ttl=64 time=0.368 ms
います。データパスの情報を確認するにはovs-dpctlを用います。
# ovs-dpctl showbr0のデータパスを確認してみます。
system@br0:
lookups: hit:2284446 missed:151252 lost:86
flows: 6
port 0: br0 (internal)
port 1: eth0
port 2: eth1
# ovs-dpctl dump-flows br0 |grep 192.168.100.123eth1側からの入力はin_port(2)に対応し、arpおよびICMP echo request
in_port(2),eth(src=00:0a:85:04:93:99,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=192.168.100.123,tip=192.168.100.219,op=1,sha=00:0a:85:04:93:99,tha=00:00:00:00:00:00), packets:0, bytes:0, used:never, actions:0,1
in_port(1),eth(src=00:0a:85:04:15:5e,dst=00:0a:85:04:93:99),eth_type(0x0800),ipv4(src=192.168.100.219,dst=192.168.100.123,proto=1,tos=0,ttl=64,frag=no),icmp(type=0,code=0), packets:4, bytes:392, used:0.145s, actions:2
in_port(1),eth(src=00:0a:85:04:15:5e,dst=00:0a:85:04:93:99),eth_type(0x0806),arp(sip=192.168.100.219,tip=192.168.100.123,op=2,sha=00:0a:85:04:15:5e,tha=00:0a:85:04:93:99), packets:0, bytes:0, used:never, actions:2
in_port(2),eth(src=00:0a:85:04:93:99,dst=00:0a:85:04:15:5e),eth_type(0x0800),ipv4(src=192.168.100.123,dst=192.168.100.219,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0), packets:4, bytes:392, used:0.145s, actions:1
(type=8)のデータパスが確認できます。actions:1は出力ポートが1(=eth0)
となっています。arpはactions:0,1となっていますが、ブロードキャスト
の場合は自分自身用にport 0(=br0) へも出力していることが確認できます。
なお、このデータパスは最大256個となっています。使用されなくなったら数秒
で消えてしまうようです。
◆Open vSwitch性能測定
OpenBlockS 600Dでopenvswitchをカーネルモードで利用した場合の性能を測定してみます。
今回は機材の関係上、obs600-1 <--> obs600-2 間のTCP転送性能を測定します。
測定にはnuttcpを用いました。
まずobs600-2でnuttcpをサーバモードで起動します。
obs600-2# nuttcp -Sそして、obs600-1ではクライアントモードで起動し、10秒間測定します。
obs600-1# nuttcp -i1 -T10 192.168.111.219比較のため、まずはopenvswitchなしの場合で、obs600-1, obs600-2 間を測定
します。ネットワーク図は以下のとおりです。
なお、obs600-1, obs600-2のeth0をmtu 1500にした場合と mtu 9000の場合と2
パターンで測定しました。
結果
mtu 1500次にopenvswitchを間に挟んで同様の測定を行いました。
224.1250 MB / 10.02 sec = 187.6814 Mbps 41 %TX 99 %RX 0 retrans 0.44 msRTT
mtu 9000
322.0000 MB / 10.02 sec = 269.6913 Mbps 48 %TX 99 %RX 0 retrans 0.46 msRTT
ネットワーク図は以下になります。mtu 1500, mtu 9000の2パターンで測定を行
結果
mtu 1500測定結果を比較すると明白に違いはみられません。
209.5625 MB / 10.03 sec = 175.2363 Mbps 40 %TX 98 %RX 0 retrans 1.56 msRTT
mtu 9000
324.0000 MB / 10.01 sec = 271.3858 Mbps 43 %TX 99 %RX 0 retrans 1.53 msRTT
今回の測定では末端のOpenBlockS 600Dの性能がボトルネックとなってしまい、上限の正確な
値は確認できていませんが、すくなくとも、
程度の性能は出ることが確認できました。mtu 1500では 170 Mbpsmtu 9000では 270 Mbps
◆OpenFlow風にOpen vSwitchをコントロール
Open vSwitchではovs-vsctl set-controllerコマンドによりOpenFlowコントロー
ラに接続してコントーラからフロー設定できるようになります。
今回はその前段階としてOpenFlowコントローラは使用せずに、ovs-ofctlコマン
ドを用いることで直接Open vSwitch上のフロー情報を書き換えて動作を確認し
ます。
今回の実験は、マルチホーム環境でopenvswitchの配下にあるクライアントから
の上流へのアクセス時に、特定のTCPポート(今回はSMTP=25)の通信だけ異なる
router を経由するように変更します。
このとき、routerやclientの設定は一切変更せずにopenvswitchの操作だけで上
記制御を行います。
今回使用したネットワーク構成は以下のようになります。
obs600-1ではデフォルトルートは192.168.100.1(router-1)となっていて、
通常の外部への通信はISP 1側を通して行います。
obs600-1# ip route初期状態でのopenvswitchのフローを確認します。
192.168.100.0/24 dev eth1 proto kernel scope link src 192.168.100.123
default via 192.168.100.1 dev eth1
# ovs-ofctl dump-flows br0
NXST_FLOW reply (xid=0x4):
cookie=0x0, duration=40.911s, table=0, n_packets=404, n_bytes=70012, priority=0 actions=NORMAL
actions=NORMALとなっているひとつのエントリが存在します。任意のパケット
はこのエントリにマッチして通常のブリッジ動作を行う。
次に新たなエントリを追加します。
宛先MACアドレスがrouter-1でTCP宛先ポートが25の場合のみ、宛先MACアドレス
を強制的にrouter-2に向かうように変更します。
これを行うにはovs-ofctl add-flowでフローを追加します。
# ovs-ofctl add-flow br0 'priority=100,in_port=2,dl_dst=00:00:00:00:00:01,tcp,tp_dst=25, actions=mod_dl_dst:00:00:00:00:00:02,output:1'priority=100を指定することで、条件にマッチする場合このエントリが優先さ
れます。in_port=2(eth1)から入力したパケットはmod_dl_dstにより宛先MACア
ドレスを変更してoutput:1でPort 1(eth0)に出力されます。
再びovs-ofctl dump-flowsでフローを確認します。
# ovs-ofctl dump-flows br0
NXST_FLOW reply (xid=0x4):
cookie=0x0, duration=1171.997s, table=0, n_packets=0, n_bytes=0, priority=100,tcp,in_port=2,dl_dst=00:00:00:00:00:01,tp_dst=25 actions=mod_dl_dst:00:00:00:00:00:02,output:1
cookie=0x0, duration=1304.627s, table=0, n_packets=2753, n_bytes=347468, priority=0 actions=NORMAL
openvswitch配下のクライアント(obs600-1)で実際に外部SMTPサーバに接続をしてみます。
obs600-1# telnet smtp.example.org 25このとき外部サーバでアクセスログを確認すると、ISP-2経由でアクセスされて
Connected to smtp.example.org.
Escape character is '^]'.
220 smtp.example.org. ESMTP Postfix
いることが確認できます。
WWWサーバ(Port 80)へも同様に接続してみます。
obs600-1# telnet www.example.org 80外部サーバで同様にアクセスログを確認すると、ISP-1経由のアクセスであるこ
Connected to www.example.org.
Escape character is '^]'.
とが確認できます。
これにより当初の目的が達成できました。
このときのOpen vSwitch上でのデータパスも確認してみます。
# ovs-dpctl dump-flows br0
- 省略 -
in_port(2),eth(src=00:0a:85:04:93:99,dst=00:00:00:00:00:01),eth_type(0x0800),ipv4(src=192.168.111.123,dst=175.41.248.246,proto=6,tos=0x10,ttl=64,frag=no),tcp(src=45737,dst=25), packets:3, bytes:206, used:0.645s, actions:set(eth(src=00:0a:85:04:93:99,dst=00:00:00:00:00:02)),1
- 省略 -
# ovs-dpctl dump-flows br0
- 省略 -
in_port(2),eth(src=00:0a:85:04:93:99,dst=00:00:00:00:00:01),eth_type(0x0800),ipv4(src=192.168.111.123,dst=175.41.248.246,proto=6,tos=0x10,ttl=64,frag=no),tcp(src=35688,dst=80), packets:0, bytes:0, used:never, actions:1
- 省略 -
dst=80の場合はactions:1に対して、dst=25の場合はMACアドレスが変更
されていることが確認できます。
◆まとめ
今回はOpenFlowに対応した仮想スイッチOpen vSwitchをOpenBlockS 600D上に導入し実際
の動作確認を行いました。転送処理はカーネルモードで行うようにビルドを行
いました。
Open vSwitchをブリッジとして動作するように設定しOpen vSwitch の各種デー
モンやコマンドを使い動作確認を行いました。
OpenBlockS 600D上でのOpen vSwitchの転送性能を測定したところ、最低でも
mtu 1500では 170 Mbps程度はでそうなことが確認できました。
mtu 9000では 270 Mbps
Open vSwitch上でフローを設定することで、特定のフローについての
動作を変更できることを確認しました。実際にはTCP宛先ポート25(=smtp)
のパケットを異なるルータに転送するという例を実現しました。
以上で今回目的としていたことは一通り確認できました。
0 件のコメント:
コメントを投稿