SlideShare ist ein Scribd-Unternehmen logo
1 von 143
Downloaden Sie, um offline zu lesen
∼SDN時代の開発よもやま話∼

         OpenFlowとTrema
         高宮安仁 (Trema開発チーム)




12年12月9日日曜日
FAQ
              よくある疑問


12年12月9日日曜日
OpenFlow/SDN FAQ



     「何の役に立つの?」


12年12月9日日曜日
世界で初めて、
          OpenFlow/SDN
          開発を扱った本
          2013/1/8 発売


12年12月9日日曜日
SDN
                とは




12年12月9日日曜日
SDN
                とは
      プログラミング分野の1つ


12年12月9日日曜日
SDN
      プログラミング分野の1つ
                     とは


               「GUIプログラミング」
                   とかと同じ!
12年12月9日日曜日
OpenFlow とは




12年12月9日日曜日
OpenFlow          とは

              SDNのいち実装方式



12年12月9日日曜日
OpenFlow              とは

              SDNのいち実装方式
                   GtkとかCocoa
                    とかと同じ!

12年12月9日日曜日
SDN
          つまり




        OpenFlow
12年12月9日日曜日
SDN
          つまり




        OpenFlow
        は純粋にソフトウェア開発の話。


12年12月9日日曜日
MAKE 「評論もいーけど、動いて役に
               立つもの作りません?」



12年12月9日日曜日
すでにバックボーンは
          OpenFlowで作っちゃた


                                                 Urs Hölzle
                           http://itpro.nikkeibp.co.jp/article/NEWS/20120418/391401/

12年12月9日日曜日
OpenFlow/SDN FAQ


    「何の役に立つの?」
         →Googleの事例を解説


12年12月9日日曜日
Googleのチャレンジ
                            最先
         • 平均 PUE = 1.13      端

         • 年間アベイラビリティ = 99.984%

         • 処理するデータ量/day = 数十ペタ



12年12月9日日曜日
Googleのチャレンジ
                            最先
         • 平均 PUE = 1.13      端

         • 年間アベイラビリティ = 99.984%

         • 処理するデータ量/day = 数十ペタ

              次の チャレンジは データセンター
                をつなぐネッ トワークだ!

12年12月9日日曜日
WAN 回線のコスト
    日米間(4.8Tbps、1万km)=320億円




12年12月9日日曜日
WAN 回線のコスト
    日米間(4.8Tbps、1万km)=320億円




               回線を 追加せずに、
               既存のを有 効活用したい
12年12月9日日曜日
DC   どれだけ流せる?   DC




                     DC
12年12月9日日曜日
従来のルーティング

              • ルータは自律分散で動く
              • 宛先に対して必ず最短路を選択
              • 帯域の使用量は加味してくれない

12年12月9日日曜日
DC   集中   DC




                        ヒマ?
                   DC
12年12月9日日曜日
DC   理想   DC




                   DC
12年12月9日日曜日
帯域は?
              DC                DC
                       10Gbps



               6Gbps




                          DC
12年12月9日日曜日
DC                DC
                       10Gbps




                                ?
               6Gbps




                        DC
12年12月9日日曜日
DC          DC




                        どう分ける?

                   DC
12年12月9日日曜日
TEサーバ
              DC           DC




                    DC
12年12月9日日曜日
TEサーバ
               DC
              空き帯域
                             DC
              の収集




                      DC
12年12月9日日曜日
TEサーバ
               DC
              空き帯域
                             DC
                              帯域の
              の収集
                             割り当て




                      DC
12年12月9日日曜日
TEサーバ
              DC           DC




                    DC
12年12月9日日曜日
TEサーバ
              DC           DC




                    DC
12年12月9日日曜日
TEサーバ

              DC
              BGPルータ      BGP処理部

                          コントローラ




                       OpenFlow
12年12月9日日曜日
                       スイッチ
TEサーバ

              DC
              BGPルータ      BGP処理部
                   経路情報
                          コントローラ




                       OpenFlow
12年12月9日日曜日
                       スイッチ
TEサーバ

              DC
              BGPルータ      BGP処理部
                   経路情報
                       コントローラ
                   トラフィック
                     情報

                       OpenFlow
12年12月9日日曜日
                       スイッチ
TEサーバ

              DC
              BGPルータ      BGP処理部
                   経路情報
                       コントローラ
                   トラフィック
                     情報

                       OpenFlow
12年12月9日日曜日
                       スイッチ
TEサーバ

                                     経路制御
              DC
              BGPルータ      BGP処理部
                   経路情報
                       コントローラ
                   トラフィック
                     情報

                       OpenFlow
12年12月9日日曜日
                       スイッチ
TEサーバ

                                     経路制御
              DC
              BGPルータ      BGP処理部
                   経路情報
                       コントローラ
                   トラフィック
                     情報

                       OpenFlow
12年12月9日日曜日
                       スイッチ
Google WANの利用率



              ほぼ100%
              使い切り


12年12月9日日曜日
TEサーバ

              DC
              BGPルータ      BGP処理部

                          コントローラ




                       OpenFlow
12年12月9日日曜日
                       スイッチ
OpenFlow/SDN FAQ



     「どういう仕組み?」


12年12月9日日曜日
2分で分かる
          OpenFlow
12年12月9日日曜日
従来のスイッチ
              制御する     パケットの
              ソフトウェア   転送ルール


               ファーム    フロー
               ウェア領域   テーブル




12年12月9日日曜日
ソフトウェア

              コントローラ

                  OpenFlow
                  プロトコル


                     フロー
                    テーブル




              ハードウェア
12年12月9日日曜日
コントローラ




                    フロー
                   テーブル

                          転送ルール
                          を参照
  速い

12年12月9日日曜日
コントローラ



              知らない
              パケット
                      フロー
                     テーブル

                            転送ルール
                            を参照
  速い

12年12月9日日曜日
コントローラ
                     フローテーブル
                     の更新
              知らない
              パケット
                        フロー
                       テーブル

                              転送ルール
                              を参照
  速い

12年12月9日日曜日
コントローラ
                     フローテーブル
  遅い                 の更新
              知らない
              パケット
                        フロー
                       テーブル

                              転送ルール
                              を参照
  速い

12年12月9日日曜日
OpenFlow/SDN FAQ



    「何がうれしいの?」


12年12月9日日曜日
OpenFlowのうれしさ




12年12月9日日曜日
OpenFlowのうれしさ

              • ソフトウェアによる高い自由度




12年12月9日日曜日
OpenFlowのうれしさ

              • ソフトウェアによる高い自由度
              • システム連携と自動化




12年12月9日日曜日
OpenFlowのうれしさ

              • ソフトウェアによる高い自由度
              • システム連携と自動化

              • ソフトウェア開発手法をネットワーク
               に適用できる




12年12月9日日曜日
コントローラ

                         好きな言語で書ける
              OpenFlow   Ruby, Python, C++,Java,...
              プロトコル


                           フロー
                          テーブル




                                 既存のプロトコルに
                                 縛られない
                                 (e.g.,VLANの上限)
12年12月9日日曜日
TEサーバ       ミドル          DB


              コントローラ      自由に連携



                    フロー
                   テーブル




12年12月9日日曜日
データセンター
                 GFS
              Paxos
                Chubby




12年12月9日日曜日
データセンター
                 GFS
              Paxos      コントローラ
                Chubby

                              フロー
                             テーブル




12年12月9日日曜日
データセンター
                 GFS
              Paxos      コントローラ
                Chubby

                              フロー
                             テーブル




12年12月9日日曜日
ソフトウェア手法の応用




12年12月9日日曜日
ソフトウェア手法の応用

              •   ネットワークを段階的に反復構築
                  (アジャイル)




12年12月9日日曜日
ソフトウェア手法の応用

              •   ネットワークを段階的に反復構築
                  (アジャイル)

              •   ネットワークのテスト
                  (各種テスト、テストドリブン)




12年12月9日日曜日
ソフトウェア手法の応用

              •   ネットワークを段階的に反復構築
                  (アジャイル)

              •   ネットワークのテスト
                  (各種テスト、テストドリブン)

              •   バージョン管理や巻き戻し
                  (git などのバージョン管理ツール)



12年12月9日日曜日
OpenFlow/SDN FAQ


    「フローテーブルで
     何ができるの?」

12年12月9日日曜日
12年12月9日日曜日
スイッチ
              コントローラ
                       パケットの宛先
                       MACアドレス
                       →出力ポート
                  転送




12年12月9日日曜日
スイッチ(トラフィックモニタ)
                 コントローラ
              トラフィック
                  情報
                       流量
                       転送




12年12月9日日曜日
ルータ
              コントローラ



                   書き換え
                     転送

              送信元・宛先
              MACアドレスを
              書き換え
