MidoNetのパケット処理をDVRと比較してみる

2015年10月21日(水)
工藤 雄大
MidoNetでのパケット処理について、DVRとの違いという観点でご紹介します。

これまで2回にわたって、OpenStackでMidoNetを利用するための手順をご紹介しました。今回は、MidoNetでのパケット処理について、皆様が一番気になるであろうDVRとの違いという観点でご紹介します。

仮想ルータはどこにある?

MidoNet利用時のパケット処理を解説する前に、Neutron OVS plug-inを利用する場合とDVRの機能を利用した場合の挙動の差について説明します。ポイントは、仮想ルータの位置とNAT変換の箇所です。なおDVRの挙動の詳細については、以前の連載「OpenStack(RHEL-OSP6)で試す分散仮想ルータ」もご参照ください。

Neutron OVS plug-in利用時の挙動

OpenStackのネットワークは、外部用ネットワーク(External Network)とインスタンス間通信のための内部用ネットワーク(Tenant Network)に分かれます。その仲介をするのが仮想ルータです。Neutron OVS plug-inを標準設定で利用するときは、仮想ルータはNetwork サーバ(Neutron Serverサービスが起動しているサーバ)上に存在します(図1)。

図1:Neutron OVS plug-inを利用する場合、仮想ルータはNetworkサーバ上で稼働している

図1:Neutron OVS plug-inを利用する場合、仮想ルータはNetworkサーバ上で稼働している

別テナント上のインスタンス間通信(East-West通信)が必ず仮想ルータを経由するため、Networkサーバの負荷が高くなる傾向があります(図2の青い矢印)。

またインスタンスと外部ネットワークとの通信(North-South通信)は、必ずNetworkサーバ上の仮想ルータでNAT処理されてパケットが流れます(図2の赤い矢印)。しかし、Networkサーバは、Active-Activeの冗長化構成をとることができないため、システム全体の処理能力はNetworkサーバ単体のハードウェア性能に依存します。

図2:Neutron OVS plug-in利用時の通信

図2:Neutron OVS plug-in利用時の通信

DVR機能利用時の挙動

一方DVRを利用すると、Networkサーバ上の仮想ルータを、Computeサーバ上へも拡張が可能です。これらの仮想ルータは、別々の仮想ルータとして存在し、External Networkのセグメント範囲からそれぞれIP Addressが割り当てられます。(図3)

図3:DVR機能利用時、仮想ルータはComputeサーバ上にも拡張できる

図3:DVR機能利用時、仮想ルータはComputeサーバ上にも拡張できる

East-West通信は、そのインスタンスが動作しているComputeサーバ同士で直接通信します(図4の青い矢印)。これは、分散仮想ルータにより処理されます。

これに対してNorth-South通信は、Floating IP割り当ての有無により処理が変わります。インスタンスにFloating IPを割り当てている場合、インスタンスが動作しているComputeサーバ上の分散仮想ルータでNAT処理されてパケットが流れます(図4の緑の矢印)。一方Floating IPを割り当てていない場合は、Networkサーバ上のSNAT用仮想ルータでNAT処理されてパケットが流れます。これは、先に説明したNeutron OVS plug-in使用時と同じ挙動です(図4の赤い矢印)。

図4:DVR機能利用時の通信

図4:DVR機能利用時の通信

MidoNet利用時の挙動

MidoNetでは、MidoNet Provider Routerという独自の仮想ルータ上に、Tenant用仮想ルータが作成されます。MidoNet Provider Routerは複数のGWサーバ上で単一の仮想ルータとして構成されます。Tenant用仮想ルータも複数のGWサーバ上で透過的に構成されます(図5)。

図5:MidoNet利用時、仮想ルータは複数のGWサーバ上に構成される

図5:MidoNet利用時、仮想ルータは複数のGWサーバ上に構成される

MidoNetのパケット処理の流れ

