狠狠撸

狠狠撸Share a Scribd company logo
インターネットマルチフィード株式会社	
 ?技術部
川上	
 ?雄也 (@yuyarin)	
 ?
2013/08/24 LLまつり	
 ?
2	
おしながき	
 ?
1.? イントロ(2分)
2.? SDNとOpenFlowのはなし(10分)
3.? Tremaのはなし(8分)	
 ?
※簡単のためバージョン間の差異異などに触れないので、この資料料をreferenceにしないでください	
 ?
3	
川上	
 ?雄也 (@yuyarin)	
 ?
??2008年年4?月	
 ?株式会社ドワンゴ? 研究開発本部? 
??ニコニコ動画のバックエンドシステムの開発
??2011年年4?月 NTTコミュニケーションズ
??2011年年8?月	
 ?インターネットマルチフィード	
 ?技術部
??JPNAPのネットワークエンジニア
??10/100GbE(広帯域L2網)、DWDM、BGP、鯖?ツール類等
?? コミュニティ活動
??JANOG30&31、InteropTokyo2012&2013 スタッフ
??wakamonog, ハチロク世代	
 ?代表幹事
4	
今?日のおはなし	
 ?
ネットワークを
Rubyで構築	
 ?
5	
ついに来た!	
 ?
ソフトウェアで
ネットワークを
制御できる時代!	
 ?
6	
その名も	
 ?
SDN48
Software Defined Network	
 ?
7	
これまでのネットワーク	
 ?
?? それぞれのネットワーク機器(ルータやスイッチ)が?自律律協調して動作
?? 個々の機器に対してログインして操作(CLI)、個々の機器から情報収集(NMS)
Control Plane
Data Plane
App/Service
Control Plane
Data Plane
App/Service
Control Plane
Data Plane
App/Service
CLI/NMS/Tool
Router/Switch	
 ?
Router/Switch	
 ?
Router/Switch	
 ?
8	
SDNのネットワーク	
 ?
?? ネットワークの動作をコントローラが集中制御
?? コントローラのAPIを使ってネットワークの操作や情報収集	
 ?
Agent
Data Plane
Switch	
 ?
API
Agent
Data Plane
Switch	
 ?Agent
Data Plane
Switch	
 ?
Controller
CLI/NMS/Tool
Controller	
 ?
9	
SDNの何が嬉しい?	
 ?
?? ネットワークを集中管理理できる
??トラフィックエンジニアリングしやすい
?? コントローラなどのソフトウェア=ネットワーク仕様
??ネットワークのバージョン管理理ができる!
??アジャイル開発ができる!!
??テスト駆動開発ができる!!!
??テスト駆動開発ができる!!!!	
 ?
??テスト駆動開発ができる!!!!!	
 ?
??テスト駆動開発ができる!!!!!!
??テスト駆動開発ができる!!!!!!!
??テスト駆動開発ができる!!!!!!!!	
 ?
10	
開流	
 ?
SDNの代表的な要素技術の1つ	
 ?
OpenFlow	
 ?
11	
開流	
 ?
OpenFlowを超カンタンに説明すると	
 ?
パケットの転送や
書換をスイッチに
指?示できる仕組み	
 ?
12	
開流	
 ?
もう少し詳しく?言うと	
 ?
条件にマッチした
パケットに対して
特定のアクションを
実?行行させられる
13	
開流	
 ?
