OpenFlowコントローラ Ryuについてのセミナーに参加

このセミナー と同じところが主催でした。

10/12(Sat)のお話。
タイトルが"コードレビューと共に学ぶ"みたいな感じだったので、「頑張ってついていこう」と気を引き締めて行ってみると、今回はRyuの成り立ちとか、実行形態だとか。
後半でコードレビューでしたが、Pythonのデコレータとインスペクションが分からず。
Power of Pythonらしい。分からん。
ちなみにソースコードはgithubにあります。
Ryu

セミナー時のメモ、というかスライドの内容と講師の方の発言とか。

***** 自己紹介
講師: 藤田智成さん (NTT Software Innovation Center -> NTT研究所)
オープンソース活動
– Linux kernel
– iSCSI Enterprise Target
– Linux SCSI target framework
– Sheepdog
– Ryu
是非OSSの活動に皆さん参加して欲しい

What are you smoking? -> 「お前何言ってるのか分からねえよ。ラリってんの?」みたいな直接的に物を言うのがOSSの文化

***** SDN/OpenFlowの基本を確認
– フローテーブルに従ってパケットを処理\

フローテーブル記述が無いパケットはpacket_inによってパケットの中身に合わせた柔軟な処理
– パケットインしないような設計が重要
— フローは予め入れておき、packet_inは例外処理

既存ネットワークを全てOpenFlowに置き換えるのは基本的に「ありえない」
既存ネットワーク・プロトコルとの融合が大切
– 全てのスイッチを置き換えるコスト
– 置換ではなく、段階的な進化

Ryuを設計する際の想定
– コントローラの性能は重要ではない
– 既存ネットワークとの連携が重要

***** Ryuについて
NTT SIC発のオープンソースプロジェクト
– ネットワークアプリケーション開発のための基盤ソフトウェア
– 誰でも参加できるコミュニティでオープンに開発
— ML参加者200名
— Apache v2 ライセンス

*** Ryuの特徴
– 特定のアプリケーションにフォーカスした完成品ではない

*** Ryuの機能概要
– データプレーン制御プロトコル
— OpenFlow 1.0, 1.2, 1.3 (OpenvSwitch専用)
— OF-config, OVSDB JSON (OpenvSwitch専用)
– 共通機能コンポーネント
— トラフィック監視 (NetFlow, sFlow)
— トポロジ検出 (LLDP)
— クラウドテナントL2分離 (GREトンネリング/VLAN) (OpenStack用)
— セキュリティ (ファイアウォール)
— 高可用化 (VRRP/LACP)
— パケットライブラリ

*** Ryuの開発を始めた理由
– 我々のネットワークのリアルな問題を解くため
— 多様なネットワークへの対応

*** RyuをOSSで開発している理由
– SDNを定着させたい強いモチベーション
— 安価なハードウェア
— 技術者