Neutron OVS plug-in利用時、およびDVR利用時のパケットは、仮想ルータ上で処理されていましたが、MidoNetでは仮想ルータだけでなく、Computeサーバ上のMidoNet Agentもパケット処理を行っています。

この処理については、レッドハットの中井氏による「完全分散エッジ処理で実現するNeutron仮想ネットワーク」で詳細に解説されていますので、それをベースに説明します。以下、注目すべき箇所には、☆の後に解説を入れています。

East-West通信

East-West通信は、Computeサーバ上のMidoNet Agentにより処理されます。

前述の図5において、Tenant210(192.168.210.0/24)に属するComputeサーバ1上のVM210-1(192.168.210.13)から、Tenant220(192.168.220.0/24)に属するComputeサーバ2上のVM220-2(192.168.220.14)への通信フローを例にします。

はじめに、各サーバにおけるMidoNet用ポートの割り当て状況を、以下で確認します。

【ポート番号確認】@Compute1
# mm-dpctl --show-dp midonet
(略)
Port #0 "midonet"  Internal (略)
Port #1 "tngre-overlay"  Gre  (略)
Port #2 "tnvxlan-overlay"  VXLan  (略)☆VXLAN用ポート
Port #3 "tnvxlan-vtep"  VXLan  (略)
Port #4 "tap6e7f5dc6-2c"  NetDev  (略)☆インスタンス用ポート
Port #5 "tap6f15c9ed-c5"  NetDev  (略)☆インスタンス用ポート
Port #6 "tap5c704d80-de"  NetDev  (略)☆インスタンス用ポート

インスタンス用ポートがどのインスタンスに割り当てられているかは、Dashboardからログインし、[プロジェクト]−[ネットワーク]−[ネットワーク]−[(Tenantネットワーク名)]で表示されるポート一覧等から確認してください(図6)。

図6:Dashboard上でポートを確認する

図6:Dashboard上でポートを確認する

次に、各サーバでのフローテーブルを確認します。Computeサーバ1でのフローテーブルは、以下のようになります。

【フローテーブル確認】@Compute 1
# mm-dpctl --dump-dp midonet
(略)
  Flow:
    match keys:☆条件
      Priority{0}
        mask: Priority{0}
      InPort{4}☆ポート4(VM210-1用)から来るパケット
        mask: InPort{-1}
      Ethernet{src=fa:16:3e:8e:35:bb, dst=ac:ca:ba:c3:3a:51}
        mask: Ethernet{src=ff:ff:ff:ff:ff:ff, dst=ff:ff:ff:ff:ff:ff}
      EtherType{0x800}
        mask: EtherType{0xffffffff}
      KeyIPv4{src=192.168.210.13, dst=192.168.220.14, proto=6, tos=16, ttl=64, frag=0}☆VM210-1からVM220-2へのパケット
        mask: KeyIPv4{src=255.255.255.255, dst=255.255.255.255, proto=-1, tos=-1, ttl=-1, frag=-1}
      TCP{src=55194, dst=22}
        mask: TCP{src=65535, dst=65535}
      TCPFlags{'PSH|ACK'}
        mask: TCPFlags{''}
    actions:☆処理
      SetKey{Ethernet{src=ac:ca:ba:7d:43:3d, dst=fa:16:3e:6b:07:bf}}
      SetKey{KeyIPv4{src=192.168.210.13, dst=192.168.220.14, proto=6, tos=16, ttl=63, frag=0}}
      SetKey{Tunnel{tun_id=23, ipv4_src=192.168.20.102, ipv4_dst=192.168.20.103, tun_flag=0, ipv4_tos=0, ipv4_ttl=-1}}☆tunnel id 23でカプセル化し、Compute1からCompute2へ送る
      Output{port=2}☆ポート2(VXLAN用ポート)から送出する
    stats: FlowStats{packets=3, bytes=246}
    tcpFlags: PSH|ACK
    lastUsedTime: 1200121773

