こんな夜中にOpenFlowでネットワークをプログラミング!

第7回 【Trema編】新シリーズ始動! OpenFlow界のRailsことTrema入門

この記事を読むのに必要な時間:およそ 3 分

スイッチの起動を捕捉する

それでは,さきほど定義したスイッチを起動してコントローラから捕捉してみましょう。スイッチの起動イベントを捕捉するにはswitch_readyハンドラを書きますリスト3-①⁠。

@switchesは現在起動しているスイッチのリストを管理するインスタンス変数で,新しくスイッチが起動するとスイッチのdatapath_idが追加されます。また,putsメソッドでdatapath_idを表示します。

スイッチの切断を捕捉する

同様に,スイッチが落ちて接続が切れたイベントを捕捉してみましょう。このためのハンドラはswitch_disconnectedですリスト3-②⁠。

スイッチの切断を捕捉すると,切断したスイッチのdatapath_idをスイッチ一覧@switchesから除きます。また,datapath_idをputsメソッドで表示します。

スイッチの一覧を表示する

最後に,スイッチの一覧を定期的に表示する部分を作ります。一定時間ごとに何らかの処理を行いたい場合には,タイマー機能を使います。リスト3-③ように,一定の間隔で呼びたいメソッドと間隔(秒数)をperiodic_timer_eventで指定すると,指定されたメソッドが呼ばれます。ここでは,スイッチの一覧を表示するメソッドshow_switchesを10秒ごとに呼び出します。

実行

それでは早速実行してみましょう。仮想スイッチを3台起動する場合,リスト4の内容のファイルをswitch-monitor.confとして保存し,設定ファイルをtrema runの-cオプションに渡してください。

リスト4 仮想スイッチを3台定義

vswitch { datapath_id 0x1 }
vswitch { datapath_id 0x2 }
vswitch { datapath_id 0x3 }

実行結果は次のようになります。

% ./trema run ./switch-monitor.rb -c ./switch-monitor.
conf Switch 0x3 is UP Switch 0x2 is UP Switch 0x1 is UP All switches = 0x1, 0x2, 0x3 All switches = 0x1, 0x2, 0x3 All switches = 0x1, 0x2, 0x3 ……

switch-monitorコントローラが起動すると設定ファイルで定義した仮想スイッチ3台が起動し,switch-monitorコントローラのswitch_readyハンドラによって捕捉され,このメッセージが出力されました。

それでは,スイッチの切断がうまく検出されるか確かめてみましょう。スイッチを停止するコマンドはtrema killです。別ターミナルを開き,次のコマンドでスイッチ0x3を落としてみてください。

% ./trema kill 0x3

すると,trema run を動かしたターミナルに次の出力が表示されているはずです。

% ./trema run ./switch-monitor.rb -c ./switch-monitor.
conf Switch 0x3 is UP Switch 0x2 is UP Switch 0x1 is UP All switches = 0x1, 0x2, 0x3 All switches = 0x1, 0x2, 0x3 All switches = 0x1, 0x2, 0x3 …… Switch 0x3 is DOWN

うまくいきました! おわかりのとおり,このメッセージはswitch_disconnectedハンドラによって表示されたものです。

[友太郎の質問]datapathってなに?

Q.「こんにちは! 僕は最近OpenFlowに興味を持ったプログラマ,友太郎です。スイッチに付いているIDをdatapath IDって呼ぶのはわかったけど,いったいdatapathってなに? スイッチのこと?」

A.実用的には「datapath=OpenFlowスイッチ」と考えて問題ありません。

「データパス」でググると,⁠CPUは演算処理を行うデータパスと,指示を出すコントローラから構成されます」というハードウェア教科書の記述がみつかります。つまり,ハードウェアの世界では一般に「筋肉にあたる部分=データパス」⁠脳にあたる部分=コントローラ」という分類をするようです。

