準備
OpenvSwitchはOpenstackでも登場しました、仮想ソフトウェアスイッチです。
OpenFlowスイッチがないとOpenFlow実践入門を読んでいても物足りない内容になってしまうので、こやつにOpenFlowスイッチの役割をしてもらうのです。
必要な物といっても、Mac上にVirtualBoxでUbuntuサーバーを2台ほど建てて、片方にTremaをインストールしたOpenFlowコントローラ。
もう片方にOpenvSwitchをインストールしたOpenFlowスイッチとして準備をしました。
2台用意しなくても、OpenFlowコントローラにループバックアドレスを指定することで1台でも実験可能なようでした。
VirtualBoxの設定
コントローラーの方はNIC2個、スイッチの方はNIC4個で設定します。
eth0/eth1は割り当てをブリッジにして、eth0はExternal用、eth1はInternal用にしました。
スイッチ側のeth2/eth3は割り当ては内部ネットワークにします。理由はまた後で書きますが、ブリッジにして設定投入したあとにリンクアップしますと、いつぞややらかしたL2のストリームを起こしてしまうのです。
OpenvSwitchでSTPを有効にすれば回避できますが、Tremaの検証がメインなのでいまのところは内部ネットワークでもいいかなと。
Ubuntuのセットアップを済ますとeth0だけしか表示されない!と思うかもしれませんが
下のようになっていれば問題ないです。
takeken@ubuntu:~$ sudo dmesg | egrep "eth0|eth1|eth2|eth3" [ 1.059113] e1000 0000:00:03.0 eth0: (PCI:33MHz:32-bit) 08:00:27:c4:9b:47 [ 1.060425] e1000 0000:00:03.0 eth0: Intel(R) PRO/1000 Network Connection [ 1.445182] e1000 0000:00:08.0 eth1: (PCI:33MHz:32-bit) 08:00:27:cb:89:41 [ 1.445648] e1000 0000:00:08.0 eth1: Intel(R) PRO/1000 Network Connection [ 1.812034] e1000 0000:00:09.0 eth2: (PCI:33MHz:32-bit) 08:00:27:cc:7c:63 [ 1.812946] e1000 0000:00:09.0 eth2: Intel(R) PRO/1000 Network Connection [ 2.175457] e1000 0000:00:0a.0 eth3: (PCI:33MHz:32-bit) 08:00:27:0c:1a:76 [ 2.177221] e1000 0000:00:0a.0 eth3: Intel(R) PRO/1000 Network Connection [ 13.445309] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready [ 13.446176] e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX [ 13.446585] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
OpenvSwitchのインストールは
openvswitch-switch
で完了ですが、検証中に色々と入れたり消したりを繰り返していたのでもしかしたら上手くいかないケースがあるかもしれません。そうなったらごめんなさい。
ただカーネルモジュールがちゃんと認識されていれば大丈夫かなと思ったり。
takeken@ubuntu:~$ sudo lsmod | grep openvswitch openvswitch 65844 0 gre 13796 1 openvswitch vxlan 37629 1 openvswitch libcrc32c 12644 1 openvswitch
後はipv6は無効にしてていいかも。
/etc/sysctl.conf net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1
設定ファイル
コントローラ側のネットワークの設定ファイルはこんな感じで。
# The loopback network interface auto lo iface lo inet loopback # The primary network interface auto eth0 iface eth0 inet static address 192.168.24.55 network 192.168.24.0 netmask 255.255.255.0 broadcast 192.168.24.255 gateway 192.168.24.1 dns-nameservers 192.168.24.1 auto eth1 iface eth1 inet static address 192.168.10.10 netmask 255.255.255.0 network 192.168.10.0 broadcast 192.168.10.255
スイッチ側のネットワーク設定ですが、ブリッジの設定方法に2通りあり、コマンドで投入する方法と、この/etc/network/interfaceに記述してしまう方法とがあります。
個人的な好みで/etc/network/interfaceに書き込みました。
# The loopback network interface auto lo iface lo inet loopback # The primary network interface auto eth0 iface eth0 inet static address 192.168.24.70 network 192.168.24.0 netmask 255.255.255.0 broadcast 192.168.24.255 gateway 192.168.24.1 dns-nameservers 192.168.24.1 auto eth1 iface eth1 inet static address 192.168.10.20 netmask 255.255.255.0 network 192.168.10.0 broadcast 192.168.10.255 allow-ovs ovsbr0 iface ovsbr0 inet manual ovs_type OVSBridge ovs_ports eth2 eth3 allow-ovsbr0 eth2 iface eth2 inet manual ovs_bridge ovsbr0 ovs_type OVSPort allow-ovsbr0 eth3 iface eth3 inet manual ovs_bridge ovsbr0 ovs_type OVSPort
ではこれで進めていきますか。
Ubuntuサーバー構築から進めていた場合は、Kernelやパッケージの更新も入っているかもしれませんので、ここらで再起動しておくのもいいかもしれませんね。
不安な場合はVirtualBoxの必殺技、スナップショットを保存しておくのもいいね。
設定投入
ブリッジの設定ですが、/etc/network/interfaceに記述していた方は、再起動したら出来上がっているかもですが
いったんifdownしてifupしたら完了です。
takeken@switch:~$ sudo ifup --allow=ovs ovsbr0 takeken@switch:~$ sudo ovs-vsctl show fbecfea7-65c4-493c-b437-d38d0001312f Bridge "ovsbr0" Port "eth3" Interface "eth3" Port "eth2" Interface "eth2" Port "ovsbr0" Interface "ovsbr0" type: internal ovs_version: "2.0.2"
コマンドで設定する場合は以下の様な感じです。
sudo ovs-vsctl add-br br0 sudo ovs-vsctl add-port br0 eth1 sudo ovs-vsctl add-port br0 eth2
後はコントローラーを設定すれば完了です。
もう完了です。数日やってますが、まとめてしまうと速いですねw
コントローラーの設定ですが、ポートの指定をしないとぼくの環境では上手くいかなかったので、まずはTremaを実行したときのポートを確認します。
takeken@ubuntu:~$ trema run ./rhave.rb & [1] 1536 takeken@ubuntu:~$ sudo ps aux | grep trema takeken 1536 7.0 2.4 77572 25096 pts/0 Sl 16:10 0:00 /usr/bin/ruby1.9.1 /usr/local/bin/trema run ./rhave.rb takeken 1540 0.0 0.1 15144 1640 ? Ss 16:10 0:00 /var/lib/gems/1.9.1/gems/trema-0.4.7/objects/switch_manager/switch_manager --daemonize --port=6653 -- port_status::MultiRepeaterHub packet_in::MultiRepeaterHub state_notify::MultiRepeaterHub vendor::MultiRepeaterHub takeken 1545 0.0 0.2 12716 2212 pts/0 S+ 16:10 0:00 grep --color=auto trema
6653のようですね。
後はコントローラー側と、スイッチ側で疎通がちゃんと取れるかどうかを確認して、問題なければコントローラの設定を入れましょう。
スイッチ側とコントローラ側で疎通がとれることを確認しておきます。
スイッチからコントローラ takeken@switch:~$ ping -c 1 192.168.10.10 PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data. 64 bytes from 192.168.10.10: icmp_seq=1 ttl=64 time=0.363 ms --- 192.168.10.10 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.363/0.363/0.363/0.000 ms コントローラからスイッチ takeken@ubuntu:~$ ping -c 1 192.168.10.20 PING 192.168.10.20 (192.168.10.20) 56(84) bytes of data. 64 bytes from 192.168.10.20: icmp_seq=1 ttl=64 time=0.325 ms --- 192.168.10.20 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.325/0.325/0.325/0.000 ms
オッケーですぅ。
疎通は問題ないのでセットしますか。
takeken@switch:~$ sudo ovs-vsctl get-controller ovsbr0 takeken@switch:~$ takeken@switch:~$ sudo ovs-vsctl set-controller ovsbr0 tcp:192.168.10.10:6653 takeken@switch:~$ takeken@switch:~$ sudo ovs-vsctl get-controller ovsbr0 tcp:192.168.10.10:6653 takeken@switch:~$ takeken@switch:~$ sudo ovs-vsctl show [sudo] password for takeken: fbecfea7-65c4-493c-b437-d38d0001312f Bridge "ovsbr0" Controller "tcp:192.168.10.10:6653" Port "eth3" Interface "eth3" Port "eth2" Interface "eth2" Port "ovsbr0" Interface "ovsbr0" type: internal ovs_version: "2.0.2"
それではコントローラーでリピータハブをTrema runしてみましょう!
ドキワク!
OpenvSwitchでOpenFlowスイッチの役をやってもらおう
と、そのまえに!
ここで利用するリピータハブ(※参考サイト参照)のコードとTremaについているExampleのリピータハブサンプルコードと
比較を少ししてみてリーディングしましょうか。
class RepeaterHub < Controller # Controllerクラスの継承 # def packet_in(datapath_id, message) def packet_in(datapath_id) # 引数はidだけでいいかね。 send_flow_mod_add( # エントリを書き込むためのメソッド:第7章参照 datapath_id, # :match => ExactMatch.from(message), # :actions => ActionOutput.new(OFPP_FLOOD) :actions => SendOutPort.new(OFPP_FLOOD) # SendOutPort 指定したスイッチのポートにパケットを出力する # OFPP_FLOOD 全ポートに"対する"フラッディングをおこなう ) # send_packet_out( # datapath_id, # :packet_in => message, # :actions => ActionOutput.new(OFPP_FLOOD) # ) end end
以上です。
んで実行すると、うまくコントローラーと接続できていればダンプされるはずなのです。
実行前の状態 takeken@ubuntu:~$ sudo ovs-ofctl dump-flows ovsbr0 NXST_FLOW reply (xid=0x4): 実行 takeken@ubuntu:~$ sudo trema run ./repeater-hub.rb 上手くダンプできました。 takeken@ubuntu:~$ sudo ovs-ofctl dump-flows ovsbr0 NXST_FLOW reply (xid=0x4): cookie=0x1, duration=12.912s, table=0, n_packets=20, n_bytes=1500, idle_age=0, priority=65535 actions=FLOOD
では第7章で実践しているパッチパネルを検証をしてみます。
実行前の状態 takeken@ubuntu:~$ sudo ovs-ofctl dump-flows ovsbr0 NXST_FLOW reply (xid=0x4): 実行します。ポートは2から3としています。 takeken@ubuntu:~$ trema run ./patch-panel.rb うまくダンプできました。ちゃんと指定した2と3とでています。 takeken@switch:~$ sudo ovs-ofctl dump-flows ovsbr0 NXST_FLOW reply (xid=0x4): cookie=0x2, duration=0.252s, table=0, n_packets=0, n_bytes=0, idle_age=0, priority=65535,in_port=3 actions=output:2 cookie=0x1, duration=0.252s, table=0, n_packets=0, n_bytes=0, idle_age=0, priority=65535,in_port=2 actions=output:3
これでOpenFlowスイッチがなくても第7章の検証ができました。
プログラミングの検証と割り切ればこれで問題ないはずですが、やっぱり実際にスイッチに繋いでとかやってみたいなぁと思いますよね。コンシューマの無線LANを改造して使えるそうなのでその辺もまた調べてみますか。
OpenFlowの何がすごいのかって、L2(L1もなのかな?)もプログラミングできるということに(っていうのもどこかのウェブサイトで読んだのですがw)
なったということなのれす。
番外編
最初は気付かずにストリーム発生しまくりだったんでw失敗の産物のログがあるのでちょこっと載せておきます。
何かの役に立つかも、立たないかもで。
OpenvSwitchでSTPの有効にするときは下のコマンドになります。
無効にするときはfalseですね。
sudo ovs-vsctl set bridge ovsbr0 stp_enable=true
万が一、ストリームが起こった時にはifdownを光速で叩けば復旧できます。
落とすNICの名前はそれぞれだろうから、落ちないじゃないか!ってうちに文句を言わないでおくれよ。
たとえばサーバーが近くになくてリブートしかできないっていうなら
リブートすればコマンドを叩ける余裕はあるはずなので、下のようなコマンドを叩こう。
たたたたん たたん たんた たんたん。
takeken@ubuntu:~$ sudo ifdown eth1 takeken@ubuntu:~$ sudo ifdown eth2 takeken@ubuntu:~$ sudo ifdown eth3
ただVirtualBoxでNICを落とすとか、LANケーブルを抜いた方が確実に速い。
失敗の産物のログです。
2015-04-16T04:29:35Z|00001|timeval|WARN|Unreasonably long 1014ms poll interval (0ms user, 75ms system) 2015-04-16T04:29:35Z|00002|timeval|WARN|faults: 2 minor, 0 major 2015-04-16T04:29:35Z|00003|timeval|WARN|context switches: 0 voluntary, 8 involuntary 2015-04-16T04:29:35Z|00004|coverage|INFO|Event coverage, hash=39783c6c: 2015-04-16T04:29:35Z|00005|coverage|INFO|hmap_expand 9 2015-04-16T04:29:35Z|00006|coverage|INFO|hmap_pathological 14 2015-04-16T04:29:35Z|00007|coverage|INFO|poll_fd_wait 8 2015-04-16T04:29:35Z|00008|coverage|INFO|util_xalloc 52 2015-04-16T04:29:35Z|00009|coverage|INFO|vconn_sent 2 2015-04-16T04:29:35Z|00010|coverage|INFO|vconn_received 1 2015-04-16T04:29:35Z|00011|coverage|INFO|vconn_open 2 2015-04-16T04:29:35Z|00012|coverage|INFO|stream_open 2 2015-04-16T04:29:35Z|00013|coverage|INFO|43 events never hit OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0
そんな感じで。
参考サイト
ainoniwa.net UbuntuでOpen vSwitchを使うときに/etc/network/interfacesが使える
ranosgrantのブログ 2万円で OpenFlow スイッチを自作しよう
Trema 日記 Openvswitch を OpenFlow スイッチとして使う