EVPN in the Data Center を読んだので、 メモを残しておく。 メールアドレスなどを登録するとNVIDIAのページからPDFを 無料でダウンロードできる。 あくまでも調査中の個人的なメモなので間違いも含まれている。

イントロ

Closトポロジで構成されたL3ネットワーク上で、L2を前提とするアプリケーションをどのようにデプロイすれば良いか。 例えば、L2のマルチキャストやブロードキャストを使って死活監視やメンバの検出を実現するようなアプリケーションがこれに該当する。 Ethernet VPN(EVPN)は、この課題に対して、L3ネットワークの上にオーバレイによって仮想的なL2ネットワークを提供することで解決する。 ここで、EVPNのコントロールプレーンにはBorder Gateway Protocol(BGP)が使われる。 EVPNとMultiprotocol Lable Switching(MPLS)の組み合わせで成熟した技術であるが、Virtual Extensibe LAN(VXLAN)への応用ができるようになった。 端的に言うと、EVPNはコントローラベースのVXLANに対する新たなアプローチとみなせる。 EVPNはサービスプロバイダの世界を起源に持つので、データセンタネットワークの世界から見ると、馴染みの薄い用語が多く理解しづらい。 この本では、OSSであるFRRを設定例として使いつつ説明していく。

ネットワーク仮想化

仮想ネットワークにおいては、あるユーザは、まるで別のユーザ(あるいはテナント)が存在しないかのようにネットワークを占有できる。 パケットがどの仮想ネットワークに紐づいているかは、多くの場合、パケットヘッダのVirtual Network Identifier(VNI)によって判断する。 VLANやL3VPN、VXLANはこれに該当する。

VLANはインライン仮想ネットワーク、VXLANはオーバレイ仮想ネットワークであり、後者の方がスケーラビリティや運用のしやすさの面で優れている。 なぜなら、上流のスイッチは仮想ネットワークについてのフォワーディングテーブルを持つ必要がなく、管理すべき状態が少なくてすむため。 さらに、仮想ネットワークの追加・削除に伴う影響は、エッジスイッチだけに限定されるため、短時間でユーザへ提供できる。 オーバレイ仮想ネットワークでは、 トンネルのエンドポイント(カプセル化したり、カプセル化をほどいたりするノード)をNetwork Virtualization Edge(NVE)と呼ぶ。 主なL3のトンネリング技術には、VXLANやGRE (IP Generic Routing Encapsulation)、MPLSがある。 VXLANではエンドポイントをVXLAN Tunnel end Point(VTEP)と呼ぶ。

オーバーレイ仮想ネットワークはさらに2つに分類できる。

  • 1つのエンドポイントが唯一のエンドポイントとのみトンネルを張る。L3VPN+MPLSがこれに該当する。
  • 1つのエンドポイントが複数のエンドポイントとトンネルを張る。Virtual Private LAN Switching(VPLS)がこれに該当する。

パケットがトンネル化されていたとしても、アンダーレイのノードはトンネルヘッダしか見ない。 そのため、すべてのパケットは同一の送信元・送信先をもつとみなされ、同一のパスを通ってしまう。 そこで、VXLANやその他のプロトコルでは、UDPのソースポートを書き換えることによって、5タプルのハッシュ値を変更し、別のパスを通すことができる。

サーバノードでは、NICでのTCPセグメントオフロードやチェックサムオフロードによって、 パケット処理にかかるCPUサイクルを削減できる。 しかし、トンネル化されているときにはこれと相性が悪い。 もちろん、VXLANヘッダを理解するNICも存在するが、この相性問題から、 多くの場合サーバノードではなくネットワークノード側でVXLANのカプセリング操作を行っている。 また、トンネル化はヘッダの追加によって実現するので、MTUサイズに気をつける必要がある。

コントロールプレーンは以下を担当する。

  • パケットの送信先を見て、適切なNVEを見つけ出す。VXLANでは、VNIとMACの組みを見て、NVEのIPアドレスを見つけ出すことに対応する。
  • 全てのNVEに対して、そのNVEに関係する仮想ネットワークの一覧を提供する

スイッチのチップは、各社独自のASICから、マーチャントシリコンへと移り変わっている。 本書の執筆時点では、トンネルヘッダとしてIPv6を使うことは多くの場合難しい。

  • Broadcom Trident2 でVXLANをサポート。Trident2+とTrident3でVXLANのルーティングをサポート
  • Mellanox SpectrumチップはVXLANのブリッジングとルーティングをサポート
  • 他にもCariumやBarefoot NetworksのチップがVXLANのブリッジングとルーティングをサポート

ソフトウェア側について見てみると、LinuxのVXLANサポートは随分前からあり、VRFのサポートは2015年にCumulus Networksによって追加された。 カーネル4.14で stable にサポートしている。

EVPNの構成要素

VPLSがL2VPNの一例としてあったが、flood-and-learnの非効率性がよく知られていて、それを解決するためにEVPNが誕生したという経緯がある。 モダンなデータセンタはClosトポロジで設計されていて、多くの場合ToRあるいはLeafがVTEPを担当する。 FRRでは単一のeBGPセッション内で、アンダーレイとオーバーレイの両方の情報をピアと交換できる。

コンロトールプレーンは以下の情報をやり取りする。

  • やり取りされるネットワークアドレスの識別・認識(AFIやSAFI)
  • そのネットワークアドレスがどの仮想ネットワークに所属するか(RDやRT)
  • どんなカプセリング手法が使われているか

EPVNではAFI/SAFIは"l2pvn/evpn"となる。 仮想ネットワーク間では、IPアドレス・MACアドレスが重複される可能性がある。 言い換えると、IPアドレスやMACアドレスは仮想ネットワーク内でのみユニークである。 ここで、Router Distinguisher(RD)は、仮想ネットワークの区別を担当する。 つまり、RDとIPアドレス(あるいはMACアドレス)の組みで持って、グローバルにユニークである。 (詳細には、RDの一部にVTEPのループバックIPも含まれる)

BGPはパス属性によって付加情報を広報できる。 Route Target(RT)はパス属性の一つ。

BGPはアップデートメッセージでNetwork Layer Reachability Information(NLRI)を送る。 EVPN NLRIは、Router Typeによって分類される。最小でRT2、3、5があれば、NVPNネットワークを構成できる。 FRR 4.0.1 では RT2、3、5をサポートしている。

  • RT2:特定のMACアドレスやIPアドレスへの到達情報を広報
  • RT3:仮想ネットワークのVNIとVTEPの紐付けを広報
  • RT5:仮想L3ネットワークでの集約されたプレフィックスを広報

EPVNのブリッジング

802.1Qのブリッジでは、普通"flood-and-learn"によってMACのフォワーディングテーブルのエントリを集めていく。 つまり、宛先MACアドレスを知らない場合には、想定される全てのポートへとパケットを転送する。 もし、レスポンスがあればそのタイミングでMACフォワーディングテーブルに追記する。

EVPNでは、全ての広報が終わると、全てのNVEが、仮想ネットワークに関連する他の全てのNVEを知っていることになる。 その後、EVPNでも同様の仕組みでもって、MACアドレスを学習する。 さらに学習したMACアドレスはBGPによって広報される。 BUM(Broadcast、Unknown Unicast、Multicast)パケットについては、2種類の選択肢がある。 1つ目は送信側で同一パケットをコピーして送る方法、2つ目はアンダーレイのマルチキャストする方法である。 前者はオーバーレイの帯域を使ってしまうが、アンダーレイを単純にできる。 さらにARP抑制(同一の仮想ネットワークにおいてARPリクエストと結果をキャッシュしておく仕組み)を使うとBUMのトラフィックを削減できる。 後者はProtocol Independent Multicast(PIM)の運用が必要になってしまう(要調査)。

第3のアプローチとして、BUMパケットをドロップさせる方法がある。 自分から全くパケットを出さないサイレントなサーバが存在する場合には、 そのMACアドレスをEVPNから学習できないため疎通できないという問題があるが、これはかなりレアなケース。

あるサーバが別のVTEP配下にマイグレーションされるケースを考えてみる。 このケースでは、そのサーバがGARPを出すことで、MACアドレスを再学習させることができる。 その結果は、BGPのMAC Mobility拡張属性によって広報される。シーケンシャルな番号を持っているので最新がわかる。

あるサーバが2つのVTEP配下に接続されているケースを考えてみる。 ここでは2つのVTEPが同一のIPアドレスを持てば良い(マルチホーム)。

EPVNのルーティング

どうやって2つの異なる仮想L2ネットワーク間をルーティングするかという話。 普通、ルータでは複数のL2ネットワークのルーティングは、SVI(Switched VLAN Interface)が担当する。

EVPN/VXLANでは VTEP がルーティングを担当する。 一つのVTEP(あるいはあるVTEPの集合)がそれを担当する場合を、Centrilizedルーティングと呼ぶ。 一方でファーストホップとなるVTEP全てがそれを担当する場合を、Distributedルーティングと呼ぶ。

さらに、Distributedルーティングは2種類に分かれる。 もし、送信側のVTEPのみがルーティングを担当する場合をAsymmetricルーティング、 送信側と受信側両方のVTEPがルーティングを担当する場合をSynmetricルーティングと呼ぶ。 ほとんどの場合には、Distributed Synmetricルーティングが採用されている。

Distributed Synmetric ルーティングの特徴を見ていく。

  • パケットは送信側と受信側の2つのVTEPで実施される
  • VTEP間を繋ぐ仮想ネットワークのVNIはL3 VNIと呼ばれる

ベンダのサポート状況について見ていく。 Arista、Cisco、CUmulusはSymetricルーティングをサポートし、 Cumulus、JuniperはAsymmerticルーティングをサポートしている。

EVPNの設定と運用

この章はボリュームが大きいので、記事をわけて書こうかと思う。この記事は一旦ここでおわり。

(2021/5/27追記)mininetを使ってEVPN/VXLANの挙動を確認できるサンドボックス環境を作った。Ubuntu20.04環境であれば動作する。このスクリプトの中では、 テナント#100とテナント#200という2つのテナントを作り、それぞれのテナントに2つずつサブネットを割り当てている。 テナントごとにVRFを分けているので、テナント内であれば適切にルーティングされて疎通が取れ、 テナント間は互いのネットワークが見えず疎通を禁止している。

この例では、Spine-Leaf-Serverの3層の構造になっていて、 SpineスイッチとLeafスイッチをAll-to-Allでつないでいる。 また、Leafごとに2台のサーバ(全体で8台)を接続していて、 あるサーバ4台をテナント#100、残りのサーバ4台をテナント#200に割り当てている。

https://github.com/bobuhiro11/mininetlab/blob/main/mininetlab/evpn_vxlan.py