12年12月9日日曜日
12年12月9日日曜日
ロードバランサ
                              バックエンド
                 コントローラ       サーバ

              トラフィック
                  情報
                        流量
                       書き換え
                        転送


               トラフィック量に
               応じて転送先を調整
12年12月9日日曜日
帯域を目一杯使う

          DC                  DC
                    転送   転送




               転送             転送




                    転送   転送



12年12月9日日曜日
レプリケーション

                          DC
                     分岐

                          DC
    DC          分岐

                          DC
                     分岐

                          DC
12年12月9日日曜日
パッチパネル
                コントローラ

                          ネットワーク
                             A

                     転送

                          ネットワーク
              所属するネットワーク     B
              をソフトウェアで切り替え
12年12月9日日曜日
パッチパネル
                コントローラ

                          ネットワーク
                             A

                     転送

                          ネットワーク
              所属するネットワーク     B
              をソフトウェアで切り替え
12年12月9日日曜日
パッチパネル
                コントローラ

                          ネットワーク
                             A

                     転送

                          ネットワーク
              所属するネットワーク     B
              をソフトウェアで切り替え
12年12月9日日曜日
OpenFlow/SDN FAQ



              「どう作るの?」


12年12月9日日曜日
主なOpenFlow
                プログラミングフレームワーク

              •Trema (Ruby)
              • POX (Python)
              • NOX (C++)
              • Floodlight (Java)
12年12月9日日曜日
バージョン対応状況




12年12月9日日曜日
バージョン対応状況




              1.0   1.1   1.2   1.3



12年12月9日日曜日
バージョン対応状況
                Trema
                 POX
                NOX
              Floodlight

                 1.0       1.1   1.2   1.3



12年12月9日日曜日
バージョン対応状況
                Trema
                 POX
                NOX
              Floodlight               TremaEdge

                 1.0       1.1   1.2     1.3



12年12月9日日曜日
12年12月9日日曜日
12年12月9日日曜日
watcher数: 1位
          Trema                           123

     Floodlight                    91

              POX             68

 OpenFaucet              28

              NOX   17

                                    12/6/2012 調べ
12年12月9日日曜日
サンプルApp数: 1位
         Trema                          29

              NOX               16

              POX           5
                                 01101101
        Beacon          4
                                 11010101
    Floodlight      3            01111101
 OpenFaucet 0                    01010111
12年12月9日日曜日
OpenFlow/SDN FAQ


     「どんな実アプリが
       あるの?」

12年12月9日日曜日
Wakame-VDC
                  http://wakame.jp/document/15/

              • コンパクトな Ruby 製 IaaS 基盤ソフト
               (e.g., OpenStack、Eucalyptus)

              • 九州電力、NII など採用事例たくさん
              • Rails による GUI
              • ネットワークとストレージの仮想化
12年12月9日日曜日
12年12月9日日曜日
12年12月9日日曜日
OpenFlow/SDN FAQ


              「ネットワーク
               カソウカ?」

12年12月9日日曜日
12年12月9日日曜日
パッチパネル
                コントローラ

                          ネットワーク
                             A

                     転送

                          ネットワーク
              所属するネットワーク     B
              をソフトウェアで切り替え
12年12月9日日曜日
「OpenFlowスイッチ
     がないとダメ?」

12年12月9日日曜日
Wakame のエッジ仮想化

                VM   VM   VM
                               SW
                               スイッチ

 物理ホスト


                   既存の
                 ネットワーク
12年12月9日日曜日
IP アドレスがかぶると?
               ユーザ X                       ユーザ Y
         192.168.0.1   192.168.0.2   192.168.0.1   192.168.0.2


              VM          VM            VM            VM



                                         普通のスイッチ

               →ユニキャストなら問題なし
12年12月9日日曜日
IP アドレスがかぶると?
               ユーザ X                        ユーザ Y
                               はーい!
                       192.168.0.2
                                                            はーい!
         192.168.0.1                  192.168.0.1   192.168.0.2


              VM         VM              VM           VM

  192.168.0.2 の
MACアドレスは?                                 普通のスイッチ

                   →ブロードキャストで問題
12年12月9日日曜日
エッジスイッチでブロック

                        ユーザ X                        ユーザ Y
                    192.168.0.1
                                          はーい!
                                  192.168.0.2    192.168.0.1   192.168.0.2



                      VM            VM             VM            VM

              192.168.0.2 の
          MACアドレスは?                                  エッジスイッチ



12年12月9日日曜日
エッジスイッチで書き換え
                     ホストA        ホストB

               ユーザ X ユーザ Y    ユーザ X ユーザ Y


                    VM   VM    VM    VM



              宛先を
                                        元に戻す
        ホストBへ


12年12月9日日曜日
OpenFlow/SDN FAQ

        「そろそろTrema
       でのプログラミング
         を教えて!」
12年12月9日日曜日
Tremaの特長




12年12月9日日曜日
Tremaの特長

              「今風」なフレームワーク




12年12月9日日曜日
Tremaの特長

              「今風」なフレームワーク

         • Rubyによる簡潔な記述




12年12月9日日曜日
Tremaの特長

              「今風」なフレームワーク

         • Rubyによる簡潔な記述
         • フルスタック: ノートPC一台で開発


12年12月9日日曜日
Tremaの特長

              「今風」なフレームワーク

         • Rubyによる簡潔な記述
         • フルスタック: ノートPC一台で開発
         • GitHub上でのオープンな開発 (GPL2)

12年12月9日日曜日
Tremaの哲学

       一、短く書けて、
       一、すぐに動くべし



                    と れ ま

                    取間先生
                            (C) Miramax Films 2004

12年12月9日日曜日
OpenFlow/SDN FAQ



               「なぜ短く?」


12年12月9日日曜日
短ければ短いほど、

         • 早くサッと作れて、
         • バグの発生率が小さく、

         • 後々のメンテも楽だから
12年12月9日日曜日
Trema でハブ
              class RepeaterHub < Controller
                def packet_in datapath_id, message
                  send_flow_mod_add(
                    datapath_id,
                    :match => ExactMatch.from( message ),
                    :actions => SendOutPort.new( OFPP_FLOOD )
                  )
                  send_packet_out(
                    datapath_id,
                    :packet_in => message,
                    :actions => SendOutPort.new( OFPP_FLOOD )
                  )
                end
              end




12年12月9日日曜日
POX (Python)




12年12月9日日曜日
POX (Python)
              from pox.core import core
              import pox.openflow.libopenflow_01 as of
              class RepeaterHub (object):
                def __init__ (self, connection):
                  self.connection = connection
                  connection.addListeners(self)
                def send_packet (self, buffer_id, raw_data, out_port, in_port):
                  msg = of.ofp_packet_out()
                  msg.in_port = in_port
                  if buffer_id != -1 and buffer_id is not None:
                    msg.buffer_id = buffer_id
                  else:
                    if raw_data is None:
                      return
                    msg.data = raw_data
                  action = of.ofp_action_output(port = out_port)
                  msg.actions.append(action)
                  self.connection.send(msg)
                def act_like_hub (self, packet, packet_in):
                  self.send_packet(packet_in.buffer_id, packet_in.data,
                                   of.OFPP_FLOOD, packet_in.in_port)
                def _handle_PacketIn (self, event):
                  packet = event.parsed
                  if not packet.parsed:
                    return
                  packet_in = event.ofp # The actual ofp_packet_in message.
                  self.act_like_hub(packet, packet_in)
              def launch ():
                def start_switch (event):
                  RepeaterHub(event.connection)
                core.openflow.addListenerByName("ConnectionUp", start_switch)




12年12月9日日曜日
NOX (C++)