`	
 ?
L2	
 ?
マッチに使える条件の例例	
 ?
???入?力力ポート番号
??送信元MACアドレス
??宛先MACアドレス
??Ethernet Type
??VLAN ID
??VLAN Priority
??送信元IPアドレス
??宛先IPアドレス
??IP Protocol
??送信元ポート番号
??宛先ポート番号
L3	
 ?
L4	
 ?
14	
開流	
 ?
アクションの例例	
 ?
??Forward
??全ポートに
??コントローラに
??スイッチ?自?身に
??フローテーブル通り
???入ってきたポートに
??普通のL2SW通り
??STPに従ってflood
??Drop
??Set-Queue (Enqueue)
??Modify-Field
??フィールド書換
??VLAN追加	
 ?
15	
?用語の説明	
 ?
?? フロー
??MACアドレスやVLAN ID、IPアドレスやポート番号などのフィールド
の組み合わせで識識別される?一連のパケットの流流れ
?? フローテーブル
??マッチングルール(ヘッダフィールド)、アクション、統計情報の要
素からなるフローエントリを登録するテーブル
?? Packet-In
??フローテーブルのエントリにマッチしなかった場合やコントローラで
の処理理が必要な時に、スイッチからパケットをコントローラに送ること
?? Packet-Out
??コントローラからスイッチにパケットを送らせると
16	
通常のForwardの動作	
 ?
?? OFCがForwardのエントリをフローテーブルに登録
?? OFSWはフローテーブルに従ってパケットをForward	
 ?
Agent
Data Plane
OFSwitch	
 ?
Agent
Data Plane
OFSwitch	
 ?Agent
Data Plane
OFSwitch	
 ?
Controller
OFController	
 ?
FlowTable	
 ?
FlowMod	
 ?
Forward	
 ?
FlowMod	
 ?
17	
Packet-InとPacket-Out	
 ?
?? OFCでの処理理が必要なフローはPacket-Inを発?生させて、パケットをOFCに送る
?? フローエントリを作成してOFCに書き込む
?? 処理理したパケットをにPacket-Outで送り返す	
 ?
Agent
Data Plane
OFSwitch	
 ?
Agent
Data Plane
OFSwitch	
 ?Agent
Data Plane
OFSwitch	
 ?
Controller
OFController	
 ?
FlowTable	
 ?
Forward	
 ?
FlowMod	
 ?
Packet-In	
 ?
Packet-Out	
 ?
18	
OpenFlowの何が嬉しい?	
 ?
??これまでのネットワーク
??各プロトコルの標準動作やベンダの実装でしかネットワ
ークやパケットを制御できなかった…
??プロトコル志向でしかトラフィック制御できなかった
??OpenFlowのネットワーク
??L2からL4までのヘッダを好きに使って、好きなようにパ
ケットを制御できる!
??フロー志向でトラフィックを制御できる	
 ?
19	
OpenFlowの何が嬉しくない? (1)	
 ?
??OpenFlowはアセンブラのようなもの
??普通のスイッチやルータの持っている機能を全部
?自分で書かないといけない
??スイッチの機能: MAC学習、フラッディング
??ルーターの機能:	
 ?NextHop検索索、ARP、MAC書換
??ルーティング機能:	
 ?トポロジーの把握、経路路計算
??…	
 ?
※何を作るかの場合に依ります
※デフォルトのL2SW動作もできます	
 ?
20	
OpenFlowの何が嬉しくない? (2)	
 ?
??OFSWで実?行行できるのはバイナリマッチに基づい
た特定のアクションのみ
??プログラマブルにするためにはPacket-Inを発?生さ
せないといけない
??OFCでのPacket-Inの処理理はHW処理理でないので重い
??簡単に出来ないことの例例:
??パケット??長ごとにスイッチング
??IPv4アドレスの下1桁の数字のポートに出?力力
??3つのポートのどれか1つににランダムで出?力力
21	
OpenFlowはどこで使われているのか?	
 ?
??データセンター内/間ネットワーク
??リンク使?用効率率率がよくなるトラフィック最適化
??ソフトウェア制御による運?用構築の?自動化
??ネットワークの集中管理理
??クラウドネットワーク
??ネットワークの仮想化
??ネットワークの動的構成変更更	
 ?
22	
OpenFlowの規格とフレームワーク	
 ?
Ver.	
 ? Framework	
 ?
1.0	
 ?
NOX(C++), POX(Python),
Trema(C, Ruby), Floodlight(Java)	
 ?
1.1	
 ?
1.2	
 ? POX1.2(Python)	
 ?
1.3	
 ?
Trema-edge(C, Ruby),
Floodlight(Java)	
 ?
23	
取間	
 ?
今回取り上げるのが	
 ?
Trema	
 ?
24	
取間	
 ?
What’s Trema?	
 ?
Full-Stack
OpenFlow
Framework
in Ruby and C	
 ?
25	
Why Trema?	
 ?
※Trema公式ロゴ	
 ?
26	
取間	
 ?
Tremaのいいところ	
 ?
?? イベントドリブンで書ける
?? ネットワークエミュレータがついてる
?? 他のフレームワークより少ない?行行数で同じ機能を書ける
?? サンプルコードが豊富
?? 開発者が?日本?人で?日本語の記事が多い
?? ?日本語の本がある
??しかも?自前でTeXをコンパイルしたらタダ
??Rubyだ
27	
取間	
 ?
TremaとOpenFlow	
 ?
??Trema
??OpenFlow 1.0
??Ruby 1.8.7
??http://trema.github.io/trema/
??Trema-edge
??OpenFlow 1.3
??Ruby 2.0.0-p0 @Ubuntu12.04 64-bit
??https://github.com/trema/trema-edge
28	
取間	
 ?
Trema-edgeのインストール	
 ?
1.? Ubuntu 12.04 (64-bit) を?用意する
2.? RVMをインストールする
?? curl -L https://get.rvm.io | bash -s stable
3.? 必要なパッケージをインストールする
?? sudo apt-get install gcc make libsqlite3-dev libpcap-dev libssl-dev git
4.? trema-edgeをcloneする
?? git clone https://github.com/trema/trema-edge.git
?? cd trema-edge
5.? Ruby 2.0.0-p0をインストールする
?? rvm install ruby-2.0.0-p0
?? rvm use 2.0.0-p0 -default
6.? trema-edgeをビルドする
?? bundle install
?? rake
?? ./trema --version	
 ?
29	
取間	
 ?
Tremaの使い?方	
 ?
?? コントローラをデーモンとして起動
?? コントローラをネットワークエミュレータと起動
?? ネットワークエミュレータを操作する	
 ?
trema run -d mycontroller.rb? 	
 ?
trema run mycontroller.rb -c mynetwork.conf	
 ?
trema send_packets -source host1 -dest host2
trema show_stats host1 -r 	
 ?
30	
コントローラの書き?方	
 ?
??イベントハンドラを書いてあげる
??ネットワークの制御に必要な機能を実装する	
 ?
require ‘MyNetworkLib’
class MyController < Controller
periodic_timer_event: <定期実行イベントのハンドラ>, <間隔>
def <イベントハンドラ>
<イベント処理>
end
...
private
def <ネットワーク制御メソッド>
<ネットワーク制御処理>
end
...
end	
 ?
31	
イベントハンドラの例例	
 ?
handler	
 ? 発?生条件	
 ?
start	
 ? コントローラ起動時	
 ?
switch_ready	
 ? OFスイッチが起動した	
 ?
switch_disconnected	
 ? OFスイッチが切切断された	
 ?
packet_in	
 ? Packet-Inが発?生した	
 ?
flow_removed	
 ? フローエントリが時効で削除された	
 ?
port_status	
 ? ポートの状態が変わった	
 ?
32	
スイッチの操作の例例	
 ?
handler	
 ? 発?生条件	
 ?
send_flow_mod_add	
 ? フローエントリを追加する	
 ?
send_flow_mod_delete フローエントリを削除する	
 ?
send_flow_mod_modify	
 ? フローエントリを修正する	
 ?
send_packet_out	
 ? Packet-Outを発?生させる	
 ?
33	
コントローラの書き?方の例例	
 ?
class MyController < Controller
def switch_ready datapath_id
action = SendOutPort.new( port_number: OFPP_CONTROLLER, max_len: OFPCML_NO_BUFFER )
apply_ins = ApplyAction.new( actions: [ action ] )
send_flow_mod_add( datapath_id, priority: OFP_LOW_PRIORITY,
buffer_id: OFP_NO_BUFFER,
instructions: [ apply_ins ] )
end
def packet_in datapath_id, message
# ...
send_flow_mod_add(
datapath_id,
:match => Match.new( :in_port => message.in_port, ...),
:actions => [ StripVlanHeader.new, SendOutPort.new(port_no) ] )
send_packet_out(
datapath_id,
:packet_in => message )
end
# ...
end	
 ?
※内容に意味はありません	
 ?
Packet-Inを起こすアクション	
 ?
マッチするエントリがない場合は
Packet-Inを起こすように設定	
 ?
マッチングルールとアクションの対を
作成してフローテーブルに登録	
 ?
Packet-Inしたパケットを送り返す	
 ?
34	
MAC学習L2スイッチ (1/2)	
 ?
class LearningSwitch < Controller
def start
@fdb = FDB.new
end
def switch_ready datapath_id
action = SendOutPort.new( port_number: OFPP_CONTROLLER, max_len: OFPCML_NO_BUFFER )
ins = ApplyAction.new( actions: [ action ] )
send_flow_mod_add( datapath_id, priority: OFP_LOW_PRIORITY,
buffer_id: OFP_NO_BUFFER,
flags: OFPFF_SEND_FLOW_REM,
instructions: [ ins ] )
end
def packet_in datapath_id, message
@fdb.learn message.eth_src, message.in_port
port_no = @fdb.port_no_of( message.eth_dst )
if port_no
flow_mod datapath_id, message, port_no
packet_out datapath_id, message, port_no
else
flood datapath_id, message
end
end
?入?力力ポートでMACを学習	
 ?
出?力力ポートが決まったらフローを
登録してPacket-Out	
 ?
出?力力ポートが未学習だったら
フラッディングする	
 ?
デフォルトPacket-In	
 ?
35	
MAC学習L2スイッチ (2/2)	
 ?
private	
 ?
	
 ? def flow_mod datapath_id, message, port_no
action = SendOutPort.new( port_number: port_no )
ins = Instructions::ApplyAction.new( actions: [ action ] )
send_flow_mod_add( datapath_id, match: ExactMatch.from( message ),
instructions: [ ins ])
end
def packet_out datapath_id, message, port_no
action = Actions::SendOutPort.new( port_number: port_no )
send_packet_out( datapath_id, packet_in: message,
actions: [ action ] )
end
def flood datapath_id, message
packet_out datapath_id, message, OFPP_ALL
end
end
36	
ネットワークエミュレータの設定	
 ?
trema_switch( "lsw" ) {
datapath_id "0xabc"
}
vhost ("host1") {
ip "192.168.0.1"
netmask "255.255.0.0"
mac "00:00:00:01:00:01"
}
vhost ("host2") {
ip "192.168.0.2"
netmask "255.255.0.0"
mac "00:00:00:01:00:02"
}
link "host1", "lsw:1"
link "host2", "lsw:2"
Open vSwitch
lsw
Trema
Controller	
 ?
phost
host1
phost
host2
1	
 ? 2	
 ?
37	
テスト駆動開発ができる!	
 ?
describe RepeaterHub do
it "は、?入ってきたパケットを他のすべてのポートに転送する" do
network {
vswitch( "switch" ) { dpid "0xabc" }
vhost( "host1" ) { promisc "on" }
vhost( "host2" ) { promisc "on" }
vhost( "host3" ) { promisc "on" }
link "switch", "host1"
link "switch", "host2"
link "switch", "host3"
}.run( RepeaterHub ) {
send_packets "host1", "host2"
# host2 と	
 ?host3 がひとつずつパケットを受け取る	
 ?
vhost( "host2" ).stats( :rx ).should have( 1 ).packets
vhost( "host3" ).stats( :rx ).should have( 1 ).packets
}
end
end
38	
ではさっそく	
 ?
なにか
作ってみよう	
 ?
39	
ロードバランサ
(超簡易易版)	
 ?
40	
こんなかんじで	
 ?
Client1
192.168.0.1	
 ?
Client2
192.168.0.2	
 ?
Client3
192.168.0.3	
 ?
Client4
192.168.0.4	
 ?
Client5
192.168.0.5	
 ?
Server1
10.0.0.1
00:00:00:00:00:01	
 ?
Server2
10.0.0.1
00:00:00:00:00:01	
 ?
Server3
10.0.0.1
00:00:00:00:00:01	
 ?
LB	
 ?
Trema	
 ?
41	
ポイント	
 ?
??サーバ側はIPアドレスもMACアドレスも同じ
??サーバ増やすの簡単だよ!
??従来のEthernet/IPの仕組みでは出来ないよ!
??クライアントの送信元IPアドレスで振り分け
??7タプルのハッシュができない
??アドレス下位8-bit (backet-size 256)で各サーバポー
トに振り分けるルールを登録しておく	
 ?
42	
demo	
 ?
43	
みんなもRubyで
ネットワークを
つくろう!	
 ?
44	
ありがとう
ございました	
 ?

More Related Content

Rubyで創るOpenFlowネットワーク - LLまつり