上記の強調箇所を読み解くと、Computeサーバ1上のVM210-1(192.168.210.13)からVM220-2(192.168.220.14)宛のパケットが来た場合、tunnel id 23でカプセル化してComputeサーバ1からComputeサーバ2へパケットを送出していることがわかります。

一方、Computeサーバ2でのフローテーブルは、以下のようになります。

【フローテーブル確認】@Compute 2
# mm-dpctl --dump-dp midonet
(略)
  Flow:
    match keys:☆条件
      Priority{0}
        mask: Priority{0}
      Tunnel{tun_id=23, ipv4_src=192.168.20.102, ipv4_dst=192.168.20.103, tun_flag=0, ipv4_tos=0, ipv4_ttl=-1}☆tunnel id 23でカプセル化されて、Compute1からCompute2へ届いたパケット
        mask: Tunnel{tun_id=-1, ipv4_src=255.255.255.255, ipv4_dst=255.255.255.255, tun_flag=0, ipv4_tos=0, ipv4_ttl=0}
      InPort{2}☆ポート2(VXLAN用ポート)からきたパケット
        mask: InPort{-1}
      Ethernet{src=ac:ca:ba:7d:43:3d, dst=fa:16:3e:6b:07:bf}
        mask: Ethernet{src=00:00:00:00:00:00, dst=00:00:00:00:00:00}
      EtherType{0x800}
        mask: EtherType{0x0}
      KeyIPv4{src=192.168.210.13, dst=192.168.220.14, proto=6, tos=16, ttl=63, frag=0}☆VM210-1からVM220-2へのパケット
        mask: KeyIPv4{src=0.0.0.0, dst=0.0.0.0, proto=0, tos=0, ttl=0, frag=0}
      TCP{src=55194, dst=22}
        mask: TCP{src=0, dst=0}
      TCPFlags{'PSH|ACK'}
        mask: TCPFlags{''}
    actions:☆処理
      Output{port=6}☆ポート6(VM220-2)へパケットを送出する
    stats: FlowStats{packets=3, bytes=246}
    tcpFlags: PSH|ACK
    lastUsedTime: 1200119105

上記の強調箇所を読み解くと、VXLAN用ポートを経由し、tunnel id 23でカプセル化されてComputeサーバ1からComputeサーバ2へ届いたパケットで、かつVM210-1(192.168.210.13)からVM220-2(192.168.220.14)宛のパケットは、VM220-2へパケットを送出することがわかります。

以上より、East-West通信では、インスタンスが動作しているサーバ間(この例ではComputeサーバ1とComputeサーバ2)のみで完結することがわかります。

North-South通信

North-South通信は、Computeサーバ上のMidoNet Agentと、GWサーバ上のMidoNet AgentおよびBGP Daemonによって処理されます。前述の図5において、Tenant210(192.168.210.0/24)に属するComputeサーバ1上のVM210-1(192.168.210.13。Floating IPなし)から、Target(10.0.0.1)への通信フローを例にします。

Computeサーバ1でのフローテーブルは以下のようになります。