*** 名前の由来
Flow -> 流 -> しかし外人には読めないし分かりにくい。
龍: 水の神 -> アイコンを重視しよう (しかし結局Ryuは発音できないらしい…。“ラウ"と呼ばれる?)

***** 実装言語について
*** 言語は何を使うべきか
すでに以下の言語でOpenFlowコントローラが存在する
– C/C++
— NOX (Python binding), Trema (Ruby binding)
– Java
— Floodlight, OpenDaylight

*** 重視したポイント
– 実行速度 vs 開発速度
— 開発速度を重視 < - コントローラの性能は重要ではない、という考えから --- No C/C++, No binding - 開発者人口 --- 開発者が多い事を重視 --- No Erlang, No Scala, No Go, No JS (サーバサイド) => 人気度的にはJava or Python
==> JavaはすでにFloodlightがあるし、Pythonで書こう

*** コードの規模 (by sloccount)
python 5万行(83%) < - Ryu本体 erlang 1万行(16%) <- テストコード sh 400行 ansic 20行 ***** Ryuの前にOSの復習 「1つのRyuで複数のスイッチをハンドリングする」 スクリプト言語で複数のコネクションをどのように制御するか? OSのthreadやprocessについて理解しないといけない *** プロセスとは? - 実行中のプログラム --- CPUは一度に一つのプログラムしか実行できない --- プロセスを切り替えながら実行することで、同時に複数のプログラムが動いているように見える *** プロセスがもつ情報 - 後で再開するのに必要な情報 --- プログラムカウンタ など *** プロセスモデルの制約 - 多くのアプリケーションは複数の独立したタスクを並列に実行する必要がある - 複数のプロセスでアプリケーションを構成 ---プロセス間で情報の共有が必要 --- プロセスは独立したメモリ空間を持っているので、情報共有のしくみが必要 *** スレッド - スレッド --- 制御ポイントを示す --- 次に実行すべき命令を格納するプログラムカウンタを持つ - プロセス --- 複数のスレッドと一つのアドレス空間から構成される *** スレッドの実装手段は二つある - 軽量プロセス --- OSのスレッド機能サポートを利用する => OSがスレッドの存在を検知
==> スレッドの数に応じてCPUリソースを割り当てる
– ユーザスレッド
— OSの機能を使わず、ライブラリで実現する
=> OSはスレッドの存在を検知できない
==> スレッドが見えないため一つのプロセスとしてCPUリソースを割り当てる

=> Pythonでは軽量プロセスは使えない(厳密には使えるが、Pythonである必要がなくなってしまう)
==> そのため、Ryuではユーザスレッドな実装をしている

*** IO多重モデルはスレッド
– スレッドはI/Oイベントを待ってスリープする
=> そうしないと他のスレッドを実行できない(CPUは一度に1つのプロセスしか動かせない)
— 1つのスイッチに対してTXスレッドとRXスレッドを立ち上げる
=> TXとRXと管理するスレッドの最低3つのスレッドが動く

*** Eventlet スレッドライブラリ
– Cooperative threading\

ソケットの送受信やキューへの送受信をスリープする場合はスレッドが切り替わる
— 1つのスレッドがCPUを占有しないように注意する必要がある
=> Pythonのライブラリなため、OSでのスレッド機能サポートと違い、CPUのリソースを強制的に取り上げる機能がない
==> 例えば4096byte受信したらスリープする、というコードを書く必要がある

*** 他のIO多重ライブラリ
– スレッド
— Gevent
– その他
— Twisted
— Tornado
標準は決まって無い

***** Ryuフレームワーク上のプログラミング基本概念
– イベントとハンドラ\

Ryuアプリケーションは特定のイベントが発生した際に実行される関数(ハンドラ)を定義する
– イベントの種類
— OpenFlowの特定のメッセージをデータプレーンから受信
— データプレーンと切断された
– Ryuアプリケーションの独自イベントも定義できる
— アプリケーション間のメッセージングとして利用
=> 複数のRyuアプリケーションを立ち上げる事が可能

*** アプリケーションは複数のRyuAppで構成される
– イベントはClassとして定義される
– それぞれのRyuAppは興味のあるイベントを登録
– イベントの種類に応じて適切なRyuAppに配送
=> Event Dispatcher が良きに計らって適切なRyuAppを呼び出し
==> RyuApp同士のやり取りにはQueueを使う
以下の感じ
RyuApp < ===(queue)=== Event Dispatcher ===(queue)===> RyuApp

OpenFlow通信をするRyuApp
データベースとの連携をするRyuAppなど、いろいろアプリケーションを作れる

*** RyuAppの内部
– 最低1つのスレッドを生成
— 受信したイベントに対応したハンドラを実行
— イベントはシリアライズされて実行される

*** イベントを利用したリクエスト・レスポンス
– 2つのRyuApp間のリクエスト・レスポンス型通信も可能
RyuApp < ===(Event)===> RyuApp
イベントとしてリクエストとレスポンスを送り合う

*** RyuApp = 再利用可能なコンポーネント
– 疎結合
— 興味があるイベントの定義だけを共有
— イベントは公開されたAPIと動議
– OpenFlowプロトコル処理もRyuApp
— データプレーンからのOpenFlow Messageをイベントとして他のRyuAppに配送
— 他のRyuAppからOpenFlow MessageイベントをデータプレーンにOpenFlow Messageとして送信

***** OpenFlow Message Class
– Eventに使われるクラスはEventBaseの派生
— Eventとして使われるための共通コード
– ‘Event’ + OpenFlow message name
— E.g. EventOFPPacketIn
– クラスは動的に生成
— Class EventOFPPacketInは定義されていない
— 起動時にClass OFPPacketInから動的に生成される
=> EventOFPPacketIn なんてイベント探しても無い!ってことになる

— Power of Python (イントロスペクション)
=> Pythonにおいては「全てがオブジェクト」である。イントロスペクションとは、メモリ上の他のモジュールや関数をオブジェクトとして参照し、それらの情報を取得し、あやつるためのコードである。

(注意) Powerは使い過ぎに注意
– OSSは多くの人たちに使ってもらうことが大切
— あまりに複雑なコードはやめましょう

*** JSONフォーマットの相互変換
– OpenFlow Messageクラス < -> JSON
— OFPクラスをJSONフォーマットで出力可能
— JSONフォーマットからOFPクラスのオブジェクトを生成可能
– 何が嬉しいの?
— 他の言語との組み合わせが容易に(JSONをAPIとして利用)
— Logging/statistics
– それぞれのOFPクラスでJSON変換コードを定義したくない
— 親クラスでやりたい
— 変数の型が分からない
=> hw_addr が ascii or utf-8 ?

***** Q&A
Q: Pythonは何系?
A: 2系。3系への対応は今後の課題としてはある。

Q: RyuAppの依存関係は?
A: 単純な依存関係は記述可能だが、順番などの複雑な部分については今後の課題として残っている。

Q: show-techのようなことは可能?トラブルの切り分け機能が重要では。
A: エラー処理などに対する機能はまだ我々も議論中。通常のネットワーク機器とは違い、制御の仕方によって違うので難しい。

Q: 実効性能は重視しないといっていたが、どうにか性能を上げたい場合は?
A: PyPyというPythonをコンパイルするという仕組みがある。RyuはPyPyに対応しているので利用可能。

Q: Ryuはプロセス1つ?
A: そこは痛いところ。RyuApp毎にプロセス化、もしくは複数プロセスを立ち上げるという検討をしているところ。