12年12月9日日曜日
NOX (C++)
              #include <boost/bind.hpp>
              #include <boost/shared_array.hpp>
              #include "assert.hh"
              #include "component.hh"
              #include "flow.hh"
              #include "packet-in.hh"

              #include "vlog.hh"


              #include "netinet++/ethernet.hh"


              namespace {


              using namespace vigil;
              using namespace vigil::container;


              Vlog_module lg("hub");


              class Hub
                   : public Component
              {
              public:
                       Hub(const Context* c,
                              const json_object*)
                              : Component(c) { }


                   void configure(const Configuration*) {
                   }


                   Disposition handler(const Event& e)
                   {
                          const Packet_in_event& pi = assert_cast<const Packet_in_event&>(e);

                          uint32_t buffer_id = pi.buffer_id;
                          Flow flow(pi.in_port, *(pi.get_buffer()));


                          if (flow.dl_type == ethernet::LLDP){
                                 return CONTINUE;
                          }


                          ofp_flow_mod* ofm;
                          size_t size = sizeof *ofm + sizeof(ofp_action_output);
                          boost::shared_array<char> raw_of(new char[size]);
                          ofm = (ofp_flow_mod*) raw_of.get();


                          ofm->header.version = OFP_VERSION;
                          ofm->header.type = OFPT_FLOW_MOD;
                          ofm->header.length = htons(size);
                          ofm->match.wildcards = htonl(0);
                          ofm->match.in_port = htons(flow.in_port);
                          ofm->match.dl_vlan = flow.dl_vlan;
                          ofm->match.dl_vlan_pcp = flow.dl_vlan_pcp;
                          memcpy(ofm->match.dl_src, flow.dl_src.octet, sizeof ofm->match.dl_src);
                          memcpy(ofm->match.dl_dst, flow.dl_dst.octet, sizeof ofm->match.dl_dst);
                          ofm->match.dl_type = flow.dl_type;
                          ofm->match.nw_src = flow.nw_src;
                          ofm->match.nw_dst = flow.nw_dst;
                          ofm->match.nw_proto = flow.nw_proto;

                          ofm->match.tp_src = flow.tp_src;
                          ofm->match.tp_dst = flow.tp_dst;
                          ofm->cookie = htonl(0);
                          ofm->command = htons(OFPFC_ADD);
                          ofm->buffer_id = htonl(buffer_id);
                          ofm->idle_timeout = htons(5);
                          ofm->hard_timeout = htons(5);
                          ofm->priority = htons(OFP_DEFAULT_PRIORITY);
                          ofm->flags = htons(0);
                          ofp_action_output& action = *((ofp_action_output*)ofm->actions);
                          memset(&action, 0, sizeof(ofp_action_output));
                          action.type = htons(OFPAT_OUTPUT);
                          action.len = htons(sizeof(ofp_action_output));
                          action.port = htons(OFPP_FLOOD);
                          action.max_len = htons(0);
                          send_openflow_command(pi.datapath_id, &ofm->header, true);
                          free(ofm);


                          if (buffer_id == UINT32_MAX) {
                                 size_t data_len = pi.get_buffer()->size();
                                 size_t total_len = pi.total_len;
                                 if (total_len == data_len) {
                                     send_openflow_packet(pi.datapath_id, *pi.get_buffer(),
                                             OFPP_FLOOD, pi.in_port, true);
                                 }

                          }


                          return CONTINUE;
                   }


                   void install()
                   {
                          register_handler<Packet_in_event>(boost::bind(&Hub::handler, this, _1));
                   }
              };


              REGISTER_COMPONENT(container::Simple_component_factory<Hub>, Hub);


              }




12年12月9日日曜日
Floodlight (Java)




12年12月9日日曜日
Floodlight (Java)
              package net.floodlightcontroller.hub;

              import java.io.IOException;
              import java.util.ArrayList;
              import java.util.Collection;
              import java.util.Collections;
              import java.util.Map;
              import net.floodlightcontroller.core.FloodlightContext;
              import net.floodlightcontroller.core.IFloodlightProviderService;
              import net.floodlightcontroller.core.IOFMessageListener;
              import net.floodlightcontroller.core.IOFSwitch;
              import net.floodlightcontroller.core.module.FloodlightModuleContext;
              import net.floodlightcontroller.core.module.FloodlightModuleException;
              import net.floodlightcontroller.core.module.IFloodlightModule;
              import net.floodlightcontroller.core.module.IFloodlightService;
              import org.openflow.protocol.OFMessage;
              import org.openflow.protocol.OFPacketIn;
              import org.openflow.protocol.OFPacketOut;
              import org.openflow.protocol.OFPort;
              import org.openflow.protocol.OFType;
              import org.openflow.protocol.action.OFAction;
              import org.openflow.protocol.action.OFActionOutput;
              import org.openflow.util.U16;
              import org.slf4j.Logger;
              import org.slf4j.LoggerFactory;

              public class Hub implements IFloodlightModule, IOFMessageListener {
                protected static Logger log = LoggerFactory.getLogger(Hub.class);
                protected IFloodlightProviderService floodlightProvider;

                  public void setFloodlightProvider(IFloodlightProviderService floodlightProvider) {
                    this.floodlightProvider = floodlightProvider;
                  }

                  @Override
                  public String getName() {
                    return Hub.class.getPackage().getName();
                  }

                  public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
                    OFPacketIn pi = (OFPacketIn) msg;
                    OFPacketOut po = (OFPacketOut) floodlightProvider.getOFMessageFactory()
                           .getMessage(OFType.PACKET_OUT);
                    po.setBufferId(pi.getBufferId())
                        .setInPort(pi.getInPort());

                      OFActionOutput action = new OFActionOutput()
                        .setPort((short) OFPort.OFPP_FLOOD.getValue());
                      po.setActions(Collections.singletonList((OFAction)action));
                      po.setActionsLength((short) OFActionOutput.MINIMUM_LENGTH);

                      if (pi.getBufferId() == 0xffffffff) {
                          byte[] packetData = pi.getPacketData();
                          po.setLength(U16.t(OFPacketOut.MINIMUM_LENGTH
                                + po.getActionsLength() + packetData.length));
                          po.setPacketData(packetData);
                      } else {
                          po.setLength(U16.t(OFPacketOut.MINIMUM_LENGTH
                                + po.getActionsLength()));
                      }
                      try {
                          sw.write(po, cntx);
                      } catch (IOException e) {
                          log.error("Failure writing PacketOut", e);
                      }

                      return Command.CONTINUE;
                  }

                  @Override
                  public boolean isCallbackOrderingPrereq(OFType type, String name) {
                    return false;
                  }

                  @Override
                  public boolean isCallbackOrderingPostreq(OFType type, String name) {
                    return false;
                  }

                  @Override
                  public Collection<Class<? extends IFloodlightService>> getModuleServices() {
                    return null;
                  }

                  @Override
                  public Map<Class<? extends IFloodlightService>, IFloodlightService>
                        getServiceImpls() {
                    return null;
                  }

                  @Override
                  public Collection<Class<? extends IFloodlightService>>
                        getModuleDependencies() {
                    Collection<Class<? extends IFloodlightService>> l =
                           new ArrayList<Class<? extends IFloodlightService>>();
                    l.add(IFloodlightProviderService.class);
                    return l;
                  }

                  @Override
                  public void init(FloodlightModuleContext context)
                        throws FloodlightModuleException {
                    floodlightProvider =
                           context.getServiceImpl(IFloodlightProviderService.class);
                  }

                  @Override
                  public void startUp(FloodlightModuleContext context) {
                    floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
                  }
              }




12年12月9日日曜日
コード行数
         120                                                      111
                                                   95
              90


              60
                                      36
              30
                       14
               0
                   Trema (Ruby)   POX (Python)   NOX (C++)   Floodlight (Java)

12年12月9日日曜日
フローテーブルの書き込み
               send_flow_mod_add(
                                                        Trem
              dpid,
              :match => ExactMatch.from( message ),                 a
              :buffer_id => message.buffer_id,
              :actions => ActionOutput.new( message.in_port + 1 )
          )




                                                         NOX
          inst.install_datapath_flow(
            dpid,
            extract_flow(packet),
            CACHE_TIMEOUT,
            openflow.OFP_FLOW_PERMANENT,
            [[openflow.OFPAT_OUTPUT, [0, prt[0]]]],
            bufid,
            openflow.OFP_DEFAULT_PRIORITY,
            inport,
            buf
          )

12年12月9日日曜日
Tremaの哲学

       一、短く書けて、
       一、すぐに動くべし



                    と れ ま

                    取間先生
                            (C) Miramax Films 2004

12年12月9日日曜日
SDN開発の面倒さ




                   プログラマの声

12年12月9日日曜日
SDN開発の面倒さ
              "OpenFlow は開発環境の構築が面倒だ"
              (ネットワーク設定や VM 構築とか)




                            プログラマの声

12年12月9日日曜日
SDN開発の面倒さ
              "OpenFlow は開発環境の構築が面倒だ"
              (ネットワーク設定や VM 構築とか)

              "OpenFlow スイッチ持ってないよ"




                            プログラマの声

12年12月9日日曜日
SDN開発の面倒さ
              "OpenFlow は開発環境の構築が面倒だ"
              (ネットワーク設定や VM 構築とか)

              "OpenFlow スイッチ持ってないよ"

              "そもそも OpenFlow の実験ができる
              ネットワーク持ってないし..."
                            プログラマの声

12年12月9日日曜日
Tremaなら簡単!
          trema run         コントローラ
                       起動

              作成




12年12月9日日曜日
Tremaなら簡単!
          trema run         コントローラ
                       起動

              作成




12年12月9日日曜日
コントローラを書いてみよう
              # simple-controller.rb
              class SimpleController < Controller
              end



         コンパイルなしですぐに実行
          % trema run simple-controller.rb


