OpenvSwitchを使ってTremaの検証をしよう


準備

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 スイッチとして使う

Similar Posts:


Leave a Reply

Your email address will not be published. Required fields are marked *