家庭用BuffaloルータのOpenFlow化へのチャレンジ 〜OpenvSwitch構築手順メモ編〜
前回、家庭用Buffaloルータ”BHR-4GRV"をOpenFlow化して、OpenFlow基本動作を確認しました。
家庭用BuffaloルータのOpenFlow化へのチャレンジ 〜OpenFlow1.3動作確認編〜 - SDN開発エンジニアを目指した活動ブログ
SDN/OpenFlowの実験環境で、OpenFlowスイッチ台数を増やすことを想定して、OpenvSwitch構築手順をメモっておきます。
◆構築手順の流れ
(1) Buffaloルータ”BHR-4GRV"のOpenWRT化
(2) OpenWRTのネットワーク設定
(3) OpenvSwitchパッケージのインストール
◆BHR-4GRVのOpenWRT化
本構築手順は、MacBook(Mac OS X)での作業を想定しております。
注) ここでの構築手順は、個人の構築メモとして掲載しております。
(Buffaloルータ”BHR-4GRV"が文鎮化してしまうなどの不測な事態が発生しても、あくまでも、自己責任でお願いします。)
1. OpenWRファームウェアの入手
BHR-4GRV専用のOpenWRTファームウェアはありませんが、WZR-HP-G450Hで代用可能です。
Table of Hardware - OpenWrt Wiki
以下のファームウェアをダウンロードし、MacBookのローカルディスクに置いておきます。
openwrt-ar71xx-generic-wzr-hp-g450h-squashfs-tftp.bin
2. debugモードでのログイン
BHR-4GRVの初期状態では、192.168.12.1が設定されているようです。
まずは、WEBブラウザの管理コンソールから管理者パスワード(8文字以内)を設定しておきます。
そして、以下のURLからdebugモードでログインします。
http://192.168.12.1/cgi-bin/cgi?req=frm&frm=py-db/55debug.html ID:bufpy Password: otdpopy + 管理者パスワード
成功するとdebugメニュー画面が表示されるので、telnetd を有効にします。
以降、telnetでのアクセスが可能となります。
3. uboot変数の確認と変更
bootloader 「u-boot」用の変数(パラメータ)を確認します。
ipaddr: 192.168.11.1
uboot_ethaddr: 02:AA:BB:CC:DD:22
BHR-4GRVのデフォルト管理IPは192.168.12.1ですが、uboot変数値は192.168.11.1になっている点を留意しておきましょう。
# ubootenv list
tftpでのファームウェアインストールをできるようにするために accept_open_rt_fmt を設定します。
# ubootenv set accept_open_rt_fmt 1
末尾に変数が登録されたことを確認します。
# ubootenv list
4. MacBookのアドレス設定
IPアドレスを以下に設定します。
IPアドレス:192.168.11.2
サブネットマスク:255.255.255.0
以下のコマンドで、MacBook上のarpテーブルにMACアドレスをスタティックで登録しておきます。
$ sudo arp -s 192.168.11.1 02:AA:BB:CC:DD:22
5. TFTPでのOpenWRTファームウェアのインストール
まずは、TFTP動作環境を設定しておきます。
$ tftp tftp> connect 192.168.11.1 tftp> verbose tftp> binary tftp> trace tftp> rexmt 1 tftp> timeout 60
つぎに、BHR-4GRVの電源ONして、数秒後に、OpenWRTファームウェアの流し込みを開始します。
tftp> put openwrt-ar71xx-generic-wzr-hp-g450h-squashfs-tftp.bin
以上で、OpenWRT化は完了です。
こちらのURLも参考になると思います。
Buffalo WHR-HP-G300N - OpenWrt Wiki
◆OpenWRTのネットワーク設定
BHR-4GRVのOpenWRT化が完了したら、つぎに、OpenvSwitch動作環境に関わるネットワーク設定を行います。
なお、BHR-4GRVの外観上のRJ45ポートが、Etherポートに対応しているわけではないようです。
すなわち、BHR-4GRV内部のEtherSwitchでeth0ポートを共有する仕組みとなっているみたいです。
よって、今回は、下図のようなVLAN構成となるようにコンフィグ設定を行います。
OpenFlowコントローラとのSecureチャネル接続は、WANポート(青色のポート)を使用することにします。
1. OpenWRTへのログイン
BHR-4GRVのLAN側ポートとMacBookをLANケーブル接続して、rootユーザで、OpenWRTにログインしてみます。
(青色のWAN側ポートではありません。)
$ ssh root@192.168.1.1 root@192.168.1.1's password: BusyBox v1.19.4 (2014-03-30 18:50:39 JST) built-in shell (ash) Enter 'help' for a list of built-in commands. _______ ________ __ | |.-----.-----.-----.| | | |.----.| |_ | - || _ | -__| || | | || _|| _| |_______|| __|_____|__|__||________||__| |____| |__| W I R E L E S S F R E E D O M ----------------------------------------------------- BARRIER BREAKER (Bleeding Edge, r40300) ----------------------------------------------------- * 1/2 oz Galliano Pour all ingredients into * 4 oz cold Coffee an irish coffee mug filled * 1 1/2 oz Dark Rum with crushed ice. Stir. * 2 tsp. Creme de Cacao -----------------------------------------------------
2. SSH通過の設定
外部から、WANポートに対してSSHログインが可能なように、firewall設定を行います。
root@OpenWrt:~# vi /etc/config/firewall ----------------------- config zone option name lan list network 'lan' option input ACCEPT option output ACCEPT option forward ACCEPT config zone option name wan list network 'wan' option input ACCEPT option output ACCEPT option forward ACCEPT config forwarding option src lan option dest wan # Allow SSH config rule option name Allow-ssh option src wan option proto tcp option dest_port 22 option target ACCEPT
コンフィグ設定を行ったら、firewallルール有効化のために再起動します。
root@OpenWrt:~# /etc/init.d/firewall restart
3. アドレス設定
WAN側ポートには、以下のIPアドレスを設定します。
IPアドレス:192.168.0.1
サブネットマスク:255.255.255.0
root@OpenWrt:~# vi /etc/config/network ----------------------- config interface 'loopback' option ifname 'lo' option proto 'static' option ipaddr '127.0.0.1' option netmask '255.0.0.0' config switch option name 'switch0' option reset '1' option enable_vlan '1' config switch_vlan option device 'switch0' option vlan '1' option ports '0t 2' config interface 'lan1' option ifname 'eth0.1' option proto 'static' config switch_vlan option device 'switch0' option vlan '2' option ports '0t 3' config interface 'lan2' option ifname 'eth0.2' option proto 'static' config switch_vlan option device 'switch0' option vlan '3' option ports '0t 4' config interface 'lan3' option ifname 'eth0.3' option proto 'static' config switch_vlan option device 'switch0' option vlan '4' option ports '0t 5' config interface 'lan4' option ifname 'eth0.4' option proto 'static' config switch_vlan option device 'switch0' option vlan '5' option ports '0t 1' config interface 'wan1' option ifname 'eth0.5' option proto 'static' option ipaddr '192.168.0.1' option netmask '255.255.255.0'
コンフィグ設定を行ったら、ネットワーク有効化のために再起動します。
root@OpenWrt:~# /etc/init.d/network restart
BHR-4GRVのWAN側ポートとMacBookをLANケーブル接続して、OpenWRTに再ログインします。
NIC設定の確認すると、こんな感じで出力されます。
root@OpenWrt:~# ifconfig eth0 Link encap:Ethernet HWaddr 96:3C:D2:D7:9E:BB inet6 addr: fe80::943c:d2ff:fed7:9ebb/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:42 errors:0 dropped:0 overruns:0 frame:0 TX packets:54 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:6061 (5.9 KiB) TX bytes:7534 (7.3 KiB) Interrupt:4 eth0.1 Link encap:Ethernet HWaddr 96:3C:D2:D7:9E:BB inet6 addr: fe80::943c:d2ff:fed7:9ebb/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:4 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:408 (408.0 B) eth0.2 Link encap:Ethernet HWaddr 96:3C:D2:D7:9E:BB inet6 addr: fe80::943c:d2ff:fed7:9ebb/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:4 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:408 (408.0 B) eth0.3 Link encap:Ethernet HWaddr 96:3C:D2:D7:9E:BB inet6 addr: fe80::943c:d2ff:fed7:9ebb/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:5 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:478 (478.0 B) eth0.4 Link encap:Ethernet HWaddr 96:3C:D2:D7:9E:BB inet6 addr: fe80::943c:d2ff:fed7:9ebb/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:4 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:408 (408.0 B) eth0.5 Link encap:Ethernet HWaddr 96:3C:D2:D7:9E:BB inet addr:192.168.0.1 Bcast:192.168.0.255 Mask:255.255.255.0 inet6 addr: fe80::943c:d2ff:fed7:9ebb/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:42 errors:0 dropped:0 overruns:0 frame:0 TX packets:33 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:5305 (5.1 KiB) TX bytes:5184 (5.0 KiB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:432 errors:0 dropped:0 overruns:0 frame:0 TX packets:432 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:29376 (28.6 KiB) TX bytes:29376 (28.6 KiB)
◆OpenvSwitchインストール
OpenWRTのネットワーク設定が終わったら、OpenvSwitchパッケージをインストールします。
1. OpenvSwitchパッケージの入手
まずは、MacBook上に、OpenvSwitchパッケージをダウンロードしておきます。
Releases · ttsubo/openvswitch · GitHub
そして、OpenWRT上に、OpenvSwitchパッケージをアップロードします。
scp kmod-crypto-crc32c_3.10.34-1_ar71xx.ipk root@192.168.0.1:/root scp kmod-crypto-hash_3.10.34-1_ar71xx.ipk root@192.168.0.1:/root scp kmod-gre_3.10.34-1_ar71xx.ipk root@192.168.0.1:/root scp kmod-iptunnel_3.10.34-1_ar71xx.ipk root@192.168.0.1:/root scp kmod-lib-crc32c_3.10.34-1_ar71xx.ipk root@192.168.0.1:/root scp kmod-llc_3.10.34-1_ar71xx.ipk root@192.168.0.1:/root scp kmod-openvswitch_3.10.34.2.1.0-1_ar71xx.ipk root@192.168.0.1:/root scp kmod-stp_3.10.34-1_ar71xx.ipk root@192.168.0.1:/root scp openvswitch-common_2.1.0-1_ar71xx.ipk root@192.168.0.1:/root scp openvswitch-switch_2.1.0-1_ar71xx.ipk root@192.168.0.1:/root scp libopenssl_1.0.1f-1_ar71xx.ipk root@192.168.0.1:/root scp libpcap_1.5.3-1_ar71xx.ipk root@192.168.0.1:/root scp librt_0.9.33.2-1_ar71xx.ipk root@192.168.0.1:/root scp libpthread_0.9.33.2-1_ar71xx.ipk root@192.168.0.1:/root scp zlib_1.2.8-1_ar71xx.ipk root@192.168.0.1:/root
そして、OpenWRT上で、パッケージインストールを行います。
$ ssh root@192.168.0.1 root@192.168.0.1's password: BusyBox v1.19.4 (2014-03-30 18:50:39 JST) built-in shell (ash) Enter 'help' for a list of built-in commands. _______ ________ __ | |.-----.-----.-----.| | | |.----.| |_ | - || _ | -__| || | | || _|| _| |_______|| __|_____|__|__||________||__| |____| |__| W I R E L E S S F R E E D O M ----------------------------------------------------- BARRIER BREAKER (Bleeding Edge, r40300) ----------------------------------------------------- * 1/2 oz Galliano Pour all ingredients into * 4 oz cold Coffee an irish coffee mug filled * 1 1/2 oz Dark Rum with crushed ice. Stir. * 2 tsp. Creme de Cacao ----------------------------------------------------- root@OpenWrt:~# ls -l -rw-r--r-- 1 root root 1704 Mar 30 15:13 kmod-crypto-crc32c_3.10.34-1_ar71xx.ipk -rw-r--r-- 1 root root 6620 Mar 30 15:13 kmod-crypto-hash_3.10.34-1_ar71xx.ipk -rw-r--r-- 1 root root 8155 Mar 30 15:13 kmod-gre_3.10.34-1_ar71xx.ipk -rw-r--r-- 1 root root 8220 Mar 30 15:14 kmod-iptunnel_3.10.34-1_ar71xx.ipk -rw-r--r-- 1 root root 1591 Mar 30 15:14 kmod-lib-crc32c_3.10.34-1_ar71xx.ipk -rw-r--r-- 1 root root 684 Mar 30 15:14 kmod-llc_3.10.34-1_ar71xx.ipk -rw-r--r-- 1 root root 39049 Mar 30 15:14 kmod-openvswitch_3.10.34.2.1.0-1_ar71xx.ipk -rw-r--r-- 1 root root 695 Mar 30 15:14 kmod-stp_3.10.34-1_ar71xx.ipk -rw-r--r-- 1 root root 674063 Mar 30 15:15 libopenssl_1.0.1f-1_ar71xx.ipk -rw-r--r-- 1 root root 88627 Mar 30 15:16 libpcap_1.5.3-1_ar71xx.ipk -rw-r--r-- 1 root root 31833 Mar 30 15:16 libpthread_0.9.33.2-1_ar71xx.ipk -rw-r--r-- 1 root root 5592 Mar 30 15:16 librt_0.9.33.2-1_ar71xx.ipk -rw-r--r-- 1 root root 523230 Mar 30 15:15 openvswitch-common_2.1.0-1_ar71xx.ipk -rw-r--r-- 1 root root 1421554 Mar 30 15:15 openvswitch-switch_2.1.0-1_ar71xx.ipk -rw-r--r-- 1 root root 40544 Mar 30 15:16 zlib_1.2.8-1_ar71xx.ipk root@OpenWrt:~# opkg install kmod-llc_3.10.34-1_ar71xx.ipk Installing kmod-llc (3.10.34-1) to root... Configuring kmod-llc. root@OpenWrt:~# opkg install kmod-stp_3.10.34-1_ar71xx.ipk Installing kmod-stp (3.10.34-1) to root... Configuring kmod-stp. root@OpenWrt:~# opkg install kmod-iptunnel_3.10.34-1_ar71xx.ipk Installing kmod-iptunnel (3.10.34-1) to root... Configuring kmod-iptunnel. root@OpenWrt:~# opkg install kmod-gre_3.10.34-1_ar71xx.ipk Installing kmod-gre (3.10.34-1) to root... Configuring kmod-gre. root@OpenWrt:~# opkg install kmod-crypto-hash_3.10.34-1_ar71xx.ipk Installing kmod-crypto-hash (3.10.34-1) to root... Configuring kmod-crypto-hash. root@OpenWrt:~# opkg install kmod-crypto-crc32c_3.10.34-1_ar71xx.ipk Installing kmod-crypto-crc32c (3.10.34-1) to root... Configuring kmod-crypto-crc32c. root@OpenWrt:~# opkg install kmod-lib-crc32c_3.10.34-1_ar71xx.ipk Installing kmod-lib-crc32c (3.10.34-1) to root... Configuring kmod-lib-crc32c. root@OpenWrt:~# modprobe libcrc32c root@OpenWrt:~# opkg install kmod-openvswitch_3.10.34.2.1.0-1_ar71xx.ipk Installing kmod-openvswitch (3.10.34+2.1.0-1) to root... Configuring kmod-openvswitch. root@OpenWrt:~# lsmod|grep open gre 1874 2 openvswitch libcrc32c 599 1 openvswitch openvswitch 60332 0 root@OpenWrt:~# opkg install zlib_1.2.8-1_ar71xx.ipk Installing zlib (1.2.8-1) to root... Configuring zlib. root@OpenWrt:~# opkg install libopenssl_1.0.1f-1_ar71xx.ipk Installing libopenssl (1.0.1f-1) to root... Configuring libopenssl. root@OpenWrt:~# opkg install libpcap_1.5.3-1_ar71xx.ipk Installing libpcap (1.5.3-1) to root... Configuring libpcap. root@OpenWrt:~# opkg install libpthread_0.9.33.2-1_ar71xx.ipk Installing libpthread (0.9.33.2-1) to root... Configuring libpthread. root@OpenWrt:~# opkg install librt_0.9.33.2-1_ar71xx.ipk Installing librt (0.9.33.2-1) to root... Configuring librt. root@OpenWrt:~# opkg install openvswitch-common_2.1.0-1_ar71xx.ipk Installing openvswitch-common (2.1.0-1) to root... Configuring openvswitch-common. root@OpenWrt:~# opkg install openvswitch-switch_2.1.0-1_ar71xx.ipk Installing openvswitch-switch (2.1.0-1) to root... Configuring openvswitch-switch. root@OpenWrt:~# /etc/init.d/openvswitch start 2014-03-30T15:26:01Z|00001|reconnect|INFO|unix:/var/run/db.sock: connecting... 2014-03-30T15:26:01Z|00002|reconnect|INFO|unix:/var/run/db.sock: connected
以上で、OpenvSwitchインストールは完了です。
いちおう、OpenvSwitchのバージョンを確認しておきます。
root@OpenWrt:~# ovs-vsctl -V ovs-vsctl (Open vSwitch) 2.1.0 Compiled Mar 30 2014 17:50:11
2. OpenvSwitch設定
ここからは、一般的なOpenvSwitch設定作業ですね。
root@OpenWrt:~# ovs-vsctl add-br br0 root@OpenWrt:~# ovs-vsctl add-port br0 eth0.1 root@OpenWrt:~# ovs-vsctl add-port br0 eth0.2 root@OpenWrt:~# ovs-vsctl set-controller br0 tcp:192.168.0.100:6633 root@OpenWrt:~# ovs-vsctl set bridge br0 other-config:datapath-id=0000000000000001 root@OpenWrt:~# ovs-vsctl set bridge br0 protocols=OpenFlow13
設定結果を確認しておきます。
root@OpenWrt:~# ovs-vsctl show 6d27491f-e242-4a02-acf3-cd0c28d16de2 Bridge "br0" Controller "tcp:192.168.0.100:6633" Port "eth0.2" Interface "eth0.2" Port "eth0.1" Interface "eth0.1" Port "br0" Interface "br0" type: internal root@OpenWrt:~# ovs-ofctl dump-ports-desc br0 --protocols=OpenFlow13 OFPST_PORT_DESC reply (OF1.3) (xid=0x2): 1(eth0.1): addr:96:3c:d2:d7:9e:bb config: 0 state: 0 current: 1GB-FD AUTO_NEG advertised: 1GB-FD supported: 1GB-FD speed: 1000 Mbps now, 1000 Mbps max 2(eth0.2): addr:96:3c:d2:d7:9e:bb config: 0 state: 0 current: 1GB-FD AUTO_NEG advertised: 1GB-FD supported: 1GB-FD speed: 1000 Mbps now, 1000 Mbps max LOCAL(br0): addr:fa:e4:ce:22:a1:9b config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max
以上で、OpenWRT上でのOpenvSwitch環境が構築できました。
◆留意事項
OpenWRT上でのネットワーク設定では、各ポートをeth0上で共有する形態になっています。
従って、各ポートに割り当てられたMACアドレスがみんな同じ値になってしまっております。
今回のSDN/OpenFlow実験環境で使用する際には、MACアドレス制御もOpenFlowで管理が可能となるので、特に気にする必要がないと思います。しかし、オーバレイNWネットワークとして、本装置を活用する場合には、ネットワークトポロジ上でのMACテーブル管理で、ループ等の弊害が発生するかもしれません。
◆終わりに
前回を通じて、"OpenWRT+OpenvSwitch"でOpenFlow1.3スイッチ環境を構築してみました。
構築手順も、OpenWRTファーム構築さえ慣れてしまえば、OpenFlowスイッチ台数の拡張時にも、それほど苦労なく対応できると思います。
さらに、OpenFlowスイッチが6,000円程度で入手可能というのは、いちばんの魅力かもしれません。
家庭用BuffaloルータのOpenFlow化へのチャレンジ 〜OpenFlow1.3動作確認編〜
これまでも、Linuxボックス"DNA940"を活用してSDN/OpenFlow環境を構築してきました。ただし、汎用性の乏しいLinuxボックス構成だったので、SDN/OpenFlow環境としてOpenFlowスイッチ台数を増やすことが困難でした。今回は、もっと簡易にOpenFlowスイッチ台数を増やすことができる環境構築を目指します。
◆OpenWRT版OpenvSwitch構築
昨年あたりから、OpenWRT版のOpenvSwitchがGitHUBに公開されているようです。ただし、OpenvSwitchバージョンが"1.9.0"と古いままになっているようです。
そこで、Buffaloルータ"BHR-4GRV"のOpenWRT化とOpenvSwitch 2.1.0版パッケージを整備しました。
Releases · ttsubo/openvswitch · GitHub
こちらが、実際に、OpenFlow化した家庭用Buffaloルータ”BHR-4GRV"です。OpenvSwitchの特徴としては、ユーザランドではなく、カーネルモジュールとして、datapathが動作する点ですね。
ちなみに、家庭用Buffaloルータ"WHR-G301N"でも、チャレンジしてみましたが、OpenvSwitch保存先のルータ本体ディスク容量不足がネックとなり、インストールできませんでした。
◆自宅ネットワークへのOpenFlow導入
基本的には、以前のブログ記事と同等の構成になります。
OpenFlow簡易ルータの実践活用(3) 〜LinuxボックスでOpenFlowスイッチ構築編〜 - SDN開発エンジニアを目指した活動ブログ
◆実際、使ってみて ...
Buffaloルータ"BHR-4GRV"で構築したOpenFlowスイッチを介して実際にインターネットにアクセスしてみました。
いまのところは、安定して動作しているようです。一般的なインターネットの使用感について、とくに、ストレスが感じることなく、大変満足できるものです。ustreamの閲覧も、すこぶる順調でした。
あと、参考までに、スピード計測の結果は、こんな感じでした。
◆OpenvSwitch上でのフローエントリ出力
ちなみに、OpenFlowのフローエントリのダンプは、こんな感じです。
root@OpenWrt:~# ovs-ofctl dump-flows br0 --protocols=OpenFlow13 OFPST_FLOW reply (OF1.3) (xid=0x2): cookie=0x0, duration=827.722s, table=0, n_packets=567, n_bytes=45795, priority=255,ip,in_port=2,dl_src=7c:c3:a1:87:8f:65,dl_dst=00:00:00:00:00:02,nw_dst=192.168.100.1 actions=set_field:00:00:00:00:00:01->eth_src,set_field:10:66:82:93:c4:f0->eth_dst,output:1,dec_ttl cookie=0x0, duration=827.722s, table=0, n_packets=234295, n_bytes=300428408, priority=255,ip,in_port=1,dl_src=10:66:82:93:c4:f0,dl_dst=00:00:00:00:00:01,nw_dst=192.168.101.1 actions=set_field:00:00:00:00:00:02->eth_src,set_field:7c:c3:a1:87:8f:65->eth_dst,output:2,dec_ttl cookie=0x0, duration=814.607s, table=0, n_packets=139100, n_bytes=12649245, priority=1,ip actions=set_field:00:00:00:00:00:01->eth_src,set_field:10:66:82:93:c4:f0->eth_dst,output:1,dec_ttl cookie=0x0, duration=844.926s, table=0, n_packets=853, n_bytes=133044, priority=0 actions=CONTROLLER:65535 cookie=0x0, duration=837.807s, table=0, n_packets=12, n_bytes=924, priority=16,ip,nw_dst=192.168.100.100 actions=CONTROLLER:65535 cookie=0x0, duration=827.794s, table=0, n_packets=92, n_bytes=11862, priority=16,ip,nw_dst=192.168.101.100 actions=CONTROLLER:65535
◆終わりに
SDN/OpenFlowを中心としたネットワーク仮想化技術は、様々な最新技術によって構成されるものです。これらを習得するためには、実際に試してみるのが一番手っ取り早いです。ただ、これまでは、家計への負担にならない程度の出費でSDN/OpenFlow環境を構築することは困難でした。今回の"OpenWRT+OpenvSwitch"の組み合わせで、手軽にリアルな環境を入手できることが判明できました。次回は、OpenFlowスイッチ台数の拡張を見据えて、"OpenWRT+OpenvSwitch"の構築手順をメモしておきたいと思います。
ネットワーク仮想化技術の実践活用(2) 〜OpenvSwitch管理プロトコル(OVSDB)編〜
ネットワーク仮想化環境の特徴は、VxLAN等のオーバレイ技術を活用して多拠点間をトンネルで接続するモデルだと思います。
ただ、拠点数(n)に対して、拠点間をフルメッシュn*(n − 1)本のトンネルを構築する必要があります。
前回のブログ記事では、2拠点をVxLANトンネルで構築する程度のため、OpenvSwitchのコマンドラインで構築しましたが、拠点数が多くなると、やっぱり、集中管理的に拠点間トンネル設定を行いたくなりますよね。ということで、今回は、OpenvSwitch管理プロトコル「OVSDB」に着目したいと思います。
◆OVSDBとは ?
OVSDBとは、OpenvSwitchのデータモデルを管理する手法です。
RDBMSにおけるSQL的な役割で、DDL(Data Definition Language:データ定義言語)の側面と、DML(Data Manipulation Language:データ操作言語)の側面を併せ持っているものです。
ざっと、OpenvSwitchのテーブル構成は、以下のようになってます。
Open_vSwitch --> Open vSwitch configuration.
Bridge --> Bridge configuration.
Port --> Port configuration.
Interface --> One physical network device in a Port. Flow_Table OpenFlow table configuration
QoS --> Quality of Service configuration Queue QoS output queue.
Mirror --> Port mirroring.
Controller --> OpenFlow controller configuration. Manager OVSDB management connection. NetFlow NetFlow configuration.
SSL --> SSL configuration.
sFlow --> sFlow configuration.
IPFIX --> IPFIX configuration. Flow_Sample_Collector_Set
Flow_Sample_Collector_Set --> configuration.
また、OpenvSwitchデータベースのスキーマ定義などの詳細は、以下のリンクが参考になります。
http://openvswitch.org/ovs-vswitchd.conf.db.5.pdf
Open_vSwitchテーブル構造
OpenvSwitchデータベースを構成する多数のテーブルのうち、「Open_vSwitch」テーブル構造を、確認してみます。
tsubo@OFS1:~$ sudo ovs-vsctl list Open_vSwitch _uuid : 82524775-43a3-4838-90ae-61e2cbd10820 bridges : [55d71da8-cd33-4117-b7a3-de8a5b4222a3] cur_cfg : 12 db_version : "7.3.0" external_ids : {system-id="a7812d37-5389-4ae6-b003-42a66a6e05fe"} manager_options : [0cc00f03-5c47-404a-9a31-66e5105f48d2] next_cfg : 12 other_config : {} ovs_version : "2.0.1" ssl : [] statistics : {} system_type : Ubuntu system_version : "12.04-precise"
ovs-vsctlコマンドと、いろいろと引数を指定してあげれば、様々なテーブル情報を参照できるようです。
◆外部からOpenvSwitchデータベースにアクセスするには ?
1. OpenvSwitch管理プロトコル
VMware社により、IETFのInformational RFC化されているようですが、OpenvSwitch専用だと思います。
他の類似技術として、OpenFlowスイッチ管理プロトコル「OF-Config」があります。
OVSDB管理手法の特徴としては、JSON-RPCをベースとしたデータモデリングを前提としている点です。
データ検索クエリのデータフォーマットとしては、"method", "params", "id"という構造となるようです。
RFC 7047 :The Open vSwitch Database Management Protocol 4.1.5. Monitor The "monitor" request enables a client to replicate tables or subsets of tables within an OVSDB database by requesting notifications of changes to those tables and by receiving the complete initial state of a table or a subset of a table. The request object has the following members: o "method": "monitor" o "params": [<db-name>, <json-value>, <monitor-requests>] o "id": <nonnull-json-value> The <json-value> parameter is used to match subsequent update notifications (see below) to this request. The <monitor-requests> object maps the name of the table to be monitored to an array of <monitor-request> objects. Each <monitor-request> is an object with the following members: "columns": [<column>*] optional "select": <monitor-select> optional The columns, if present, define the columns within the table to be monitored. <snip>
2. 外部機器からデータ操作するための事前準備
外部機器から、OpenvSwitchデータベースにアクセスするために、事前に、以下のコマンドを実施しておきます。
$ sudo ovs-vsctl set-manager ptcp:6632
ポート番号は、今回は、とりあえず、"6632"としました。
3. 実際に「Open_vSwitchテーブル」を参照してみる
それでは、外部装置から、以下のPythonプログラムで「Open_vSwitchテーブル」を参照してみます。
#-*- coding: utf-8 -*- import socket import json OVSDB_IP = '192.168.0.1' OVSDB_PORT = 6632 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((OVSDB_IP, OVSDB_PORT)) monitor_query = \ {"method":"monitor", "params":["Open_vSwitch","null",{"Open_vSwitch":{"columns":["bridges","cur_cfg","db_version","external_ids","manager_options","next_cfg","other_config","ovs_version","ssl","statistics","system_type","system_version"]}}], "id":0} print "----------------------------------" print "json rpc request" print "----------------------------------" print json.dumps(monitor_query, sort_keys=False, indent=1) s.send(json.dumps(monitor_query)) print "----------------------------------" print "json rpc reply" print "----------------------------------" response = s.recv(8192) result = json.loads(response) print json.dumps(result, sort_keys=False, indent=1)
Pythonプログラムの実行結果は、こんな感じです。
さきほど、"sudo ovs-vsctl list Open_vSwitch"の実行結果と対比してみると、OVSDBの挙動がイメージしやすいかもしれません。
$ python ovsdb_show.py ---------------------------------- json rpc request ---------------------------------- { "params": [ "Open_vSwitch", "null", { "Open_vSwitch": { "columns": [ "bridges", "cur_cfg", "db_version", "external_ids", "manager_options", "next_cfg", "other_config", "ovs_version", "ssl", "statistics", "system_type", "system_version" ] } } ], "method": "monitor", "id": 0 } ---------------------------------- json rpc reply ---------------------------------- { "error": null, "id": 0, "result": { "Open_vSwitch": { "82524775-43a3-4838-90ae-61e2cbd10820": { "new": { "bridges": [ "uuid", "55d71da8-cd33-4117-b7a3-de8a5b4222a3" ], "statistics": [ "map", [] ], "db_version": "7.3.0", "next_cfg": 12, "ovs_version": "2.0.1", "other_config": [ "map", [] ], "ssl": [ "set", [] ], "system_type": "Ubuntu", "external_ids": [ "map", [ [ "system-id", "a7812d37-5389-4ae6-b003-42a66a6e05fe" ] ] ], "system_version": "12.04-precise", "cur_cfg": 12, "manager_options": [ "uuid", "0cc00f03-5c47-404a-9a31-66e5105f48d2" ] } } } } }
◆集中管理的にVxLANトンネルを設定してみる
OpenvSwitch管理プロトコル概要が理解できたところで、それでは、もう少し実用的なOVSDB活用にチャレンジしてみます。
1. 検証構成
基本的な検証構成は、前回のブログ記事と同様です。
ただし、今回は、OpenFlowコントローラを使用せず、OVSDBコントローラとして、Ryuコントローラを活用しました。
2. VxLANトンネル設定プログラム
OVSDBを制御するPythonプログラムは、以下になります。OVSDBコントローラのNorthBoundインタフェースとして、REST-APIを採用しております。
import json from webob import Response from ryu.base import app_manager from ryu.app.wsgi import ControllerBase, WSGIApplication, route from ryu.lib.dpid import DPID_PATTERN from ryu.lib.ovs import bridge OVSDB_ADDR1 = 'tcp:192.168.0.1:6632' OVSDB_ADDR2 = 'tcp:192.168.0.2:6632' class SetOvsdb(app_manager.RyuApp): _CONTEXTS = { 'wsgi': WSGIApplication } def __init__(self, *args, **kwargs): super(SetOvsdb, self).__init__(*args, **kwargs) wsgi = kwargs['wsgi'] wsgi.register(OvsdbController, {'SetOvsdb' : self}) def setTunnel(self, id, name, type, local_ip, remote_ip): if id == 1: ovs_bridge = bridge.OVSBridge(id, OVSDB_ADDR1) elif id == 2: ovs_bridge = bridge.OVSBridge(id, OVSDB_ADDR2) else: return 1 ovs_bridge.init() ovs_bridge.add_tunnel_port(name, type, local_ip, remote_ip) return 0 class OvsdbController(ControllerBase): def __init__(self, req, link, data, **config): super(OvsdbController, self).__init__(req, link, data, **config) self.ovsdb_spp = data['SetOvsdb'] @route('router', '/ovsdb/{dpid}/tunnel', methods=['POST'], requirements={'dpid': DPID_PATTERN}) def set_tunnel_port(self, req, dpid, **kwargs): tunnel_param = eval(req.body) result = self.setTunnel(int(dpid, 16), tunnel_param) message = json.dumps(result) return Response(status=200, content_type = 'application/json', body = message) def setTunnel(self, id, tunnel_param): simpleOvsdb = self.ovsdb_spp name = tunnel_param['tunnel']['name'] type = tunnel_param['tunnel']['type'] local_ip = tunnel_param['tunnel']['local_ip'] remote_ip = tunnel_param['tunnel']['remote_ip'] simpleOvsdb.setTunnel(id, name, type, local_ip, remote_ip) return { 'id': '%016d' % id, 'tunnel': { 'name': '%s' % name, 'type': '%s' % type, 'local_ip': '%s' % local_ip, 'remote_ip': '%s' % remote_ip } }
3. OVSDBコントローラ上でのプログラム動作イメージ
実際に、プログラムを動作させてみました。REST-API経由で、VxLANトンネル設定パラメータを受信した様子がわかると思います。
$ ryu-manager setOvsdb.py loading app setOvsdb.py creating context wsgi instantiating app setOvsdb.py of SetOvsdb (4017) wsgi starting up on http://0.0.0.0:8080/ (4017) accepted ('127.0.0.1', 37197) 127.0.0.1 - - [23/Mar/2014 17:35:17] "POST /ovsdb/0000000000000001/tunnel HTTP/1.1" 200 250 0.285298 (4017) accepted ('127.0.0.1', 37201) 127.0.0.1 - - [23/Mar/2014 17:35:21] "POST /ovsdb/0000000000000002/tunnel HTTP/1.1" 200 250 0.287827
4. OFS1へのVxLANトンネル設定
実際に、OVSDBコントローラの上位より、REST-APIを経由してOFS1用のVxLANトンネル設定パラメータを指定しました。
$ curl -s -X POST -d '{"tunnel": {"name": "vxlan1", "type": "vxlan", "local_ip": "172.16.0.1", "remote_ip": "172.16.0.2"}}' http://localhost:8080/ovsdb/0000000000000001/tunnel | python -mjson.tool { "id": "0000000000000001", "tunnel": { "local_ip": "172.16.0.1", "name": "vxlan1", "remote_ip": "172.16.0.2", "type": "vxlan" } }
結果として、OFS1上で、想定どおりにVxLANトンネルが構築できました。
tsubo@OFS1:~$ sudo ovs-vsctl show 82524775-43a3-4838-90ae-61e2cbd10820 Manager "ptcp:6632" Bridge "br0" Controller "tcp:192.168.0.100:6633" Port "eth1" Interface "eth1" Port "br0" Interface "br0" type: internal Port "vxlan1" Interface "vxlan1" type: vxlan options: {local_ip="172.16.0.1", remote_ip="172.16.0.2"} ovs_version: "2.0.1"
5. OFS2へのVxLANトンネル設定
同様に、OVSDBコントローラの上位より、REST-APIを経由してOFS2用のVxLANトンネル設定パラメータを指定しました。
$ curl -s -X POST -d '{"tunnel": {"name": "vxlan2", "type": "vxlan", "local_ip": "172.16.0.2", "remote_ip": "172.16.0.1"}}' http://localhost:8080/ovsdb/0000000000000002/tunnel | python -mjson.tool { "id": "0000000000000002", "tunnel": { "local_ip": "172.16.0.2", "name": "vxlan2", "remote_ip": "172.16.0.1", "type": "vxlan" } }
結果として、OFS2上で、想定どおりにVxLANトンネルが構築できました。
tsubo@OFS2:~$ sudo ovs-vsctl show 845f5da2-fb63-4273-b32a-c4cf77b0b943 Manager "ptcp:6632" Bridge "br0" Controller "tcp:192.168.0.100:6633" Port "br0" Interface "br0" type: internal Port "eth2" Interface "eth2" Port "vxlan2" Interface "vxlan2" type: vxlan options: {local_ip="172.16.0.2", remote_ip="172.16.0.1"} ovs_version: "2.0.1"
6. VxLANトンネル上での通信確認
VxLANトンネル構築が完了したので、ちゃんと動作できるかの確認として、MacBook Airからインターネットに接続して、Ustream映像を閲覧してみました。ustream映像も問題なく再生できておりました。あと、余談ですが、ustream映像の「BABYMETAL」は、要注目ですよ。
7. 留意事項
VxLANトンネルの登録・削除を繰り返すと、OFポート番号が、インクリメントしてしまうようです。
OpenFlowでVxLANトンネルを制御する際には、考慮が必要となりますね。
tsubo@OFS1:~$ sudo ovs-ofctl dump-ports-desc br0 --protocols=OpenFlow13 OFPST_PORT_DESC reply (OF1.3) (xid=0x2): 1(eth1): addr:00:10:f3:1d:3d:1d config: 0 state: 0 current: 1GB-FD COPPER AUTO_NEG advertised: 10MB-HD 10MB-FD 100MB-HD 100MB-FD 1GB-FD COPPER AUTO_NEG supported: 10MB-HD 10MB-FD 100MB-HD 100MB-FD 1GB-FD COPPER AUTO_NEG speed: 1000 Mbps now, 1000 Mbps max 5(vxlan1): addr:de:be:49:23:35:a6 config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max LOCAL(br0): addr:00:10:f3:1d:3d:1d config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max
◆終わりに
以前から、VxLANトンネル等のネットワーク仮想化の構成管理って、OpenvSwitchコマンド主体だと煩雑になる懸念がありました。OVSDBプロトコル自体の活用シーンは、OpenvSwitch専用ツールが前提となります。ただし、今後も、SDN技術領域におけるOpenvSwitchの役割りは大きなウエイトを占めると予想されますので、もっとちゃんと使いこなせるように調査探求していきたいです。
ネットワーク仮想化技術の実践活用(1) 〜LinuxボックスでVxLAN構築編〜
前回まで、OpenFlow簡易ルータの実践活用として、いろいろと実装技術を試してきました。今回からは、少し路線を変更して、ネットワーク仮想化技術に着目したいと思います。
ネットワーク仮想化技術といえば、SDN業界では、VxLANやNVGREなどの新技術が注目されておりますね。ただ、ちょっと前までは、ベンダのプロプライエタリ製品でなければ実践活用が難しい側面がありました。
最近では、OpenvSwitchでVxLANが使用できるようになったみたいなので、さっそく、試してみたいと思います。
◆ネットワーク仮想化環境
通常だと、ネットワーク仮想化環境を試してみる場合には、お手軽にサーバ仮想化環境で、ネットワーク仮想化ソフトウェアを構築してみる方法が一般的だと思いますが、折角なので、もっと、実践的にLinuxボックスでネットワーク仮想化環境を構築したいと思います。
1. ハードウェア構成
DNA940のLinuxボックスに、OpenvSwitchを搭載する形態としました。よって、前回のDNA940を引き続き使用します。
DNA 940 - ネットワーク&コミュニケーション関連 - NEXCOM
ただし、ネットワーク仮想化を実現するためには、オーバレイNWを終端するエッジ機能を有するLinuxボックスが最低2台必要になりますので、もう一台も事前にセットアップしておきました。
◆OpenvSwitchでのVxLAN設定方法
1. OpenvSwitch(2.0.1)のインストール
OpenvSwitchのインストール手順は、前回のブログ記事と同一のため、ここでは記述を割愛します。
OpenFlow簡易ルータの実践活用(3) 〜LinuxボックスでOpenFlowスイッチ構築編〜 - SDN開発エンジニアを目指した活動ブログ
2. その他、Linuxボックスでの環境設定
その他の設定作業は、概ね、こんな感じです。
ここでは、OFS1についてのみ記載しますが、同様の作業をOFS2についても行います。
(1) IPフォワードを有効にする
$ sudo vi /etc/sysctl.conf net.ipv4.ip_forward=1 $ sudo sysctl -p net.ipv4.ip_forward = 1
(2) Linuxネットワークを設定する
$ sudo vi /etc/network/interface ---------- auto eth0 iface eth0 inet static address 192.168.0.1 netmask 255.255.255.0 auto eth1 iface eth1 inet manual up ifconfig $IFACE 0.0.0.0 up up ip link set $IFACE promisc on down ip link set $IFACE promisc off down ifconfig $IFACE down auto eth2 iface eth2 inet static address 172.16.0.1 netmask 255.255.255.0 ----------
(3) OpenvSwitchのVxLAN用の仮想ポートを作成する
$ sudo ovs-vsctl add-port br0 vxlan1 -- set interface vxlan1 type=vxlan options:remote_ip=172.16.0.2 $ sudo ovs-vsctl show 82524775-43a3-4838-90ae-61e2cbd10820 Bridge "br0" Controller "tcp:192.168.0.100:6633" Port "eth1" Interface "eth1" Port "br0" Interface "br0" type: internal Port "vxlan1" Interface "vxlan1" type: vxlan options: {remote_ip="172.16.0.2"} ovs_version: "2.0.1"
3. OpenFlowによるフローエントリ設定
LinuxボックスでのVxLAN設定作業が完了したら、OpenFlowによるフロー制御ルールを設定します。
ここでは、必要最低限のサンプルなので、実用性は度外視しております。
import logging from ryu.base import app_manager from ryu.controller import ofp_event from ryu.controller.handler import CONFIG_DISPATCHER from ryu.controller.handler import set_ev_cls from ryu.ofproto import ofproto_v1_3 LOG = logging.getLogger('SimpleForward') class SimpleForward(app_manager.RyuApp): OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION] def __init__(self, *args, **kwargs): super(SimpleForward, self).__init__(*args, **kwargs) @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER) def switch_features_handler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto datapath.id = msg.datapath_id ofproto_parser = datapath.ofproto_parser set_config = ofproto_parser.OFPSetConfig( datapath, datapath.ofproto.OFPC_FRAG_NORMAL, datapath.ofproto.OFPCML_MAX ) datapath.send_msg(set_config) self.send_flow(datapath) return 0 def send_flow(self, datapath): self.add_flow(datapath, 1, 2) self.add_flow(datapath, 2, 1) def add_flow(self, datapath, inPort, outPort): match = datapath.ofproto_parser.OFPMatch( in_port=inPort ) actions =[datapath.ofproto_parser.OFPActionOutput(outPort, 0)] inst = [datapath.ofproto_parser.OFPInstructionActions( datapath.ofproto.OFPIT_APPLY_ACTIONS, actions)] mod = datapath.ofproto_parser.OFPFlowMod( cookie=0, cookie_mask=0, table_id=0, command=datapath.ofproto.OFPFC_ADD, datapath=datapath, idle_timeout=0, hard_timeout=0, priority=0xff, buffer_id=0xffffffff, out_port=datapath.ofproto.OFPP_ANY, out_group=datapath.ofproto.OFPG_ANY, match=match, instructions=inst) datapath.send_msg(mod)
4. その他、OpenvSwitch上での各種確認
OpenFlowコントローラから設定したフローエントリは、こんな感じで確認できます
$ sudo ovs-ofctl dump-flows br0 --protocols=OpenFlow13 OFPST_FLOW reply (OF1.3) (xid=0x2): cookie=0x0, duration=32.161s, table=0, n_packets=566, n_bytes=181688, priority=255,in_port=1 actions=output:2 cookie=0x0, duration=32.161s, table=0, n_packets=590, n_bytes=62642, priority=255,in_port=2 actions=output:1
OpenFlowポートでの実際のトラフィックカウンタも、こんな感じで確認することが可能です。
$ sudo ovs-ofctl dump-ports br0 --protocols=OpenFlow13 OFPST_PORT reply (OF1.3) (xid=0x2): 3 ports port 1: rx pkts=27727, bytes=73419238, drop=0, errs=0, frame=0, over=0, crc=0 tx pkts=18985, bytes=1927125, drop=0, errs=0, coll=0 duration=2236.049s port 2: rx pkts=17785, bytes=1809954, drop=0, errs=0, frame=0, over=0, crc=0 tx pkts=25827, bytes=72731314, drop=0, errs=0, coll=0 duration=1060.543s port LOCAL: rx pkts=26, bytes=2724, drop=0, errs=0, frame=0, over=0, crc=0 tx pkts=3357, bytes=1168560, drop=0, errs=0, coll=0 duration=2236.104s
OpenFlowポートとVxLAN仮想ポートの対応付けも、こんな感じで確認することが可能です。
$ sudo ovs-ofctl dump-ports-desc br0 --protocols=OpenFlow13 OFPST_PORT_DESC reply (OF1.3) (xid=0x2): 1(eth1): addr:00:10:f3:1d:3d:1d config: 0 state: 0 current: 1GB-FD COPPER AUTO_NEG advertised: 10MB-HD 10MB-FD 100MB-HD 100MB-FD 1GB-FD COPPER AUTO_NEG supported: 10MB-HD 10MB-FD 100MB-HD 100MB-FD 1GB-FD COPPER AUTO_NEG speed: 1000 Mbps now, 1000 Mbps max 2(vxlan1): addr:ea:01:9a:e2:fa:67 config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max LOCAL(br0): addr:00:10:f3:1d:3d:1d config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max
以上で、VxLANの動作環境の準備が整いました。
◆実際、使ってみて ...
ある程度、Webレスポンス性の性能劣化を想定していたのですが、予想外にも、普段のインターネット利用での操作感と、まったく遜色ありませんでした。通常の検索ポータルでのキーワード検索や、YouTubeなども、ストレスを感じることなく利用することができました。本日のプロ野球オープン戦の実況中継ustream配信も、鮮明な映像だったと思います。
いちおう、参考までに、回線速度も計測しておきましたが、結果良好でしたね。
◆終わりに
今回は、ネットワーク仮想化の実践活用として基本的なVxLAN環境構築しました。本来のネットワーク仮想化では、MTU調整などをしっかり設計しておかないとフラグメンテーションの多発によるトラフィック性能劣化が発生するはずなのですが、MTUもデフォルト値のままにも関わらず、データプレーンのパフォーマンス劣化を体感することもなく、良好な結果だったと思います。最近のOpenvSwitchでは、オーバレイなカプセル処理によるパケット転送もカーネルモジュールで動作するようになったため、処理能力は昔と比べても、大幅に改善しているようです。
今後は、実践活用における運用面として、環境構築オートメーション化などの対応について、もっと深堀しておきたいところです。
OpenFlow簡易ルータの実践活用(3) 〜LinuxボックスでOpenFlowスイッチ構築編〜
最近、SDN業界では、ホワイトボックス版Linuxベースのオープンなネットワーク機器をデプロイする動きが活発ですよね。
ネットワークにダウンサイジングの波 - [1]スイッチの「オープン化」と「スケールアウト」が進む:ITpro
ネットワークにダウンサイジングの波 - [3]ホワイトボックスに賭ける、ACCESSとPica8の挑戦:ITpro
そこで、これまでの技術ブログ活動の集大成として、ホワイトボックス版OpenFlowスイッチによるOpenFlow簡易ルータを自宅ネットワークに導入してみるチャレンジに取り組んでみたいと思います。
◆OpenFlow簡易ルータのハードウェア構成
今後、OpenFlowスイッチの量産化を意識して、OpenFlowルータの物理構成としての要求条件について、優先順位の高いものから選定ポイントを挙げてみます。
(1)複数の物理NICが搭載していること(何は、さておきといった感じです)
(2)Debian系Linuxが動作すること(オープン版スイッチは、Debian系が有望とのことなので...)
(3)なるべく、安価であること(小遣いから工面するわけですから)
(4)見た目がルータ機器っぽいこと(見栄えって案外と重要ですよね)
(5)基本構成として、なるべく汎用性が高いこと(動作実績などを重視したいところなんですけど...)
◆ハードウェアの製品選定
これが、予想通り(?)に難航しました。
世の中、多NICポート搭載の小型Linuxボックスって、なかなか見つからない...
個人的な財力があれば、「OpenBlocks AX3」あたりを選定したいところなんですが...
そんな折に、¥12,800 (税込)で4ポートGigabitEthernet搭載のLinuxボックスを見つけました。
株式会社ネクスコム・ジャパン - 産業用ファンレスコンピュータ, Panel PC, 産業用無線LAN, PCベースFA制御, マシンオートメーション, 車載用テレマティクスPC, デジタルサイネージ, ネットワーク&コミュニケーション関連, IP Camera
(1)〜(4)の条件は、満たしておりますね。
(5)は、こちらのブログ記事でも記載されてますように、HDD用の電源ケーブルとVGAケーブルが汎用製品ではないという課題がありそうですが、即買いしてOpenFlow簡易ルータの導入に着手しました。
DNA940にFreeBSD10.0-RELEASEをインストールする: AliceSystem開発日記
◆OpenFlow簡易ルータの外観
実際に構築したLinuxボックスは、こんな感じです。
ちなみに、汎用品が見当たらないケーブル類は、@wakadannacomさんの助け舟により幸運にもゲットすることができました。
- 16pin→DIN15pin変換VGAケーブル
- 電源変換ケーブル 4ピン(メス)->SATA15ピン(メス)
◆Linuxインストールの留意点
Debian系Linuxとして、Ubuntu Server版をインストールしました。
ここでの落とし穴は、DNA940搭載CPUは、”Intel® Celeron® M 600MHz”ということなので、PAE非搭載CPUだということですね。
こちらの技術ブログに記載されているように、このままでは、Ubuntu 12.04 LTSをインストールすることができません。
PAE非搭載CPUで使えるLinux » のろまのひでっち ウェブサイト
そこで、敢えて、11.10をインストールした上で、12.04にupgradeしました。
upgrade from 11.10 to 12.04 - No upgrade option available in update manager - Ask Ubuntu
◆自宅ネットワークへの導入形態
Linuxボックスの導入形態は、こちらの構成になります。
1. Ryuコントローラの環境構築
まずは、Ryuコントローラ構築からはじめます。
$ sudo apt-get -y install python-pip python-dev libxml2-dev libxslt1-dev python-lxml $ sudo pip install ryu
2. OpenvSwitch(2.0.1)の環境構築
最近、OpenvSwitch(2.0.1)がリリースされたみたいです。
以下に構築メモを掲載しておきます。
$ uname -a Linux OFS 3.2.0-60-generic #91-Ubuntu SMP Wed Feb 19 03:55:18 UTC 2014 i686 i686 i386 GNU/Linux tsubo@OFS:~$ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=12.04 DISTRIB_CODENAME=precise DISTRIB_DESCRIPTION="Ubuntu 12.04.4 LTS" $ wget http://openvswitch.org/releases/openvswitch-2.0.1.tar.gz $ tar zxvf openvswitch-2.0.1.tar.gz $ rm openvswitch-2.0.1.tar.gz $ cd openvswitch-2.0.1 $ sudo apt-get install build-essential fakeroot $ dpkg-checkbuilddeps dpkg-checkbuilddeps: Unmet build dependencies: debhelper (>= 8) autoconf (>= 2.64) automake (>= 1.10) | automake1.10 libssl-dev python-all (>= 2.6.6-3~) python-qt4 python-twisted-conch $ sudo apt-get install debhelper autoconf automake libssl-dev python-all python-qt4 python-twisted-conch $ dpkg-checkbuilddeps $ sudo fakeroot debian/rules binary $ cd .. $ sudo dpkg -i openvswitch-common_2.0.1-1_i386.deb openvswitch-switch_2.0.1-1_i386.deb Selecting previously unselected package openvswitch-common. (Reading database ... 62168 files and directories currently installed.) Unpacking openvswitch-common (from openvswitch-common_2.0.1-1_i386.deb) ... Selecting previously unselected package openvswitch-switch. Unpacking openvswitch-switch (from openvswitch-switch_2.0.1-1_i386.deb) ... Setting up openvswitch-common (2.0.1-1) ... Processing triggers for man-db ... Setting up openvswitch-switch (2.0.1-1) ... FATAL: Module openvswitch not found. * Inserting openvswitch module * /etc/openvswitch/conf.db does not exist * Creating empty database /etc/openvswitch/conf.db * Starting ovsdb-server * Configuring Open vSwitch system IDs FATAL: Module openvswitch not found. * Inserting openvswitch module * Enabling remote OVSDB managers Processing triggers for ureadahead ... $ cd openvswitch-2.0.1 $ sudo apt-get install libtool autopoint $ ./boot.sh $ ./configure --with-linux=/lib/modules/`uname -r`/build $ make $ ls -la ./datapath/linux/openvswitch.ko -rw-rw-r-- 1 tsubo tsubo 4107386 Mar 9 10:39 ./datapath/linux/openvswitch.ko $ modinfo ./datapath/linux/openvswitch.ko filename: ./datapath/linux/openvswitch.ko version: 2.0.1 license: GPL description: Open vSwitch switching datapath srcversion: EEA0E974ABDD9576BE7716E depends: libcrc32c,gre vermagic: 3.2.0-60-generic SMP mod_unload modversions 686 $ sudo make modules_install cd datapath/linux && make modules_install make[1]: Entering directory `/home/tsubo/openvswitch-2.0.1/datapath/linux' make -C /lib/modules/3.2.0-60-generic/build M=/home/tsubo/openvswitch-2.0.1/datapath/linux modules_install make[2]: Entering directory `/usr/src/linux-headers-3.2.0-60-generic' INSTALL /home/tsubo/openvswitch-2.0.1/datapath/linux/openvswitch.ko DEPMOD 3.2.0-60-generic make[2]: Leaving directory `/usr/src/linux-headers-3.2.0-60-generic' depmod `sed -n 's/#define UTS_RELEASE "\([^"]*\)"/\1/p' /lib/modules/3.2.0-60-generic/build/include/generated/utsrelease.h` make[1]: Leaving directory `/home/tsubo/openvswitch-2.0.1/datapath/linux' $ sudo modprobe gre $ sudo modprobe libcrc32c $ sudo insmod ./datapath/linux/openvswitch.ko $ lsmod|grep open openvswitch 75156 0 libcrc32c 12543 1 openvswitch gre 12853 1 openvswitch $ sudo vi /etc/network/interfaces ———————— auto eth0 iface eth0 inet static address 192.168.0.1 netmask 255.255.255.0 auto eth1 iface eth1 inet manual up ifconfig $IFACE 0.0.0.0 up up ip link set $IFACE promisc on down ip link set $IFACE promisc off down ifconfig $IFACE down auto eth2 iface eth2 inet manual up ifconfig $IFACE 0.0.0.0 up up ip link set $IFACE promisc on down ip link set $IFACE promisc off down ifconfig $IFACE down ———————— $ sudo reboot $ sudo ovs-vsctl add-br br0 $ sudo ovs-vsctl add-port br0 eth1 $ sudo ovs-vsctl add-port br0 eth2 $ sudo ovs-vsctl set-controller br0 tcp:192.168.0.100:6633 $ sudo ovs-vsctl set bridge br0 other-config:datapath-id=0000000000000001 $ sudo ovs-vsctl set bridge br0 protocols=OpenFlow13
datapath-idもデフォルト値を使用せず、敢えて、「0000000000000001」を前提としております。
OpenvSwitch設定パラメータは以下の通りです。
(OpenFlowチャネルも、昔のポート番号6633のままとしております)
3. OpenFlow簡易ルータの動作準備
ここからは、PC版OpenvSwitchによるOpenFlow簡易ルータの動作準備とまったく同一ですが、いちおう再掲しておきます。
Ryu SDN Frameworkが動作する環境に、OpenFlow簡易ルータのプログラム一式を以下のサイトからダウンロードした上で、 Ryuコントローラを起動します。
Release OpenFlow簡易ルータ(基本動作版) · ttsubo/simpleRouter · GitHub
- Ryuコントローラの起動
$ cd simpleRouter-0.1/ryu-app/ $ ryu-manager openflowRouter.py loading app openflowRouter.py loading app ryu.controller.ofp_handler loading app ryu.controller.ofp_handler creating context wsgi instantiating app None of SimpleMonitor creating context monitor instantiating app openflowRouter.py of OpenflowRouter instantiating app ryu.controller.ofp_handler of OFPHandler (10256) wsgi starting up on http://0.0.0.0:8080/
4. OpenFlow簡易ルータのアドレス等の設定
OpenFlow簡易ルータの物理ポートにIPアドレスを付与して、デフォルトゲートウェイ設定を行います。通常のルータ機器であれば、CLIで実施する作業でしょうけど、ここでは、RESTful-IFにて、パラメータ設定を行っております。
注)ポート番号とIPアドレスの対応付けは、ここで指定することになります。よって、実際の物理ポートとケーブル結線が一致していないと通信できません。
- eth1側の物理ポート設定
$ curl -s -X POST -d '{"interface": {"macaddress": "00:00:00:00:00:01", "ipaddress": "192.168.100.100", "port": "1", "opposite_ipaddress": "192.168.100.1"}}' http://localhost:8080/openflow/0000000000000001/interface | python -mjson.tool { "id": "0000000000000001", "interface": { "ipaddress": "192.168.100.100", "macaddress": "00:00:00:00:00:01", "opposite_ipaddress": "192.168.100.1", "port": "1" } }
- eth2側の物理ポート設定
$ curl -s -X POST -d '{"interface": {"macaddress": "00:00:00:00:00:02", "ipaddress": "192.168.101.100", "port": "2", "opposite_ipaddress": "192.168.101.1"}}' http://localhost:8080/openflow/0000000000000001/interface | python -mjson.tool { "id": "0000000000000001", "interface": { "ipaddress": "192.168.101.100", "macaddress": "00:00:00:00:00:02", "opposite_ipaddress": "192.168.101.1", "port": "2" } }
$ curl -s -X POST -d '{"gateway": {"ipaddress": "192.168.100.1"}}' http://localhost:8080/openflow/0000000000000001/gateway | python -mjson.tool { "gateway": { "ipaddress": "192.168.100.1" }, "id": "0000000000000001" }
以上で、環境準備は終了です。
◆実際、使ってみて ...
Linuxボックスで構築したOpenFlowスイッチを介して実際にインターネットにアクセスしてみました。
結論としては、PC版OpenvSwitchと同様に、普段のインターネット利用での操作感と、まったく遜色ありませんでした。通常の検索ポータルでのキーワード検索や、YouTubeなども、普通に利用できました。
さきほど配信されていたustreamでのオープン戦のライブ映像も、ストレスなく閲覧できておりました。
あと、回線速度計測の結果も、良好でしたね。
今回の技術興味のポイントとしては、実際の通信パケットが、OpenFlowスイッチを通過する度に、Linuxボックス側のCPUがFlowエントリに従って、宛先MACアドレス,送信元MACアドレスを書き換えた上で、パケット転送処理を実施している点であり、DNA940の搭載CPU「Intel® Celeron® M 600MHz」が、パケット転送のオーバヘッドとして、「どの程度の影響を与えるか?」という点です。
結論としては、通常のインターネット利用の体感に、ほとんど影響するものではありませんでした。
(DNA940は、GigabitEthernet搭載なので、このあたりの処理限界を確認できてはおりませんが...)
◆終わりに
今回は、LinuxボックスDNA940で構築したをOpenFlowスイッチを自宅ネットワークに導入して、インターネットが利用できるところまで確認できました。結果には、大変、満足しております。
あとは、時間がゆるせば、今後、最新OpenvSwitch機能を試しておきたいところですね。
OpenFlow簡易ルータの実践活用(2) 〜LINC-Switch導入編〜
前回は、OpenvSwitch (2.0.0)で構築したOpenFlowスイッチとOpenFlow簡易ルータを、自宅ネットワークに導入してみました。
今回は、OpenFlowスイッチとして、LINC-Switchを採用して、前回と同様に自宅ネットワークに導入してみたいと思います。
◆導入形態
導入形態は、前回とまったく同様の構成になります。
OpenFlow簡易ルータの実践活用(1) 〜OpenvSwitch導入編〜 - SDN開発エンジニアを目指した活動ブログ
1. Ryuコントローラの最新化
Ryuコントローラのインストールが最近行われていない場合は、後述のof_configが失敗する可能性があります。
私のRyuコントローラ環境では、lxmlをアップグレードすることでof_configが使用できるようになりました。
$ sudo pip install lxml --upgrade
2. LINC-Switchの環境構築
つぎに、LINC-Switch環境手順です。
こちらのブログ記事を参考にさせて頂きました。
Raspberry Piで家庭内LANをOpenFlow化 (part 1) | d.yasukun
LINC-Switchのインストールが完了したら、早速、LINC-Switchを起動してみます。
$ sudo LINC-Switch/rel/linc/bin/linc console Exec: /home/tsubo/LINC-Switch/rel/linc/erts-5.10.4/bin/erlexec -boot /home/tsubo/LINC-Switch/rel/linc/releases/1.0/linc -mode embedded -config /home/tsubo/LINC-Switch/rel/linc/releases/1.0/sys.config -args_file /home/tsubo/LINC-Switch/rel/linc/releases/1.0/vm.args -- console Root: /home/tsubo/LINC-Switch/rel/linc Erlang R16B03-1 (erts-5.10.4) [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] 22:09:22.086 [info] Application lager started on node linc@OFS 22:09:22.087 [info] Application ssh started on node linc@OFS 22:09:22.087 [info] Application enetconf started on node linc@OFS 22:09:22.125 [info] Application linc started on node linc@OFS Eshell V5.10.4 (abort with ^G) (linc@OFS)1> 22:09:22.158 [info] Created port: {port,1,[{queues_status,disabled},{queues,[]},{config,{port_configuration,undefined,up,false,false,false}},{features,{features,undefined,'100Mb-FD',true,copper,unsupported}},{queues,[]},{interface,"eth2"}]} 22:09:22.194 [info] Created port: {port,2,[{queues_status,disabled},{queues,[]},{config,{port_configuration,undefined,up,false,false,false}},{features,{features,undefined,'100Mb-FD',true,copper,unsupported}},{queues,[]},{interface,"eth1"}]}
3. of_configによるdatapath-idの変更
LINC-Switchのdatapath-idは、デフォルト値を使用せず、「0000000000000001」に変更する必要があります。
LINC-Switchでは、of-configによりdatapath-idを変更できるようです。
Ryuコントローラも、of_configに対応しておりますので、今回は、of_config用pythonスクリプトで対応します。
from ryu.lib.of_config.capable_switch import OFCapableSwitch import time sess = OFCapableSwitch( host='192.168.0.1', port=1830, username='linc', password='linc', unknown_host_cb=lambda host, fingeprint: True) #------------------------------------------- # edit_config " #------------------------------------------- csw = sess.get_config('running') for p in csw.logical_switches.switch: p.datapath_id = '00:00:00:00:00:01:00:00' sess.edit_config('running', csw) time.sleep(3) #------------------------------------------- # get_config " #------------------------------------------- csw = sess.get_config('running') for p in csw.logical_switches.switch: print p
of_config用pythonスクリプトを、Ryuコントローラから起動します。
$ python of_config.py OFLogicalSwitchType(capabilities=None,check_controller_certificate=None,controllers=OFLogicalSwitchControllersType(controller=[OFControllerType(id='Switch0-DefaultController',ip_address='192.168.0.100',local_ip_address=None,local_port=None,port=6633,protocol='tcp',role='equal',state=OFControllerStateType(connection_state='down',current_version=None,local_ip_address_in_use=None,local_port_in_use=None,supported_versions=[1.3]))]),datapath_id='00:00:00:00:00:01:00:00',enabled=None,id='LogicalSwitch0',lost_connection_behavior=None,resources=OFLogicalSwitchResourcesType(certificate=None,flow_table=[],port=['LogicalSwitch0-Port2', 'LogicalSwitch0-Port1'],queue=[])) $
4. OpenFlow簡易ルータの動作準備
ここからは、前回とまったく同様の手順です。
Ryu SDN Frameworkが動作する環境に、OpenFlow簡易ルータのプログラム一式を以下のサイトからダウンロードした上で、 Ryuコントローラを起動します。
Release OpenFlow簡易ルータ(基本動作版) · ttsubo/simpleRouter · GitHub
- Ryuコントローラの起動
$ cd simpleRouter-0.1/ryu-app/ $ ryu-manager openflowRouter.py loading app openflowRouter.py loading app ryu.controller.ofp_handler loading app ryu.controller.ofp_handler creating context wsgi instantiating app None of SimpleMonitor creating context monitor instantiating app openflowRouter.py of OpenflowRouter instantiating app ryu.controller.ofp_handler of OFPHandler (10256) wsgi starting up on http://0.0.0.0:8080/
- eth1側の物理ポート設定
$ curl -s -X POST -d '{"interface": {"macaddress": "00:00:00:00:00:01", "ipaddress": "192.168.100.100", "port": "1", "opposite_ipaddress": "192.168.100.1"}}' http://localhost:8080/openflow/0000000000000001/interface | python -mjson.tool { "id": "0000000000000001", "interface": { "ipaddress": "192.168.100.100", "macaddress": "00:00:00:00:00:01", "opposite_ipaddress": "192.168.100.1", "port": "1" } }
- eth2側の物理ポート設定
$ curl -s -X POST -d '{"interface": {"macaddress": "00:00:00:00:00:02", "ipaddress": "192.168.101.100", "port": "2", "opposite_ipaddress": "192.168.101.1"}}' http://localhost:8080/openflow/0000000000000001/interface | python -mjson.tool { "id": "0000000000000001", "interface": { "ipaddress": "192.168.101.100", "macaddress": "00:00:00:00:00:02", "opposite_ipaddress": "192.168.101.1", "port": "2" } }
$ curl -s -X POST -d '{"gateway": {"ipaddress": "192.168.100.1"}}' http://localhost:8080/openflow/0000000000000001/gateway | python -mjson.tool { "gateway": { "ipaddress": "192.168.100.1" }, "id": "0000000000000001" }
以上で、環境準備は終了です。
◆iperfを用いたスループットの計測
LINC-Switchのパフォーマンスを測ってみました。
- iperf確認結果(MacBook Air側)
$ iperf -c 192.168.100.1 ------------------------------------------------------------ Client connecting to 192.168.100.1, TCP port 5001 TCP window size: 129 KByte (default) ------------------------------------------------------------ [ 4] local 192.168.101.1 port 62192 connected with 192.168.100.1 port 5001 [ ID] Interval Transfer Bandwidth [ 4] 0.0-10.0 sec 110 MBytes 92.0 Mbits/sec
- iperf確認結果(ThinkPad T61側)
$ iperf -c 192.168.101.1 ------------------------------------------------------------ Client connecting to 192.168.101.1, TCP port 5001 TCP window size: 23.5 KByte (default) ------------------------------------------------------------ [ 3] local 192.168.100.1 port 59915 connected with 192.168.101.1 port 5001 [ ID] Interval Transfer Bandwidth [ 3] 0.0-10.0 sec 110 MBytes 92.1 Mbits/sec
計測結果としては、前回のOpenvSwitchと、ほぼ同等のTCPスループットでした。
- ping確認結果(MacBook Air側)
$ ping 192.168.100.1 PING 192.168.100.1 (192.168.100.1): 56 data bytes 64 bytes from 192.168.100.1: icmp_seq=0 ttl=64 time=1.465 ms 64 bytes from 192.168.100.1: icmp_seq=1 ttl=64 time=1.792 ms 64 bytes from 192.168.100.1: icmp_seq=2 ttl=64 time=1.549 ms 64 bytes from 192.168.100.1: icmp_seq=3 ttl=64 time=1.577 ms 64 bytes from 192.168.100.1: icmp_seq=4 ttl=64 time=2.072 ms ^C --- 192.168.100.1 ping statistics --- 5 packets transmitted, 5 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 1.465/1.691/2.072/0.219 ms
◆実際、使ってみて ...
LINC-Switchを介して実際にインターネットにアクセスしてみました。
使い勝手としては、前回のOpenvSwitchよりも、Webブラウジングのレスポンス性が芳しくありませんでした。
Safariのブラウザからだと、通常の検索ポータルでのキーワード検索や、ustreamが利用できましたが、操作感はストレスを感じるものでした。
なお、firefoxのブラウザだと、軒並み以下のエラー画面が表示されてしまいました。
◆OpenvSwitchとのスピードテスト結果の比較
インターネット上のスピードテストを計測できるサイトを活用して、OpenvSwitchとLINC-Switchの回線速度を比較してみました。
使用したスピード計測サイトを以下となります。
BNR スピードテスト 回線速度/通信速度 測定
1. LINC-Switchの場合
昔のダイアルアップ接続の回線速度と同程度という結果でした。
やはり、LINC-Switchはユーザランドでパケット転送処理を実施しているため、回線速度の低下してしまうということでしょうか
◆終わりに
LINC-Switchを実際に使ってみて、ちょっと、実用性は低そうです。
ただ、OpenFlowコントローラの勉強用(デバック用)として活用する場合には、とても利用価値が高い製品だと思います。
OpenFlow簡易ルータの実践活用(1) 〜OpenvSwitch導入編〜
前回まで、Ryu SDN Frameworkを活用したOpenFlow簡易ルータ作成を行ってきましたが、OpenFlow勉強の素材として、当初想定していた必要機能は一通り具備できたと思います。早速、OpenFlow簡易ルータを自宅ネットワークに導入して、その使い勝手を確認してみたいと思います。
◆導入形態
OpenFlow簡易ルータの自宅ネットワークへの導入形態としては、新たなサブネットと既存サブネットとをゲートウェイ的に相互接続し、新セグメント上に配備したMacBookからインターネットにアクセスできる形態を目指します。
◆導入にあたっての準備
OpenFlowコントローラやOpenFlowスイッチを動作できる環境を構築します。
また、自宅ネットワーク側でのBBルータでのルーティング追加などが必要ですが、ここでは設定方法などは割愛します。
1. Ryuコントローラの環境構築
まずは、Ryuコントローラ構築からはじめます。
$ sudo apt-get -y install python-pip python-dev libxml2-dev libxslt1-dev python-lxml $ sudo pip install ryu
2. OpenvSwitch(2.0.0)の環境構築
つぎに、OpenvSwitch環境手順ですが、こちらのブログ記事を参考にさせて頂きました。本来であれば、Ubuntu Server版でOpenvSwitchを構築すべきなんですが、今回が初回ということもあり、環境構築の準備中に、Wiresharkを動作させたかったので、まずは実績つくりを優先してDesktop版を使用しました。
Ubuntu-12.04.3にopenvswitch-2.0.0をインストール | 迷い庭
あと、datapath-idもデフォルト値を使用せず、敢えて、「0000000000000001」を前提としております。
OpenvSwitch設定パラメータは以下の通りです。
(OpenFlowチャネルも、昔のポート番号6633のままとしております)
$ sudo ovs-vsctl add-br br0 $ sudo ovs-vsctl add-port br0 eth1 $ sudo ovs-vsctl add-port br0 eth2 $ sudo ovs-vsctl set-controller br0 tcp:192.168.0.100:6633 $ sudo ovs-vsctl set bridge br0 other-config:datapath-id=0000000000000001 $ sudo ovs-vsctl set bridge br0 protocols=OpenFlow13
3. OpenFlow簡易ルータの動作準備
Ryu SDN Frameworkが動作する環境に、OpenFlow簡易ルータのプログラム一式を以下のサイトからダウンロードした上で、 Ryuコントローラを起動します。
Release OpenFlow簡易ルータ(基本動作版) · ttsubo/simpleRouter · GitHub
- Ryuコントローラの起動
$ cd simpleRouter-0.1/ryu-app/ $ ryu-manager openflowRouter.py loading app openflowRouter.py loading app ryu.controller.ofp_handler loading app ryu.controller.ofp_handler creating context wsgi instantiating app None of SimpleMonitor creating context monitor instantiating app openflowRouter.py of OpenflowRouter instantiating app ryu.controller.ofp_handler of OFPHandler (10256) wsgi starting up on http://0.0.0.0:8080/
OpenFlow簡易ルータの物理ポートにIPアドレスを付与して、デフォルトゲートウェイ設定を行います。通常のルータ機器であれば、CLIで実施する作業でしょうけど、ここでは、RESTful-IFにて、パラメータ設定を行っております。
注)ポート番号とIPアドレスの対応付けは、ここで指定することになります。よって、実際の物理ポートとケーブル結線が一致していないと通信できません。
- eth1側の物理ポート設定
$ curl -s -X POST -d '{"interface": {"macaddress": "00:00:00:00:00:01", "ipaddress": "192.168.100.100", "port": "1", "opposite_ipaddress": "192.168.100.1"}}' http://localhost:8080/openflow/0000000000000001/interface | python -mjson.tool { "id": "0000000000000001", "interface": { "ipaddress": "192.168.100.100", "macaddress": "00:00:00:00:00:01", "opposite_ipaddress": "192.168.100.1", "port": "1" } }
- eth2側の物理ポート設定
$ curl -s -X POST -d '{"interface": {"macaddress": "00:00:00:00:00:02", "ipaddress": "192.168.101.100", "port": "2", "opposite_ipaddress": "192.168.101.1"}}' http://localhost:8080/openflow/0000000000000001/interface | python -mjson.tool { "id": "0000000000000001", "interface": { "ipaddress": "192.168.101.100", "macaddress": "00:00:00:00:00:02", "opposite_ipaddress": "192.168.101.1", "port": "2" } }
$ curl -s -X POST -d '{"gateway": {"ipaddress": "192.168.100.1"}}' http://localhost:8080/openflow/0000000000000001/gateway | python -mjson.tool { "gateway": { "ipaddress": "192.168.100.1" }, "id": "0000000000000001" }
◆OpenFlow簡易ルータの動作確認
基本的な準備が完了したところで、正しくOpenFlow簡易ルータが動作しているかを確認してみましょう。
なお、動作確認で使用したスクリプトは、こちらから利用可能です。
simpleRouter/rest-client at master · ttsubo/simpleRouter · GitHub
(1) Arpテーブル確認
: 物理ポート毎の接続先ホスト(MacBook, BBルータ)のMacアドレスが取得できていることを確認します。
$ ./get_arp.sh /openflow/0000000000000001/arp ----------------------------------------------------------- reply: 'HTTP/1.1 200 OK\r\n' header: Content-Type: application/json; charset=UTF-8 header: Content-Length: 238 header: Date: Sat, 01 Mar 2014 23:25:44 GMT +++++++++++++++++++++++++++++++ 2014/03/02 08:25:44 : ArpTable +++++++++++++++++++++++++++++++ portNo MacAddress IpAddress -------- ----------------- ------------ 1 10:66:82:93:c4:f0 192.168.100.1 2 7c:c3:a1:87:8f:65 192.168.101.1
注)さきほど、RESTful-IFで設定したポート番号とIPアドレスの対応付けが、実際の物理ポートとケーブル結線が一致していない場合には、Arpテーブルに該当情報が表示されません。
◆実際、使ってみて ...
OpenFlow簡易ルータの動作確認を終了したので、いよいよ、実際にインターネットにアクセスしてみました。
結論としては、普段のインターネット利用での操作感と、まったく遜色ありませんでした。
通常の検索ポータルでのキーワード検索や、YouTubeなども、普通に利用できました。
今朝のustreamでの鈴鹿サーキット公式レースのライブ映像も、ストレスなく閲覧できておりました。
あと、ざっくりですが、OpenvSwitchでのトラフィックカウンタも確認してみました。
(1) PortStats確認
: 物理ポート毎のトラフィックカウンタが取得できていることを確認しました
$ ./get_port_stats.sh /openflow/0000000000000001/stats/port ----------------------------------------------------------- reply: 'HTTP/1.1 200 OK\r\n' header: Content-Type: application/json; charset=UTF-8 header: Content-Length: 443 header: Date: Sat, 01 Mar 2014 23:35:25 GMT +++++++++++++++++++++++++++++++ 2014/03/02 08:35:25 : PortStats +++++++++++++++++++++++++++++++ portNo rxPackets rxBytes rxErrors txPackets txBytes txErrors -------- --------- -------- -------- --------- -------- -------- 1 31631 41554372 0 16960 2475911 0 2 17342 2553369 0 30423 41169870 0 fffffffe 10 844 0 164 38702 0
(2) FlowStats確認
: Flowエントリ毎のトラフィックカウンタが取得できていることを確認しました
$ ./get_flow_stats.sh /openflow/0000000000000001/stats/flow ----------------------------------------------------------- reply: 'HTTP/1.1 200 OK\r\n' header: Content-Type: application/json; charset=UTF-8 header: Content-Length: 454 header: Date: Sat, 01 Mar 2014 23:35:32 GMT +++++++++++++++++++++++++++++++ 2014/03/02 08:35:32 : FlowStats +++++++++++++++++++++++++++++++ inPort ethSrc ethDst ipv4Dst packets bytes -------- ------------------ ------------------ --------------- -------- -------- 1 10:66:82:93:c4:f0 00:00:00:00:00:01 192.168.101.1 29859 41033174 2 7c:c3:a1:87:8f:65 00:00:00:00:00:02 192.168.100.1 159 13110 * * * 0.0.0.0/0 17345 2659435
◆簡単な動作検証
iperf等でOpenFlow簡易ルータの簡単なパフォーマンスを測ってみました。
(ちなみに、ここでの通信はすべて、Flowエントリに基づいた転送処理になっています。)
- iperf確認結果(MacBook Air側)
$ iperf -c 192.168.100.1 ------------------------------------------------------------ Client connecting to 192.168.100.1, TCP port 5001 TCP window size: 129 KByte (default) ------------------------------------------------------------ [ 4] local 192.168.101.1 port 57447 connected with 192.168.100.1 port 5001 [ ID] Interval Transfer Bandwidth [ 4] 0.0-10.0 sec 112 MBytes 94.3 Mbits/sec
- iperf確認結果(ThinkPad T61側)
$ iperf -c 192.168.101.1 ------------------------------------------------------------ Client connecting to 192.168.101.1, TCP port 5001 TCP window size: 23.5 KByte (default) ------------------------------------------------------------ [ 3] local 192.168.100.1 port 51676 connected with 192.168.101.1 port 5001 [ ID] Interval Transfer Bandwidth [ 3] 0.0-10.0 sec 114 MBytes 95.2 Mbits/sec
- ping確認結果(MacBook Air側)
$ ping 192.168.100.1 PING 192.168.100.1 (192.168.100.1): 56 data bytes 64 bytes from 192.168.100.1: icmp_seq=0 ttl=64 time=0.907 ms 64 bytes from 192.168.100.1: icmp_seq=1 ttl=64 time=0.989 ms 64 bytes from 192.168.100.1: icmp_seq=2 ttl=64 time=0.908 ms 64 bytes from 192.168.100.1: icmp_seq=3 ttl=64 time=0.873 ms 64 bytes from 192.168.100.1: icmp_seq=4 ttl=64 time=0.892 ms 64 bytes from 192.168.100.1: icmp_seq=5 ttl=64 time=1.196 ms ^C --- 192.168.100.1 ping statistics --- 6 packets transmitted, 6 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.873/0.961/1.196/0.111 ms
◆終わりに
実際にOpenFlow簡易ルータを使ってみて、想定通りの動作を確認できました。
前回まで、仮想VM環境で同等の動作確認を行ってきたわけですし、OpenvSwitch動作環境として、それなりのスペックを取り揃えたわけですから、今回の結果は最初から想定できた内容なのですが、実際に実機と繋がったワクワク感は、純粋に楽しいですよね。まあ、今後の課題は、如何にコモディティ化を図った安価な機器に置き換えられるというところでしょうけど ...
あと、Mininet環境だと、ちゃんと動作したのに実機だと想定どおり動作しない場面もよく遭遇しまよね。この時のトラブルシューティング経験が、SDN開発エンジニアとしての技術知識の糧になるものだと思いますので、これからも実機での作業を大切にしていきたいです。
次回からは、OpenFlowスイッチとして、LINC-Switch環境を導入していきたいと思います。