12年12月9日日曜日
スイッチの起動を捕捉

              class SimpleController < Controller
                def switch_connected dpid
                    puts “Hello #{ dpid.to_hex }!”
                end
              end
                           “スイッチ起動”イベントの
                           ハンドラを追加

12年12月9日日曜日
仮想スイッチを接続
              # network.conf
              vswitch { dpid 0xabc }
              vswitch { dpid 0xdef }


          % trema run simple-controller.rb 
            -c network.conf
          Hello 0xabc!
          Hello 0xdef!


12年12月9日日曜日
OpenFlow/SDN FAQ


              「パケットは
               送れないの?」

12年12月9日日曜日
パケットを送る
              # network.conf
              vswitch { dpid 0xabc }
              vswitch { dpid 0xdef }
              vhost “host1”
              vhost “host2”
              link “0xabc”, “host1”
              link “0xdef”, “host2”


12年12月9日日曜日
パケットを送る
              class SimpleController < Controller

                def switch_connected dpid

                    puts “Hello #{ dpid.to_hex }!”

                end

                def packet_in dpid, message

                    puts “Unknown packet!”

                end

              end


12年12月9日日曜日
パケットを送る
              % trema send_packets --source host1 
                --dest host2 --n_pkts 10 --pps 10

              Unknown packet!

              Unknown packet!

              Unknown packet!

              Unknown packet!

              Unknown packet!

                ...


12年12月9日日曜日
SDN
      プログラミング分野の1つ
                     とは


               「GUIプログラミング」
                   とかと同じ!
12年12月9日日曜日
仮想ネットワークDSL

              開発マシン上に好きなトポロジを構築して
              コントローラを実行できる
              • テストパケットを送受信してコントローラを
              デバッグできる
              • 使える部品は仮想スイッチ、仮想ホスト、
              仮想リンク




12年12月9日日曜日
スイッチ10台のフルメッシュ接続を
         ベタ書き(約80行)
         vswitch   {   dpid   "0x1"   }
         vswitch   {   dpid   "0x2"   }
         vswitch   {   dpid   "0x3"   }
         vswitch   {   dpid   "0x4"   }
           ...

         link "0x1",    "0x2"
         link "0x1",    "0x3"
         link "0x1",    "0x4"
         link "0x1",    "0x5"
         link "0x1",    "0x6"
         link "0x1",    "0x7"
         link "0x1",    "0x8"
         link "0x1",    "0x9"
         link "0x1",    "0x10"
         link "0x2",    "0x3"
         link "0x2",    "0x4"
           ...




12年12月9日日曜日
言語内 DSL
         $nswitch = 10

         1.upto( $nswitch ).each do | sw1 |
           vswitch { dpid sw1.to_hex }

           1.upto( $nswitch ).each do | sw2 |
             if sw1 < sw2
               link sw1.to_hex, sw2.to_hex
             end
           end
         end

12年12月9日日曜日
OpenFlow/SDN FAQ



              「...GUIないの?」


12年12月9日日曜日
Tremashark




12年12月9日日曜日
12年12月9日日曜日
SDNでTDD




12年12月9日日曜日
SDNでTDD

              •   RSpecでネットワークを
                  ユニットテスト




12年12月9日日曜日
SDNでTDD

              •   RSpecでネットワークを
                  ユニットテスト

              •   ホスト間でのパケットの送受信数




12年12月9日日曜日
SDNでTDD

              •   RSpecでネットワークを
                  ユニットテスト

              •   ホスト間でのパケットの送受信数

              • スイッチのフローテーブルの中身




12年12月9日日曜日
SDNでTDD

              •   RSpecでネットワークを
                  ユニットテスト

              •   ホスト間でのパケットの送受信数

              • スイッチのフローテーブルの中身

              • Etc.


12年12月9日日曜日
ハブのテストコード
         describe RepeaterHub do
        around do | example |
          network { # ネットワークの定義
            vswitch("switch") { datapath_id "0xabc" }
            vhost("host1") { promisc "on" }                      仮想NWで
            vhost("host2") { promisc "on" }
            link "switch", "host1"                               ハブを動かし、
            link "switch", "host2"
          }.run( RepeaterHub ) {
            example.run
          }
        end

        context "when host1 sends one packet to host2" do
          describe "switch" do
            before { send_packets "host1", "host2" }
            subject { switch( "switch" ) }
                                                                 フローテーブル
            it { should have( 1 ).flows }
            its( "flows.first.actions" ) { should == "FLOOD" }
                                                                 の中身をテスト
          end

              ...



12年12月9日日曜日
まとめ

         •    SDNはプログラミング
         •やってるとこはやっている
              (Google、Trema)
         •    Tremaで楽に作ろう

12年12月9日日曜日
Amazon で
              好評予約中!




12年12月9日日曜日

Weitere ähnliche Inhalte

Andere mochten auch

アプリ屋 対 ネットワーク屋
アプリ屋 対 ネットワーク屋アプリ屋 対 ネットワーク屋
アプリ屋 対 ネットワーク屋Yasuhito Takamiya
 
物理ネットワーク受け入れテストツールNetTester あるいは私は如何にして心配するのを止めてネットワーク管理を・愛する・ようになったか
物理ネットワーク受け入れテストツールNetTester あるいは私は如何にして心配するのを止めてネットワーク管理を・愛する・ようになったか物理ネットワーク受け入れテストツールNetTester あるいは私は如何にして心配するのを止めてネットワーク管理を・愛する・ようになったか
物理ネットワーク受け入れテストツールNetTester あるいは私は如何にして心配するのを止めてネットワーク管理を・愛する・ようになったかYasuhito Takamiya
 
Microsoft MVP から見たクラウド サービスの現状と今後について
Microsoft MVP から見たクラウド サービスの現状と今後についてMicrosoft MVP から見たクラウド サービスの現状と今後について
Microsoft MVP から見たクラウド サービスの現状と今後についてIIJ
 
L2 over L3 ecnaspsulations
L2 over L3 ecnaspsulationsL2 over L3 ecnaspsulations
L2 over L3 ecnaspsulationsMotonori Shindo
 
OpenFlow フレームワークの選びかた
OpenFlow フレームワークの選びかたOpenFlow フレームワークの選びかた
OpenFlow フレームワークの選びかたYasuhito Takamiya
 
SDNフレームワークの解説と、OpenFlowコントローラのプログラミングおよび実演
SDNフレームワークの解説と、OpenFlowコントローラのプログラミングおよび実演SDNフレームワークの解説と、OpenFlowコントローラのプログラミングおよび実演
SDNフレームワークの解説と、OpenFlowコントローラのプログラミングおよび実演孝史 菱野
 
Cloud Days Tokyo 2014 Spring 「80分でばっちり理解するOpenFlow」 NEC宮永直樹
Cloud Days Tokyo 2014 Spring 「80分でばっちり理解するOpenFlow」 NEC宮永直樹Cloud Days Tokyo 2014 Spring 「80分でばっちり理解するOpenFlow」 NEC宮永直樹
Cloud Days Tokyo 2014 Spring 「80分でばっちり理解するOpenFlow」 NEC宮永直樹Naoki Miyanaga
 
社内ネットワーク改善の過程で分かった物理ゆえの闇と脆弱性そしてネットワークの基礎入門
社内ネットワーク改善の過程で分かった物理ゆえの闇と脆弱性そしてネットワークの基礎入門社内ネットワーク改善の過程で分かった物理ゆえの闇と脆弱性そしてネットワークの基礎入門
社内ネットワーク改善の過程で分かった物理ゆえの闇と脆弱性そしてネットワークの基礎入門zaru sakuraba
 
#qpstudy 2016.07 第一部 基礎知識編 「ご認証は認可ですか?」
#qpstudy 2016.07  第一部 基礎知識編 「ご認証は認可ですか?」#qpstudy 2016.07  第一部 基礎知識編 「ご認証は認可ですか?」
#qpstudy 2016.07 第一部 基礎知識編 「ご認証は認可ですか?」 Masahiro NAKAYAMA
 
物理ネットワーク受け入れテストの自動化を考える
物理ネットワーク受け入れテストの自動化を考える物理ネットワーク受け入れテストの自動化を考える
物理ネットワーク受け入れテストの自動化を考えるskipping classes
 
小学生でもわかるSDN
小学生でもわかるSDN小学生でもわかるSDN
小学生でもわかるSDNKen SASAKI
 
Open blockchain in a nutshell
Open blockchain in a nutshellOpen blockchain in a nutshell
Open blockchain in a nutshellTakeshi Matsubara
 

Andere mochten auch (14)

アプリ屋 対 ネットワーク屋
アプリ屋 対 ネットワーク屋アプリ屋 対 ネットワーク屋
アプリ屋 対 ネットワーク屋
 
Bop1
Bop1Bop1
Bop1
 
物理ネットワーク受け入れテストツールNetTester あるいは私は如何にして心配するのを止めてネットワーク管理を・愛する・ようになったか
物理ネットワーク受け入れテストツールNetTester あるいは私は如何にして心配するのを止めてネットワーク管理を・愛する・ようになったか物理ネットワーク受け入れテストツールNetTester あるいは私は如何にして心配するのを止めてネットワーク管理を・愛する・ようになったか
物理ネットワーク受け入れテストツールNetTester あるいは私は如何にして心配するのを止めてネットワーク管理を・愛する・ようになったか
 
OpenFlow Group Table
OpenFlow Group TableOpenFlow Group Table
OpenFlow Group Table
 
Microsoft MVP から見たクラウド サービスの現状と今後について
Microsoft MVP から見たクラウド サービスの現状と今後についてMicrosoft MVP から見たクラウド サービスの現状と今後について
Microsoft MVP から見たクラウド サービスの現状と今後について
 
L2 over L3 ecnaspsulations
L2 over L3 ecnaspsulationsL2 over L3 ecnaspsulations
L2 over L3 ecnaspsulations
 
OpenFlow フレームワークの選びかた
OpenFlow フレームワークの選びかたOpenFlow フレームワークの選びかた
OpenFlow フレームワークの選びかた
 
SDNフレームワークの解説と、OpenFlowコントローラのプログラミングおよび実演
SDNフレームワークの解説と、OpenFlowコントローラのプログラミングおよび実演SDNフレームワークの解説と、OpenFlowコントローラのプログラミングおよび実演
SDNフレームワークの解説と、OpenFlowコントローラのプログラミングおよび実演
 
Cloud Days Tokyo 2014 Spring 「80分でばっちり理解するOpenFlow」 NEC宮永直樹
Cloud Days Tokyo 2014 Spring 「80分でばっちり理解するOpenFlow」 NEC宮永直樹Cloud Days Tokyo 2014 Spring 「80分でばっちり理解するOpenFlow」 NEC宮永直樹
Cloud Days Tokyo 2014 Spring 「80分でばっちり理解するOpenFlow」 NEC宮永直樹
 
社内ネットワーク改善の過程で分かった物理ゆえの闇と脆弱性そしてネットワークの基礎入門
社内ネットワーク改善の過程で分かった物理ゆえの闇と脆弱性そしてネットワークの基礎入門社内ネットワーク改善の過程で分かった物理ゆえの闇と脆弱性そしてネットワークの基礎入門
社内ネットワーク改善の過程で分かった物理ゆえの闇と脆弱性そしてネットワークの基礎入門
 
#qpstudy 2016.07 第一部 基礎知識編 「ご認証は認可ですか?」
#qpstudy 2016.07  第一部 基礎知識編 「ご認証は認可ですか?」#qpstudy 2016.07  第一部 基礎知識編 「ご認証は認可ですか?」
#qpstudy 2016.07 第一部 基礎知識編 「ご認証は認可ですか?」
 
物理ネットワーク受け入れテストの自動化を考える
物理ネットワーク受け入れテストの自動化を考える物理ネットワーク受け入れテストの自動化を考える
物理ネットワーク受け入れテストの自動化を考える
 
小学生でもわかるSDN
小学生でもわかるSDN小学生でもわかるSDN
小学生でもわかるSDN
 
Open blockchain in a nutshell
Open blockchain in a nutshellOpen blockchain in a nutshell
Open blockchain in a nutshell
 

Ähnlich wie SDN時代の開発よもやま話 - OpenFlowとTrema

セプテーニさんでのセミナー
セプテーニさんでのセミナーセプテーニさんでのセミナー
セプテーニさんでのセミナーTokusei Noborio
 
社会ネットワーク分析第7回
社会ネットワーク分析第7回社会ネットワーク分析第7回
社会ネットワーク分析第7回Satoru Mikami
 
NoSQLとビックデータ入門編Update版
NoSQLとビックデータ入門編Update版NoSQLとビックデータ入門編Update版
NoSQLとビックデータ入門編Update版Koichiro Nishijima
 
「ほげエンジニア」の定義について #operationcasual
「ほげエンジニア」の定義について #operationcasual「ほげエンジニア」の定義について #operationcasual
「ほげエンジニア」の定義について #operationcasualSATOSHI TAGOMORI
 
CyberAgentにおけるMongoDB
CyberAgentにおけるMongoDBCyberAgentにおけるMongoDB
CyberAgentにおけるMongoDBAkihiro Kuwano
 
OSC2012.Cloud_CloudStack概要
OSC2012.Cloud_CloudStack概要OSC2012.Cloud_CloudStack概要
OSC2012.Cloud_CloudStack概要Midori Oge
 

Ähnlich wie SDN時代の開発よもやま話 - OpenFlowとTrema (7)

セプテーニさんでのセミナー
セプテーニさんでのセミナーセプテーニさんでのセミナー
セプテーニさんでのセミナー
 
社会ネットワーク分析第7回
社会ネットワーク分析第7回社会ネットワーク分析第7回
社会ネットワーク分析第7回
 
NoSQLとビックデータ入門編Update版
NoSQLとビックデータ入門編Update版NoSQLとビックデータ入門編Update版
NoSQLとビックデータ入門編Update版
 
DRBD9とdrbdmanageの紹介
DRBD9とdrbdmanageの紹介DRBD9とdrbdmanageの紹介
DRBD9とdrbdmanageの紹介
 
「ほげエンジニア」の定義について #operationcasual
「ほげエンジニア」の定義について #operationcasual「ほげエンジニア」の定義について #operationcasual
「ほげエンジニア」の定義について #operationcasual
 
CyberAgentにおけるMongoDB
CyberAgentにおけるMongoDBCyberAgentにおけるMongoDB
CyberAgentにおけるMongoDB
 
OSC2012.Cloud_CloudStack概要
OSC2012.Cloud_CloudStack概要OSC2012.Cloud_CloudStack概要
OSC2012.Cloud_CloudStack概要
 

Mehr von Yasuhito Takamiya

Tremaプログラミング ウル技(テク) 大技林
Tremaプログラミング ウル技(テク) 大技林Tremaプログラミング ウル技(テク) 大技林
Tremaプログラミング ウル技(テク) 大技林Yasuhito Takamiya
 
Ruby でパケットパーサを作ろう
Ruby でパケットパーサを作ろうRuby でパケットパーサを作ろう
Ruby でパケットパーサを作ろうYasuhito Takamiya
 
クラウドインターネットルータ
クラウドインターネットルータクラウドインターネットルータ
クラウドインターネットルータYasuhito Takamiya
 
Trema コミッタになるには
Trema コミッタになるにはTrema コミッタになるには
Trema コミッタになるにはYasuhito Takamiya
 
Bare Metal Cloud: 実マシンを提供するクラウドサービス (SWoPP 2010)
Bare Metal Cloud: 実マシンを提供するクラウドサービス (SWoPP 2010)Bare Metal Cloud: 実マシンを提供するクラウドサービス (SWoPP 2010)
Bare Metal Cloud: 実マシンを提供するクラウドサービス (SWoPP 2010)Yasuhito Takamiya
 

Mehr von Yasuhito Takamiya (6)

Tremaプログラミング ウル技(テク) 大技林
Tremaプログラミング ウル技(テク) 大技林Tremaプログラミング ウル技(テク) 大技林
Tremaプログラミング ウル技(テク) 大技林
 
データで見るTrema
データで見るTremaデータで見るTrema
データで見るTrema
 
Ruby でパケットパーサを作ろう
Ruby でパケットパーサを作ろうRuby でパケットパーサを作ろう
Ruby でパケットパーサを作ろう
 
クラウドインターネットルータ
クラウドインターネットルータクラウドインターネットルータ
クラウドインターネットルータ
 
Trema コミッタになるには
Trema コミッタになるにはTrema コミッタになるには
Trema コミッタになるには
 
Bare Metal Cloud: 実マシンを提供するクラウドサービス (SWoPP 2010)
Bare Metal Cloud: 実マシンを提供するクラウドサービス (SWoPP 2010)Bare Metal Cloud: 実マシンを提供するクラウドサービス (SWoPP 2010)
Bare Metal Cloud: 実マシンを提供するクラウドサービス (SWoPP 2010)
 

SDN時代の開発よもやま話 - OpenFlowとTrema

  • 1. ∼SDN時代の開発よもやま話∼ OpenFlowとTrema 高宮安仁 (Trema開発チーム) 12年12月9日日曜日
  • 2. FAQ よくある疑問 12年12月9日日曜日
  • 3. OpenFlow/SDN FAQ 「何の役に立つの?」 12年12月9日日曜日
  • 4. 世界で初めて、 OpenFlow/SDN 開発を扱った本 2013/1/8 発売 12年12月9日日曜日
  • 5. SDN とは 12年12月9日日曜日
  • 6. SDN とは プログラミング分野の1つ 12年12月9日日曜日
  • 7. SDN プログラミング分野の1つ とは 「GUIプログラミング」 とかと同じ! 12年12月9日日曜日
  • 9. OpenFlow とは SDNのいち実装方式 12年12月9日日曜日
  • 10. OpenFlow とは SDNのいち実装方式 GtkとかCocoa とかと同じ! 12年12月9日日曜日
  • 11. SDN つまり OpenFlow 12年12月9日日曜日
  • 12. SDN つまり OpenFlow は純粋にソフトウェア開発の話。 12年12月9日日曜日
  • 13. MAKE 「評論もいーけど、動いて役に 立つもの作りません?」 12年12月9日日曜日
  • 14. すでにバックボーンは OpenFlowで作っちゃた Urs Hölzle http://itpro.nikkeibp.co.jp/article/NEWS/20120418/391401/ 12年12月9日日曜日
  • 15. OpenFlow/SDN FAQ 「何の役に立つの?」 →Googleの事例を解説 12年12月9日日曜日
  • 16. Googleのチャレンジ 最先 • 平均 PUE = 1.13 端 • 年間アベイラビリティ = 99.984% • 処理するデータ量/day = 数十ペタ 12年12月9日日曜日
  • 17. Googleのチャレンジ 最先 • 平均 PUE = 1.13 端 • 年間アベイラビリティ = 99.984% • 処理するデータ量/day = 数十ペタ 次の チャレンジは データセンター をつなぐネッ トワークだ! 12年12月9日日曜日
  • 18. WAN 回線のコスト 日米間(4.8Tbps、1万km)=320億円 12年12月9日日曜日
  • 19. WAN 回線のコスト 日米間(4.8Tbps、1万km)=320億円 回線を 追加せずに、 既存のを有 効活用したい 12年12月9日日曜日
  • 20. DC どれだけ流せる? DC DC 12年12月9日日曜日
  • 21. 従来のルーティング • ルータは自律分散で動く • 宛先に対して必ず最短路を選択 • 帯域の使用量は加味してくれない 12年12月9日日曜日
  • 22. DC 集中 DC ヒマ? DC 12年12月9日日曜日
  • 23. DC 理想 DC DC 12年12月9日日曜日
  • 24. 帯域は? DC DC 10Gbps 6Gbps DC 12年12月9日日曜日
  • 25. DC DC 10Gbps ? 6Gbps DC 12年12月9日日曜日
  • 26. DC DC どう分ける? DC 12年12月9日日曜日
  • 27. TEサーバ DC DC DC 12年12月9日日曜日
  • 28. TEサーバ DC 空き帯域 DC の収集 DC 12年12月9日日曜日
  • 29. TEサーバ DC 空き帯域 DC 帯域の の収集 割り当て DC 12年12月9日日曜日
  • 30. TEサーバ DC DC DC 12年12月9日日曜日
  • 31. TEサーバ DC DC DC 12年12月9日日曜日
  • 32. TEサーバ DC BGPルータ BGP処理部 コントローラ OpenFlow 12年12月9日日曜日 スイッチ
  • 33. TEサーバ DC BGPルータ BGP処理部 経路情報 コントローラ OpenFlow 12年12月9日日曜日 スイッチ
  • 34. TEサーバ DC BGPルータ BGP処理部 経路情報 コントローラ トラフィック 情報 OpenFlow 12年12月9日日曜日 スイッチ
  • 35. TEサーバ DC BGPルータ BGP処理部 経路情報 コントローラ トラフィック 情報 OpenFlow 12年12月9日日曜日 スイッチ
  • 36. TEサーバ 経路制御 DC BGPルータ BGP処理部 経路情報 コントローラ トラフィック 情報 OpenFlow 12年12月9日日曜日 スイッチ
  • 37. TEサーバ 経路制御 DC BGPルータ BGP処理部 経路情報 コントローラ トラフィック 情報 OpenFlow 12年12月9日日曜日 スイッチ
  • 38. Google WANの利用率 ほぼ100% 使い切り 12年12月9日日曜日
  • 39. TEサーバ DC BGPルータ BGP処理部 コントローラ OpenFlow 12年12月9日日曜日 スイッチ
  • 40. OpenFlow/SDN FAQ 「どういう仕組み?」 12年12月9日日曜日
  • 41. 2分で分かる OpenFlow 12年12月9日日曜日
  • 42. 従来のスイッチ 制御する パケットの ソフトウェア 転送ルール ファーム フロー ウェア領域 テーブル 12年12月9日日曜日
  • 43. ソフトウェア コントローラ OpenFlow プロトコル フロー テーブル ハードウェア 12年12月9日日曜日
  • 44. コントローラ フロー テーブル 転送ルール を参照 速い 12年12月9日日曜日
  • 45. コントローラ 知らない パケット フロー テーブル 転送ルール を参照 速い 12年12月9日日曜日
  • 46. コントローラ フローテーブル の更新 知らない パケット フロー テーブル 転送ルール を参照 速い 12年12月9日日曜日
  • 47. コントローラ フローテーブル 遅い の更新 知らない パケット フロー テーブル 転送ルール を参照 速い 12年12月9日日曜日
  • 48. OpenFlow/SDN FAQ 「何がうれしいの?」 12年12月9日日曜日
  • 50. OpenFlowのうれしさ • ソフトウェアによる高い自由度 12年12月9日日曜日
  • 51. OpenFlowのうれしさ • ソフトウェアによる高い自由度 • システム連携と自動化 12年12月9日日曜日
  • 52. OpenFlowのうれしさ • ソフトウェアによる高い自由度 • システム連携と自動化 • ソフトウェア開発手法をネットワーク に適用できる 12年12月9日日曜日
  • 53. コントローラ 好きな言語で書ける OpenFlow Ruby, Python, C++,Java,... プロトコル フロー テーブル 既存のプロトコルに 縛られない (e.g.,VLANの上限) 12年12月9日日曜日
  • 54. TEサーバ ミドル DB コントローラ 自由に連携 フロー テーブル 12年12月9日日曜日
  • 55. データセンター GFS Paxos Chubby 12年12月9日日曜日
  • 56. データセンター GFS Paxos コントローラ Chubby フロー テーブル 12年12月9日日曜日
  • 57. データセンター GFS Paxos コントローラ Chubby フロー テーブル 12年12月9日日曜日
  • 59. ソフトウェア手法の応用 • ネットワークを段階的に反復構築 (アジャイル) 12年12月9日日曜日
  • 60. ソフトウェア手法の応用 • ネットワークを段階的に反復構築 (アジャイル) • ネットワークのテスト (各種テスト、テストドリブン) 12年12月9日日曜日
  • 61. ソフトウェア手法の応用 • ネットワークを段階的に反復構築 (アジャイル) • ネットワークのテスト (各種テスト、テストドリブン) • バージョン管理や巻き戻し (git などのバージョン管理ツール) 12年12月9日日曜日
  • 62. OpenFlow/SDN FAQ 「フローテーブルで 何ができるの?」 12年12月9日日曜日
  • 64. スイッチ コントローラ パケットの宛先 MACアドレス →出力ポート 転送 12年12月9日日曜日
  • 65. スイッチ(トラフィックモニタ) コントローラ トラフィック 情報 流量 転送 12年12月9日日曜日
  • 66. ルータ コントローラ 書き換え 転送 送信元・宛先 MACアドレスを 書き換え 12年12月9日日曜日
  • 68. ロードバランサ バックエンド コントローラ サーバ トラフィック 情報 流量 書き換え 転送 トラフィック量に 応じて転送先を調整 12年12月9日日曜日
  • 69. 帯域を目一杯使う DC DC 転送 転送 転送 転送 転送 転送 12年12月9日日曜日
  • 70. レプリケーション DC 分岐 DC DC 分岐 DC 分岐 DC 12年12月9日日曜日
  • 71. パッチパネル コントローラ ネットワーク A 転送 ネットワーク 所属するネットワーク B をソフトウェアで切り替え 12年12月9日日曜日
  • 72. パッチパネル コントローラ ネットワーク A 転送 ネットワーク 所属するネットワーク B をソフトウェアで切り替え 12年12月9日日曜日
  • 73. パッチパネル コントローラ ネットワーク A 転送 ネットワーク 所属するネットワーク B をソフトウェアで切り替え 12年12月9日日曜日
  • 74. OpenFlow/SDN FAQ 「どう作るの?」 12年12月9日日曜日
  • 75. 主なOpenFlow プログラミングフレームワーク •Trema (Ruby) • POX (Python) • NOX (C++) • Floodlight (Java) 12年12月9日日曜日
  • 77. バージョン対応状況 1.0 1.1 1.2 1.3 12年12月9日日曜日
  • 78. バージョン対応状況 Trema POX NOX Floodlight 1.0 1.1 1.2 1.3 12年12月9日日曜日
  • 79. バージョン対応状況 Trema POX NOX Floodlight TremaEdge 1.0 1.1 1.2 1.3 12年12月9日日曜日
  • 82. watcher数: 1位 Trema 123 Floodlight 91 POX 68 OpenFaucet 28 NOX 17 12/6/2012 調べ 12年12月9日日曜日
  • 83. サンプルApp数: 1位 Trema 29 NOX 16 POX 5 01101101 Beacon 4 11010101 Floodlight 3 01111101 OpenFaucet 0 01010111 12年12月9日日曜日
  • 84. OpenFlow/SDN FAQ 「どんな実アプリが あるの?」 12年12月9日日曜日
  • 85. Wakame-VDC http://wakame.jp/document/15/ • コンパクトな Ruby 製 IaaS 基盤ソフト (e.g., OpenStack、Eucalyptus) • 九州電力、NII など採用事例たくさん • Rails による GUI • ネットワークとストレージの仮想化 12年12月9日日曜日
  • 88. OpenFlow/SDN FAQ 「ネットワーク カソウカ?」 12年12月9日日曜日
  • 90. パッチパネル コントローラ ネットワーク A 転送 ネットワーク 所属するネットワーク B をソフトウェアで切り替え 12年12月9日日曜日
  • 91. 「OpenFlowスイッチ がないとダメ?」 12年12月9日日曜日
  • 92. Wakame のエッジ仮想化 VM VM VM SW スイッチ 物理ホスト 既存の ネットワーク 12年12月9日日曜日
  • 93. IP アドレスがかぶると? ユーザ X ユーザ Y 192.168.0.1 192.168.0.2 192.168.0.1 192.168.0.2 VM VM VM VM 普通のスイッチ →ユニキャストなら問題なし 12年12月9日日曜日
  • 94. IP アドレスがかぶると? ユーザ X ユーザ Y はーい! 192.168.0.2 はーい! 192.168.0.1 192.168.0.1 192.168.0.2 VM VM VM VM 192.168.0.2 の MACアドレスは? 普通のスイッチ →ブロードキャストで問題 12年12月9日日曜日
  • 95. エッジスイッチでブロック ユーザ X ユーザ Y 192.168.0.1 はーい! 192.168.0.2 192.168.0.1 192.168.0.2 VM VM VM VM 192.168.0.2 の MACアドレスは? エッジスイッチ 12年12月9日日曜日
  • 96. エッジスイッチで書き換え ホストA ホストB ユーザ X ユーザ Y ユーザ X ユーザ Y VM VM VM VM 宛先を 元に戻す ホストBへ 12年12月9日日曜日
  • 97. OpenFlow/SDN FAQ 「そろそろTrema でのプログラミング を教えて!」 12年12月9日日曜日
  • 99. Tremaの特長 「今風」なフレームワーク 12年12月9日日曜日
  • 100. Tremaの特長 「今風」なフレームワーク • Rubyによる簡潔な記述 12年12月9日日曜日
  • 101. Tremaの特長 「今風」なフレームワーク • Rubyによる簡潔な記述 • フルスタック: ノートPC一台で開発 12年12月9日日曜日
  • 102. Tremaの特長 「今風」なフレームワーク • Rubyによる簡潔な記述 • フルスタック: ノートPC一台で開発 • GitHub上でのオープンな開発 (GPL2) 12年12月9日日曜日
  • 103. Tremaの哲学 一、短く書けて、 一、すぐに動くべし と れ ま 取間先生 (C) Miramax Films 2004 12年12月9日日曜日
  • 104. OpenFlow/SDN FAQ 「なぜ短く?」 12年12月9日日曜日
  • 105. 短ければ短いほど、 • 早くサッと作れて、 • バグの発生率が小さく、 • 後々のメンテも楽だから 12年12月9日日曜日
  • 106. Trema でハブ class RepeaterHub < Controller def packet_in datapath_id, message send_flow_mod_add( datapath_id, :match => ExactMatch.from( message ), :actions => SendOutPort.new( OFPP_FLOOD ) ) send_packet_out( datapath_id, :packet_in => message, :actions => SendOutPort.new( OFPP_FLOOD ) ) end end 12年12月9日日曜日
  • 108. POX (Python) from pox.core import core import pox.openflow.libopenflow_01 as of class RepeaterHub (object): def __init__ (self, connection): self.connection = connection connection.addListeners(self) def send_packet (self, buffer_id, raw_data, out_port, in_port): msg = of.ofp_packet_out() msg.in_port = in_port if buffer_id != -1 and buffer_id is not None: msg.buffer_id = buffer_id else: if raw_data is None: return msg.data = raw_data action = of.ofp_action_output(port = out_port) msg.actions.append(action) self.connection.send(msg) def act_like_hub (self, packet, packet_in): self.send_packet(packet_in.buffer_id, packet_in.data, of.OFPP_FLOOD, packet_in.in_port) def _handle_PacketIn (self, event): packet = event.parsed if not packet.parsed: return packet_in = event.ofp # The actual ofp_packet_in message. self.act_like_hub(packet, packet_in) def launch (): def start_switch (event): RepeaterHub(event.connection) core.openflow.addListenerByName("ConnectionUp", start_switch) 12年12月9日日曜日
  • 110. NOX (C++) #include <boost/bind.hpp> #include <boost/shared_array.hpp> #include "assert.hh" #include "component.hh" #include "flow.hh" #include "packet-in.hh" #include "vlog.hh" #include "netinet++/ethernet.hh" namespace { using namespace vigil; using namespace vigil::container; Vlog_module lg("hub"); class Hub : public Component { public: Hub(const Context* c, const json_object*) : Component(c) { } void configure(const Configuration*) { } Disposition handler(const Event& e) { const Packet_in_event& pi = assert_cast<const Packet_in_event&>(e); uint32_t buffer_id = pi.buffer_id; Flow flow(pi.in_port, *(pi.get_buffer())); if (flow.dl_type == ethernet::LLDP){ return CONTINUE; } ofp_flow_mod* ofm; size_t size = sizeof *ofm + sizeof(ofp_action_output); boost::shared_array<char> raw_of(new char[size]); ofm = (ofp_flow_mod*) raw_of.get(); ofm->header.version = OFP_VERSION; ofm->header.type = OFPT_FLOW_MOD; ofm->header.length = htons(size); ofm->match.wildcards = htonl(0); ofm->match.in_port = htons(flow.in_port); ofm->match.dl_vlan = flow.dl_vlan; ofm->match.dl_vlan_pcp = flow.dl_vlan_pcp; memcpy(ofm->match.dl_src, flow.dl_src.octet, sizeof ofm->match.dl_src); memcpy(ofm->match.dl_dst, flow.dl_dst.octet, sizeof ofm->match.dl_dst); ofm->match.dl_type = flow.dl_type; ofm->match.nw_src = flow.nw_src; ofm->match.nw_dst = flow.nw_dst; ofm->match.nw_proto = flow.nw_proto; ofm->match.tp_src = flow.tp_src; ofm->match.tp_dst = flow.tp_dst; ofm->cookie = htonl(0); ofm->command = htons(OFPFC_ADD); ofm->buffer_id = htonl(buffer_id); ofm->idle_timeout = htons(5); ofm->hard_timeout = htons(5); ofm->priority = htons(OFP_DEFAULT_PRIORITY); ofm->flags = htons(0); ofp_action_output& action = *((ofp_action_output*)ofm->actions); memset(&action, 0, sizeof(ofp_action_output)); action.type = htons(OFPAT_OUTPUT); action.len = htons(sizeof(ofp_action_output)); action.port = htons(OFPP_FLOOD); action.max_len = htons(0); send_openflow_command(pi.datapath_id, &ofm->header, true); free(ofm); if (buffer_id == UINT32_MAX) { size_t data_len = pi.get_buffer()->size(); size_t total_len = pi.total_len; if (total_len == data_len) { send_openflow_packet(pi.datapath_id, *pi.get_buffer(), OFPP_FLOOD, pi.in_port, true); } } return CONTINUE; } void install() { register_handler<Packet_in_event>(boost::bind(&Hub::handler, this, _1)); } }; REGISTER_COMPONENT(container::Simple_component_factory<Hub>, Hub); } 12年12月9日日曜日
  • 112. Floodlight (Java) package net.floodlightcontroller.hub; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Map; import net.floodlightcontroller.core.FloodlightContext; import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFMessageListener; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.module.FloodlightModuleContext; import net.floodlightcontroller.core.module.FloodlightModuleException; import net.floodlightcontroller.core.module.IFloodlightModule; import net.floodlightcontroller.core.module.IFloodlightService; import org.openflow.protocol.OFMessage; import org.openflow.protocol.OFPacketIn; import org.openflow.protocol.OFPacketOut; import org.openflow.protocol.OFPort; import org.openflow.protocol.OFType; import org.openflow.protocol.action.OFAction; import org.openflow.protocol.action.OFActionOutput; import org.openflow.util.U16; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Hub implements IFloodlightModule, IOFMessageListener { protected static Logger log = LoggerFactory.getLogger(Hub.class); protected IFloodlightProviderService floodlightProvider; public void setFloodlightProvider(IFloodlightProviderService floodlightProvider) { this.floodlightProvider = floodlightProvider; } @Override public String getName() { return Hub.class.getPackage().getName(); } public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) { OFPacketIn pi = (OFPacketIn) msg; OFPacketOut po = (OFPacketOut) floodlightProvider.getOFMessageFactory() .getMessage(OFType.PACKET_OUT); po.setBufferId(pi.getBufferId()) .setInPort(pi.getInPort()); OFActionOutput action = new OFActionOutput() .setPort((short) OFPort.OFPP_FLOOD.getValue()); po.setActions(Collections.singletonList((OFAction)action)); po.setActionsLength((short) OFActionOutput.MINIMUM_LENGTH); if (pi.getBufferId() == 0xffffffff) { byte[] packetData = pi.getPacketData(); po.setLength(U16.t(OFPacketOut.MINIMUM_LENGTH + po.getActionsLength() + packetData.length)); po.setPacketData(packetData); } else { po.setLength(U16.t(OFPacketOut.MINIMUM_LENGTH + po.getActionsLength())); } try { sw.write(po, cntx); } catch (IOException e) { log.error("Failure writing PacketOut", e); } return Command.CONTINUE; } @Override public boolean isCallbackOrderingPrereq(OFType type, String name) { return false; } @Override public boolean isCallbackOrderingPostreq(OFType type, String name) { return false; } @Override public Collection<Class<? extends IFloodlightService>> getModuleServices() { return null; } @Override public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() { return null; } @Override public Collection<Class<? extends IFloodlightService>> getModuleDependencies() { Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>(); l.add(IFloodlightProviderService.class); return l; } @Override public void init(FloodlightModuleContext context) throws FloodlightModuleException { floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class); } @Override public void startUp(FloodlightModuleContext context) { floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this); } } 12年12月9日日曜日
  • 113. コード行数 120 111 95 90 60 36 30 14 0 Trema (Ruby) POX (Python) NOX (C++) Floodlight (Java) 12年12月9日日曜日
  • 114. フローテーブルの書き込み send_flow_mod_add( Trem dpid, :match => ExactMatch.from( message ), a :buffer_id => message.buffer_id, :actions => ActionOutput.new( message.in_port + 1 ) ) NOX inst.install_datapath_flow( dpid, extract_flow(packet), CACHE_TIMEOUT, openflow.OFP_FLOW_PERMANENT, [[openflow.OFPAT_OUTPUT, [0, prt[0]]]], bufid, openflow.OFP_DEFAULT_PRIORITY, inport, buf ) 12年12月9日日曜日
  • 115. Tremaの哲学 一、短く書けて、 一、すぐに動くべし と れ ま 取間先生 (C) Miramax Films 2004 12年12月9日日曜日
  • 116. SDN開発の面倒さ プログラマの声 12年12月9日日曜日
  • 117. SDN開発の面倒さ "OpenFlow は開発環境の構築が面倒だ" (ネットワーク設定や VM 構築とか) プログラマの声 12年12月9日日曜日
  • 118. SDN開発の面倒さ "OpenFlow は開発環境の構築が面倒だ" (ネットワーク設定や VM 構築とか) "OpenFlow スイッチ持ってないよ" プログラマの声 12年12月9日日曜日
  • 119. SDN開発の面倒さ "OpenFlow は開発環境の構築が面倒だ" (ネットワーク設定や VM 構築とか) "OpenFlow スイッチ持ってないよ" "そもそも OpenFlow の実験ができる ネットワーク持ってないし..." プログラマの声 12年12月9日日曜日
  • 120. Tremaなら簡単! trema run コントローラ 起動 作成 12年12月9日日曜日
  • 121. Tremaなら簡単! trema run コントローラ 起動 作成 12年12月9日日曜日
  • 122. コントローラを書いてみよう # simple-controller.rb class SimpleController < Controller end コンパイルなしですぐに実行 % trema run simple-controller.rb 12年12月9日日曜日
  • 123. スイッチの起動を捕捉 class SimpleController < Controller def switch_connected dpid puts “Hello #{ dpid.to_hex }!” end end “スイッチ起動”イベントの ハンドラを追加 12年12月9日日曜日
  • 124. 仮想スイッチを接続 # network.conf vswitch { dpid 0xabc } vswitch { dpid 0xdef } % trema run simple-controller.rb -c network.conf Hello 0xabc! Hello 0xdef! 12年12月9日日曜日
  • 125. OpenFlow/SDN FAQ 「パケットは 送れないの?」 12年12月9日日曜日
  • 126. パケットを送る # network.conf vswitch { dpid 0xabc } vswitch { dpid 0xdef } vhost “host1” vhost “host2” link “0xabc”, “host1” link “0xdef”, “host2” 12年12月9日日曜日
  • 127. パケットを送る class SimpleController < Controller def switch_connected dpid puts “Hello #{ dpid.to_hex }!” end def packet_in dpid, message puts “Unknown packet!” end end 12年12月9日日曜日
  • 128. パケットを送る % trema send_packets --source host1 --dest host2 --n_pkts 10 --pps 10 Unknown packet! Unknown packet! Unknown packet! Unknown packet! Unknown packet! ... 12年12月9日日曜日
  • 129. SDN プログラミング分野の1つ とは 「GUIプログラミング」 とかと同じ! 12年12月9日日曜日
  • 130. 仮想ネットワークDSL 開発マシン上に好きなトポロジを構築して コントローラを実行できる • テストパケットを送受信してコントローラを デバッグできる • 使える部品は仮想スイッチ、仮想ホスト、 仮想リンク 12年12月9日日曜日
  • 131. スイッチ10台のフルメッシュ接続を ベタ書き(約80行) vswitch { dpid "0x1" } vswitch { dpid "0x2" } vswitch { dpid "0x3" } vswitch { dpid "0x4" } ... link "0x1", "0x2" link "0x1", "0x3" link "0x1", "0x4" link "0x1", "0x5" link "0x1", "0x6" link "0x1", "0x7" link "0x1", "0x8" link "0x1", "0x9" link "0x1", "0x10" link "0x2", "0x3" link "0x2", "0x4" ... 12年12月9日日曜日
  • 132. 言語内 DSL $nswitch = 10 1.upto( $nswitch ).each do | sw1 | vswitch { dpid sw1.to_hex } 1.upto( $nswitch ).each do | sw2 | if sw1 < sw2 link sw1.to_hex, sw2.to_hex end end end 12年12月9日日曜日
  • 133. OpenFlow/SDN FAQ 「...GUIないの?」 12年12月9日日曜日
  • 137. SDNでTDD • RSpecでネットワークを ユニットテスト 12年12月9日日曜日
  • 138. SDNでTDD • RSpecでネットワークを ユニットテスト • ホスト間でのパケットの送受信数 12年12月9日日曜日
  • 139. SDNでTDD • RSpecでネットワークを ユニットテスト • ホスト間でのパケットの送受信数 • スイッチのフローテーブルの中身 12年12月9日日曜日
  • 140. SDNでTDD • RSpecでネットワークを ユニットテスト • ホスト間でのパケットの送受信数 • スイッチのフローテーブルの中身 • Etc. 12年12月9日日曜日
  • 141. ハブのテストコード describe RepeaterHub do around do | example | network { # ネットワークの定義 vswitch("switch") { datapath_id "0xabc" } vhost("host1") { promisc "on" } 仮想NWで vhost("host2") { promisc "on" } link "switch", "host1" ハブを動かし、 link "switch", "host2" }.run( RepeaterHub ) { example.run } end context "when host1 sends one packet to host2" do describe "switch" do before { send_packets "host1", "host2" } subject { switch( "switch" ) } フローテーブル it { should have( 1 ).flows } its( "flows.first.actions" ) { should == "FLOOD" } の中身をテスト end ... 12年12月9日日曜日
  • 142. まとめ • SDNはプログラミング •やってるとこはやっている (Google、Trema) • Tremaで楽に作ろう 12年12月9日日曜日
  • 143. Amazon で 好評予約中! 12年12月9日日曜日