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

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

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

Hello, Trema!

tremaディレクトリの中にhello_trema.rbというファイルを作成し,エディタでリスト1のコードを入力してください。

リスト1 Hello Trema! コントローラ

class HelloController < Controller ――①
  def start ――②
    puts "Hello, Trema!"
  end
end

それでは早速実行してみましょう! 作成したコントローラはtrema runコマンドで実行できます。この世界一短いOpenFlowコントローラ(?)は画面に「Hello, Trema!」と出力します。

% cd trema
% ./trema run ./hello_trema.rb
Hello, Trema!  ←Ctrl+cで終了

いかがでしょうか? Tremaを使うと,とても簡単にコントローラを書いて実行できることがわかると思います。えっ? これがいったいスイッチの何を制御したかって? 確かにこのコントローラはほとんど何もしてくれませんが,Tremaでコントローラを書くのに必要な知識がひととおり含まれています。スイッチをつなげるのはちょっと辛抱して,まずはソースコードを見ていきましょう。

コントローラクラスを定義する

Rubyで書く場合,すべてのコントローラはControllerクラスを継承して定義しますリスト1-①)⁠

Controllerクラスを継承することで,コントローラに必要な基本機能がHelloControllerクラスにこっそりと追加されます。

ハンドラを定義する

Tremaはイベントドリブンなプログラミングモデルを採用しています。つまり,OpenFlowメッセージの到着など各種イベントに対応するハンドラを定義しておくと,イベントの発生時に対応するハンドラが呼び出されます。たとえばstartメソッドを定義しておくと,コントローラの起動時にこれが自動的に呼ばれますリスト1-②)⁠

さて,これでTremaの基本はおしまいです。次は,いよいよ実用的なOpenFlowコントローラを書いて実際にスイッチをつないでみます。今回のお題はスイッチのモニタリングツールです。⁠今,ネットワーク中にどのスイッチが動いているか」をリアルタイムに表示しますので,何らかの障害で落ちてしまったスイッチを発見するのに便利です。

スイッチモニタリングツールの概要

スイッチモニタリングツールは図2のように動作します。

図2 スイッチモニタリングツールの動作

図2 スイッチモニタリングツールの動作

OpenFlowスイッチは,起動するとOpenFlowコントローラへ接続しに行きます。Tremaでは,スイッチとの接続が確立すると,コントローラのswitch_readyハンドラが呼ばれます。コントローラはスイッチ一覧リストを更新し,新しく起動したスイッチをリストに追加します。逆にスイッチが何らかの原因で接続を切った場合,コントローラのswitch_disconnectedハンドラが呼ばれます。コントローラはリストを更新し,いなくなったスイッチをリストから削除します。

仮想ネットワーク

それでは早速,スイッチの起動を検知するコードを書いてみましょう。なんと,Tremaを使えばOpenFlowスイッチを持っていなくてもこうしたコードを実行してテストできます。いったいどういうことでしょうか?

その答えは,Tremaの強力な機能の1つ,仮想ネットワーク構築機能にあります。これは仮想OpenFlowスイッチや仮想ホストを接続した仮想ネットワークを作る機能です。この仮想ネットワークとコントローラを接続することによって,物理的なOpenFlowスイッチやホストを準備しなくとも,開発マシン1 台でOpenFlow コントローラと動作環境を一度に用意して開発できます。もちろん,開発したコントローラは実際の物理的なOpenFlowスイッチやホストで構成されたネットワークでもそのまま動作します!

それでは仮想スイッチを起動してみましょう。

仮想OpenFlowスイッチを起動する

仮想スイッチを起動するには,仮想ネットワークの構成を記述した設定ファイルをtrema runに渡します。たとえば,リスト2の設定ファイルでは仮想スイッチ(vswitch)を2台定義しています。

リスト2 仮想ネットワークに仮想スイッチを2台追加

vswitch { datapath_id 0xabc }
vswitch { datapath_id 0xdef }

それぞれに指定されているdatapath_id(0xabc,0xdef)はネットワークカードにおけるMACアドレスのような存在で,スイッチを一意に特定するIDとして使われます。OpenFlowの規格によると,64ビットの一意な整数値をOpenFlow スイッチ1 台ごとに割り振ることになっています。仮想スイッチでは好きな値を設定できるので,かぶらないように適当な値をセットしてください。

リスト3 SwitchMonitorコントローラ

class SwitchMonitor < Controller
  periodic_timer_event :show_switches, 10 ――③

  def start
    @switches = []
  end

  def switch_ready datapath_id ――①
    @switches << datapath_id.to_hex
    info "Switch #{ datapath_id.to_hex } is UP"
  end

  def switch_disconnected datapath_id ――②
    @switches -= [datapath_id.to_hex ]
    info "Switch #{ datapath_id.to_hex } is DOWN"
  end

  private ――③
  def show_switches
    info "All switches = " + @switches.sort.join( ", " )
  end
end

著者プロフィール

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

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


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

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

コメント

コメントの記入