【フローテーブル確認】@Compute 1
# mm-dpctl --dump-dp midonet
(略)
  Flow:
    match keys: ☆条件
      Priority{0}
        mask: Priority{0}
      InPort{4}☆ ポート4(VM210-1用)から来るパケット
        mask: InPort{-1}
      Ethernet{src=fa:16:3e:8e:35:bb, dst=ac:ca:ba:c3:3a:51}
        mask: Ethernet{src=ff:ff:ff:ff:ff:ff, dst=ff:ff:ff:ff:ff:ff}
      EtherType{0x800}
        mask: EtherType{0xffffffff}
      KeyIPv4{src=192.168.210.13, dst=10.0.0.1, proto=6, tos=0, ttl=64, frag=0}☆VM210-1からTargetへのパケット
        mask: KeyIPv4{src=255.255.255.255, dst=255.255.255.255, proto=-1, tos=-1, ttl=-1, frag=-1}
      TCP{src=57655, dst=22}☆Src port 57655からDst port22へのパケット
        mask: TCP{src=65535, dst=65535}
      TCPFlags{'SYN'}
        mask: TCPFlags{''}
    actions: ☆処理
      SetKey{Ethernet{src=ac:ca:ba:d4:6d:9a, dst=00:0c:29:c2:72:32}}
      SetKey{KeyIPv4{src=10.10.0.10, dst=10.0.0.1, proto=6, tos=0, ttl=62, frag=0}}☆Src IP Addressを仮想ルータのExternal Network用インタフェースのIP Addressへ変換
      SetKey{TCP{src=4623, dst=22}}☆Src portを4623へ変換
      SetKey{Tunnel{tun_id=4, ipv4_src=192.168.20.102, ipv4_dst=192.168.20.107, tun_flag=0, ipv4_tos=0, ipv4_ttl=-1}}
      Output{port=2}☆tunnel id 4でカプセル化し、Compute1からGW1へ送る
    stats: FlowStats{packets=14, bytes=2473}☆ポート2(VXLAN用ポート)から送出する
    tcpFlags: PSH|ACK
    lastUsedTime: 1221653557

上記の強調箇所を読み解くと、Computeサーバ1上のVM210-1(192.168.210.13:57655)からTarget(10.0.0.1:22)宛のパケットは、仮想ルータのExternal Network用インタフェース(10.10.0.10:4623)をSourceとするようなNAT変換をし、tunnel id 4でカプセル化して、Computeサーバ1からGWサーバ1へ送出されていることがわかります。ここでは省略しましたが、GWサーバ2へ向けてのフローも同様に存在します。

一方、GWサーバ1でのMidoNet用ポートの割り当て状況は、以下の通りです。上流ネットワーク用のポートが存在していることが確認できます。

【ポート番号確認】@Compute1
# mm-dpctl --show-dp midonet
(略)
Port #0 "midonet"  Internal  (略)
Port #1 "tngre-overlay"  Gre  (略)
Port #2 "tnvxlan-overlay"  VXLan  (略)☆VXLAN用ポート
Port #3 "tnvxlan-vtep"  VXLan  (略)
Port #4 "eth2"  NetDev  (略)☆上流ネットワーク用ポート
Port #5 "mbgp1"  NetDev  (略)

GWサーバ1でのフローテーブルは、以下のようになります。

【フローテーブル確認】@GW1
# mm-dpctl --dump-dp midonet
(略)
  Flow:
    match keys: ☆条件
      Priority{0}
        mask: Priority{0}
      Tunnel{tun_id=4, ipv4_src=192.168.20.102, ipv4_dst=192.168.20.107, tun_flag=0, ipv4_tos=0, ipv4_ttl=-1}☆tunnel id4でカプセル化されて、Compute1からGW1へ届いたパケット
        mask: Tunnel{tun_id=-1, ipv4_src=255.255.255.255, ipv4_dst=255.255.255.255, tun_flag=0, ipv4_tos=0, ipv4_ttl=0}
      InPort{2}☆ポート2(VXLAN用ポート)からきたパケット
        mask: InPort{-1}
      Ethernet{src=ac:ca:ba:d4:6d:9a, dst=00:0c:29:c2:72:32}
        mask: Ethernet{src=00:00:00:00:00:00, dst=00:00:00:00:00:00}
      EtherType{0x800}
        mask: EtherType{0x0}
      KeyIPv4{src=10.10.0.10, dst=10.0.0.1, proto=6, tos=0, ttl=62, frag=0}☆仮想ルータのExternal Network用インタフェースからTargetへのパケット
        mask: KeyIPv4{src=0.0.0.0, dst=0.0.0.0, proto=0, tos=0, ttl=0, frag=0}
      TCP{src=4623, dst=22}☆Src port4623からDst port22へのパケット
        mask: TCP{src=0, dst=0}
      TCPFlags{'SYN'}
        mask: TCPFlags{''}
    actions:
      Output{port=4}☆ポート4(上流ネットワーク用ポート)から送出する
    stats: FlowStats{packets=14, bytes=2473}
    tcpFlags: PSH|ACK
    lastUsedTime: 776754605