OpenFlowの世界でも同じ用法が踏襲されています。OpenFlowのデータパスはパケット処理を行うスイッチを示し,その制御を行うソフトウェア部分をコントローラと呼びます。

まとめ

すべてのコントローラのテンプレートとなるHello, Trema! コントローラを書きました。また,これを改造してスイッチの動作状況を監視するスイッチモニタを作りました。学んだことは次の3つです。

  • OpenFlowネットワークはパケットを処理するスイッチ(datapath)と,スイッチを制御するソフトウェア(コントローラ)から構成される。Tremaは,このコントローラを書くためのプログラミングフレームワークである
  • Tremaは仮想ネットワーク構築機能を持っており,OpenFlowスイッチを持っていなくてもコントローラの開発やテストが可能。たとえば,仮想ネットワークに仮想スイッチを追加し,任意のdatapath IDを設定できる
  • コントローラはRubyのControllerクラスを継承し,OpenFlowの各種イベントに対応するハンドラを定義することでスイッチをコントロールできる。たとえば,switch_readyとswitch_disconnectedハンドラでスイッチの起動と切断イベントに対応するアクションを書ける

次回はいよいよ本格的なコントローラとして,トラフィック集計機能のあるレイヤ2スイッチを作ります。初歩的なレイヤ2スイッチング機能と,誰がどのくらいネットワークトラフィックを発生させているかを集計する機能をOpenFlowで実現します。

[友太郎の質問]switch_readyってなに?

Q.「OpenFlowの仕様を読んでみたけど,どこにもswitch_readyって出てこなかったよ? OpenFlowにそんなイベントが定義されてるの?」

A.switch_readyはTrema独自のイベントで,スイッチがTremaに接続し指示が出せるようになった段階でコントローラに送られます。実は,switch_readyの裏では図Aの一連の処理が行われており,TremaがOpenFlowプロトコルの詳細をうまくカーペットの裏に隠してくれているのです。

図A switch_readyイベントが起こるまで

図A switch_readyイベントが起こるまで

最初に,スイッチとコントローラがしゃべるOpenFlowプロトコルが合っているか確認します。OpenFlowのHELLOメッセージを使ってお互いのプロトコルバージョンを確認し,うまく会話できそうか確認します。

次は,スイッチを識別するためのdatapath IDの取得です。datapath IDのようなスイッチ固有の情報は,スイッチに対してOpenFlowのFeatures Requestメッセージを送ることで取得できます。成功した場合,datapath IDやポート数などの情報がFeatures Replyメッセージに乗ってやってきます。

最後にスイッチを初期化します。スイッチに以前の状態が残っていると,コントローラが管理する情報と競合が起こるため,初期化することでこれを避けます。これら一連の処理が終わると,ようやくswitch_readyがコントローラに通知されます。

著者プロフィール

高宮安仁(たかみややすひと)

Trema開発チーム自称リーダー。東京の大学で計算科学を学び,並列プログラミング用ライブラリや,大規模クラスタ管理ツールの開発,とくに東工大のスパコンTSUBAME,分散クラスタInTriggerの管理基盤などなど主に分散・大規模システムのミドルウェア開発者・研究者として活動。現在は企業の研究者として,OpenFlow用プログラミングフレームワークTremaのメイン開発者。モットーは何がなんでも定時に帰ること。コンピューターはもちろん映画や音楽も好きで,スクラッチDJとしても活動しています。DJの仕事ください。


鈴木一哉(すずきかずや)

Trema開発チームのメンバー。Ascend,古河電工,ヤマハ等のネットワーク機器を扱うエンジニアを経て,現在は経路制御の研究に従事。ホエールズ時代からのベイスターズファンで,98年の優勝時にはもちろん横浜スタジアムへ駆けつけました。野球のない時期には,もっぱらSFを読んでいます。会社ではランニングサークルに入っており,先日も多摩川の駅伝に参加しましたが,練習不足で全然走れませんでした。ちゃんと練習して,来年こそはしっかり走るぞ!