ネットワーク仮想化技術の実践活用(1) 〜LinuxボックスでVxLAN構築編〜
前回まで、OpenFlow簡易ルータの実践活用として、いろいろと実装技術を試してきました。今回からは、少し路線を変更して、ネットワーク仮想化技術に着目したいと思います。
ネットワーク仮想化技術といえば、SDN業界では、VxLANやNVGREなどの新技術が注目されておりますね。ただ、ちょっと前までは、ベンダのプロプライエタリ製品でなければ実践活用が難しい側面がありました。
最近では、OpenvSwitchでVxLANが使用できるようになったみたいなので、さっそく、試してみたいと思います。
◆ネットワーク仮想化環境
通常だと、ネットワーク仮想化環境を試してみる場合には、お手軽にサーバ仮想化環境で、ネットワーク仮想化ソフトウェアを構築してみる方法が一般的だと思いますが、折角なので、もっと、実践的にLinuxボックスでネットワーク仮想化環境を構築したいと思います。
1. ハードウェア構成
DNA940のLinuxボックスに、OpenvSwitchを搭載する形態としました。よって、前回のDNA940を引き続き使用します。
DNA 940 - ネットワーク&コミュニケーション関連 - NEXCOM
ただし、ネットワーク仮想化を実現するためには、オーバレイNWを終端するエッジ機能を有するLinuxボックスが最低2台必要になりますので、もう一台も事前にセットアップしておきました。
◆OpenvSwitchでのVxLAN設定方法
1. OpenvSwitch(2.0.1)のインストール
OpenvSwitchのインストール手順は、前回のブログ記事と同一のため、ここでは記述を割愛します。
OpenFlow簡易ルータの実践活用(3) 〜LinuxボックスでOpenFlowスイッチ構築編〜 - SDN開発エンジニアを目指した活動ブログ
2. その他、Linuxボックスでの環境設定
その他の設定作業は、概ね、こんな感じです。
ここでは、OFS1についてのみ記載しますが、同様の作業をOFS2についても行います。
(1) IPフォワードを有効にする
$ sudo vi /etc/sysctl.conf net.ipv4.ip_forward=1 $ sudo sysctl -p net.ipv4.ip_forward = 1
(2) Linuxネットワークを設定する
$ sudo vi /etc/network/interface ---------- auto eth0 iface eth0 inet static address 192.168.0.1 netmask 255.255.255.0 auto eth1 iface eth1 inet manual up ifconfig $IFACE 0.0.0.0 up up ip link set $IFACE promisc on down ip link set $IFACE promisc off down ifconfig $IFACE down auto eth2 iface eth2 inet static address 172.16.0.1 netmask 255.255.255.0 ----------
(3) OpenvSwitchのVxLAN用の仮想ポートを作成する
$ sudo ovs-vsctl add-port br0 vxlan1 -- set interface vxlan1 type=vxlan options:remote_ip=172.16.0.2 $ sudo ovs-vsctl show 82524775-43a3-4838-90ae-61e2cbd10820 Bridge "br0" Controller "tcp:192.168.0.100:6633" Port "eth1" Interface "eth1" Port "br0" Interface "br0" type: internal Port "vxlan1" Interface "vxlan1" type: vxlan options: {remote_ip="172.16.0.2"} ovs_version: "2.0.1"
3. OpenFlowによるフローエントリ設定
LinuxボックスでのVxLAN設定作業が完了したら、OpenFlowによるフロー制御ルールを設定します。
ここでは、必要最低限のサンプルなので、実用性は度外視しております。
import logging from ryu.base import app_manager from ryu.controller import ofp_event from ryu.controller.handler import CONFIG_DISPATCHER from ryu.controller.handler import set_ev_cls from ryu.ofproto import ofproto_v1_3 LOG = logging.getLogger('SimpleForward') class SimpleForward(app_manager.RyuApp): OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION] def __init__(self, *args, **kwargs): super(SimpleForward, self).__init__(*args, **kwargs) @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER) def switch_features_handler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto datapath.id = msg.datapath_id ofproto_parser = datapath.ofproto_parser set_config = ofproto_parser.OFPSetConfig( datapath, datapath.ofproto.OFPC_FRAG_NORMAL, datapath.ofproto.OFPCML_MAX ) datapath.send_msg(set_config) self.send_flow(datapath) return 0 def send_flow(self, datapath): self.add_flow(datapath, 1, 2) self.add_flow(datapath, 2, 1) def add_flow(self, datapath, inPort, outPort): match = datapath.ofproto_parser.OFPMatch( in_port=inPort ) actions =[datapath.ofproto_parser.OFPActionOutput(outPort, 0)] inst = [datapath.ofproto_parser.OFPInstructionActions( datapath.ofproto.OFPIT_APPLY_ACTIONS, actions)] mod = datapath.ofproto_parser.OFPFlowMod( cookie=0, cookie_mask=0, table_id=0, command=datapath.ofproto.OFPFC_ADD, datapath=datapath, idle_timeout=0, hard_timeout=0, priority=0xff, buffer_id=0xffffffff, out_port=datapath.ofproto.OFPP_ANY, out_group=datapath.ofproto.OFPG_ANY, match=match, instructions=inst) datapath.send_msg(mod)
4. その他、OpenvSwitch上での各種確認
OpenFlowコントローラから設定したフローエントリは、こんな感じで確認できます
$ sudo ovs-ofctl dump-flows br0 --protocols=OpenFlow13 OFPST_FLOW reply (OF1.3) (xid=0x2): cookie=0x0, duration=32.161s, table=0, n_packets=566, n_bytes=181688, priority=255,in_port=1 actions=output:2 cookie=0x0, duration=32.161s, table=0, n_packets=590, n_bytes=62642, priority=255,in_port=2 actions=output:1
OpenFlowポートでの実際のトラフィックカウンタも、こんな感じで確認することが可能です。
$ sudo ovs-ofctl dump-ports br0 --protocols=OpenFlow13 OFPST_PORT reply (OF1.3) (xid=0x2): 3 ports port 1: rx pkts=27727, bytes=73419238, drop=0, errs=0, frame=0, over=0, crc=0 tx pkts=18985, bytes=1927125, drop=0, errs=0, coll=0 duration=2236.049s port 2: rx pkts=17785, bytes=1809954, drop=0, errs=0, frame=0, over=0, crc=0 tx pkts=25827, bytes=72731314, drop=0, errs=0, coll=0 duration=1060.543s port LOCAL: rx pkts=26, bytes=2724, drop=0, errs=0, frame=0, over=0, crc=0 tx pkts=3357, bytes=1168560, drop=0, errs=0, coll=0 duration=2236.104s
OpenFlowポートとVxLAN仮想ポートの対応付けも、こんな感じで確認することが可能です。
$ sudo ovs-ofctl dump-ports-desc br0 --protocols=OpenFlow13 OFPST_PORT_DESC reply (OF1.3) (xid=0x2): 1(eth1): addr:00:10:f3:1d:3d:1d config: 0 state: 0 current: 1GB-FD COPPER AUTO_NEG advertised: 10MB-HD 10MB-FD 100MB-HD 100MB-FD 1GB-FD COPPER AUTO_NEG supported: 10MB-HD 10MB-FD 100MB-HD 100MB-FD 1GB-FD COPPER AUTO_NEG speed: 1000 Mbps now, 1000 Mbps max 2(vxlan1): addr:ea:01:9a:e2:fa:67 config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max LOCAL(br0): addr:00:10:f3:1d:3d:1d config: 0 state: 0 speed: 0 Mbps now, 0 Mbps max
以上で、VxLANの動作環境の準備が整いました。
◆実際、使ってみて ...
ある程度、Webレスポンス性の性能劣化を想定していたのですが、予想外にも、普段のインターネット利用での操作感と、まったく遜色ありませんでした。通常の検索ポータルでのキーワード検索や、YouTubeなども、ストレスを感じることなく利用することができました。本日のプロ野球オープン戦の実況中継ustream配信も、鮮明な映像だったと思います。
いちおう、参考までに、回線速度も計測しておきましたが、結果良好でしたね。
◆終わりに
今回は、ネットワーク仮想化の実践活用として基本的なVxLAN環境構築しました。本来のネットワーク仮想化では、MTU調整などをしっかり設計しておかないとフラグメンテーションの多発によるトラフィック性能劣化が発生するはずなのですが、MTUもデフォルト値のままにも関わらず、データプレーンのパフォーマンス劣化を体感することもなく、良好な結果だったと思います。最近のOpenvSwitchでは、オーバレイなカプセル処理によるパケット転送もカーネルモジュールで動作するようになったため、処理能力は昔と比べても、大幅に改善しているようです。
今後は、実践活用における運用面として、環境構築オートメーション化などの対応について、もっと深堀しておきたいところです。