上記の強調箇所を読み解くと、VXLAN用ポートを経由し、tunnel id 4でカプセル化されてComputeサーバ1からGWサーバ1へ届いたパケットで、かつ仮想ルータのExternal Network用インタフェース(10.10.0.10:4623)からTarget(10.0.0.1:22)に宛てたもの(すなわちComputeサーバ1でNAT変換されたパケット)は、上流ネットワーク用のポートから送出されることがわかります。

GWサーバ2でも、同様のフローが存在します。また、インスタンスにFloating IPを割り当てたときは、ポート変換がない(送信元ノード上でFloating IPと1:1NAT変換をする)以外は、同様の処理となります。

つまりNorth-South通信では、インスタンスが動作しているサーバ上でNAT変換され、複数のGWサーバへ振り分けられて転送されます。

MidoNet利用時の通信をまとめると、図7のようになります。

図7:MidoNet利用時の通信

図7:MidoNet利用時の通信

おわりに

本連載では、OpenStack上でMidoNetを利用する際の手順や仕組みについて解説してきました。前回の連載も合わせて、Neutron DVRとMidoNetの違いを理解いただき、設計要件にどちらが適しているかの判断の手助けとなれば幸いです。

本記事執筆にあたり、OSCA™技術分科会メンバーの皆様、日本OpenStackユーザ会の皆様、Blogで情報公開いただいた皆様にご協力をいただきました。特にミドクラジャパン鈴木氏、松尾氏、レッドハット中井氏には技術情報提供・引用で多大なるご協力をいただきました。心より感謝いたします。

  • Linuxは、Linus Torvalds氏の日本およびその他の国における登録商標または商標です。
  • MidoNetは、Midokura SARLの登録商標です。
  • OpenStack®の文字表記とOpenStackのロゴは、米国とその他の国におけるOpenStack Foundationの登録商標/サービスマークまたは商標/サービスマークのいずれかであり,OpenStack Foundationの許諾を得て使用しています。日立製作所は,OpenStack FoundationやOpenStackコミュニティの関連企業ではなく、また支援や出資を受けていません。
  • OSCA™(Open Standard Cloud Association)は、デル株式会社の登録商標です。
  • Red Hat、Red Hat Enterprise Linuxは、米国およびその他の国におけるRed Hat, Inc. の登録商標です。
  • その他、記載の商標やロゴは、各社の商標または登録商標です。

【参考文献】

完全分散エッジ処理で実現するNeutron仮想ネットワーク(アクセス:2015/10)

http://www.slideshare.net/enakai/midonet-technology-internalsv10

MidoNet Documentation(アクセス:2015/10)

http://docs.midonet.org/

MidoNet integration - RDO(アクセス:2015/10)

https://www.rdoproject.org/MidoNet_integration

OpenStackNetworking Plug-in 比較 -OVS と MidoNet-(アクセス:2015/10)

http://www.osca-jp.com/solution.html

第20回 OpenStack勉強会 Neutron Deep Dive - DVR(アクセス:2015/10)

http://www.slideshare.net/ToruMakabe/20-openstack-neutron-deep-dive-dvr

株式会社日立ソリューションズ

技術開発本部 研究開発部 オープンソース技術グループ 技師
新技術、新製品の評価及びソリューション開発に従事。ここ7、8年は仮想化関連技術の先行評価に取り組み、近年はオープンソースのクラウド技術の評価及び技術情報展開を実施している。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています