TECH PLAY

Spine

イベント

該当するコンテンツが見つかりませんでした

マガジン

該当するコンテンツが見つかりませんでした

技術ブログ

Containerlab と Juniper の無償仮想イメージ vJunos を使用し、データセンターネットワーク(NW)の定番アーキテクチャ「Leaf-Spine 構成」をゼロから構築するハンズオン記事です。eBGP による Underlay 構成を皮切りに、EVPN/VXLAN によるテナント L2 拡張、ESI-LAG を用いた冗長化、VRF Route Leaking によるインターネット接続ゲートウェイ模擬まで、クラウド NW の中核技術をひと通り体験できます。ハードウェア不要・無償イメージのみで動く手順と全設定例を掲載しています。 はじめに 前提知識 全体像 構築するトポロジ ポイント 進め方 前提とする環境 vJunos イメージの準備(vrnetlab でコンテナ化) 1. 環境構築 — Containerlab で機器を起動 1.1 トポロジ定義(clos-network.clab.yml) 1.2 デプロイ ✅ 完成状態チェックリスト 2. Underlay の構築 — eBGP で Loopback 同士を疎通させる 2.1 IP アドレス設計 2.2 各ノードの IP / Loopback 設定 2.3 eBGP の設定 ポイント spine1 leaf1-1 2.4 動作確認 ✅ 完成状態チェックリスト 3. Overlay の構築 — EVPN/VXLAN 3.1 アーキテクチャの整理 3.2 C-Plane: iBGP EVPN ピア leaf2-1 rr1 hv1(FRR) 確認 3.3 D-Plane: VXLAN セグメントを作る hv1:Linux Kernel + FRR leaf2-1 bm1 動作確認 3.4 EVPN Multihoming(ESI-LAG)で BM の接続を冗長化 方針 leaf2-1(既存設定の置き換え) leaf2-2(新規) bm1(Linux Bond) 切断試験 ✅ 完成状態チェックリスト(Overlay全体) 4. Border Leaf と Internet Gateway 4.1 leaf3-1(Border Leaf として VTEP 化) 4.2 inet-gw1: 共通の下準備(I/F + ASN) 4.3 inet-gw1: VRF と Route Leaking 4.4 inet-gw1: 外部 ISP との eBGP 4.5 isp1 (外部 ISP 模擬) 4.6 bm1 (Global IP 付与とデフォルトゲートウェイ) 4.7 動作確認 ✅ 完成状態チェックリスト(Border GW) 全体の完成確認 おまけ: ハマったら見るところ(Troubleshooting) Junos 側で何が起きているか覗くコマンド FRR 側 まとめ はじめに こんにちは。NTTドコモビジネスのクラウド、 SDPFクラウド/サーバー (以降、SDPF クラウド)の内製開発に従事している堀岡勇杜と申します。 私が主に担当しているのは、ESI(Elastic Service Infrastructure)という名称の、クラウドのNWオーケストレータの開発です。ESI チームの業務内容については、 こちらの記事 で詳しく紹介しています。 ※ 本記事で出てくるEVPN Multihoming の関連用語であるESI(Ethernet Segment Identifier)とは全くの別物です。 突然ですが、データセンター NW の定番アーキテクチャである Leaf-Spine(CLOS) と、その上で動く EVPN/VXLAN は、クラウド NW の中核技術です。しかし実機やシミュレータがなければ、その挙動を肌で理解するのは大変難しいです。私自身も入社当時(2025年4月)はクラウド NW については完全な初学者だったのですが、この 1 年間で勉強させていただき、その全貌の一端が理解できるようになってきました。本記事を通じて、私が得た知見を共有できましたら幸いです。さまざまな用語が出てきますが、それらを全て解説するのは不可能であるため、気になる点は適宜調べながら進めていただければと思います。 用語解説 Leaf-Spine … サーバーを収容する「Leaf(葉)」スイッチと、Leaf 同士をつなぐ「Spine(背骨)」スイッチの 2 階層でネットワークを組む CLOS の定番設計。どのサーバー間も同じホップ数で通信でき、帯域を横に足しやすいのが特長です。SDPFクラウドでは、Spineのさらに上のSuper Spineが存在しており、3 階層の CLOS になっています。 EVPN/VXLAN … 物理的に離れたサーバー同士を「同じ LAN にいるかのように」つなぐ仮想ネットワーク技術です。EVPN が「誰がどこにいるか」の情報交換(制御プレーン)、VXLAN が実データのトンネル転送(データプレーン)を担います。 本記事では、OSS である Containerlab と Juniper Networks 社の vJunos (無償の仮想ルータ/スイッチイメージ)を使用し、典型的な Leaf-Spine 構成をゼロから組み立てます。最終的には以下を達成します。 eBGP による Underlay の経路交換 iBGP + EVPN Type-2/3 による MAC/IP 学習(C-Plane = 制御プレーン) VXLAN によるテナント(利用者)トラフィックのカプセル化(D-Plane = データプレーン) ESI-LAG による EVPN Multihoming(サーバーの複数スイッチへの冗長接続) Border Leaf + VRF Route Leaking (仮想ルーティングテーブル間の経路共有)によるインターネット接続ゲートウェイ模擬 「SDPFクラウドの SDN コントローラや NW オーケストレータが裏で何をしているのか」をハンズオンで体験し、クラウド NW の裏側を覗いていただける構成になっています。 ⚠️ 本記事は学習用ラボ構成を前提としています 動作させることを優先しているため、本番設計とは異なる選択をしている箇所が多々あります(例: MTU デフォルトのまま、BGP 認証なし、など) 前提知識 本記事の主な対象読者は、 BGP の基本概念(AS・ピアリング・経路広告)を理解している、データセンター NW の Overlay 技術を手を動かして学びたいインフラエンジニアや学生 です。以下の知識があるとスムーズに進められます。 分野 期待するレベルの目安 Linux 操作 コマンドライン操作( ip , ping , tcpdump など)、Network Namespace の概念 TCP/IP 基礎 IP アドレス・サブネットマスク・ルーティングの仕組み、L2(Ethernet)と L3(IP)の違い BGP 基礎 AS(Autonomous System)・ASN・eBGP / iBGP の区別、経路広告・ピアリングの概念 Docker 基礎 docker ps / docker pull などの基本操作、コンテナとイメージの違い 各セクションに設けている「用語解説」や「Q&A」は補足情報です。すでにご存知の方は読み飛ばしてください。 全体像 構築するトポロジ 最終的なゴールは、 物理的に異なるラックに収容された HV1(ハイパーバイザー上の VM)と BM1(ベアメタルサーバー)が同一の L2 ネットワーク上で通信でき、さらにそこからインターネットへ抜けられる 状態を作ることです。これを実現するために、Underlay(物理 IP 転送の土台)→ Overlay(EVPN/VXLAN による L2 延伸)→ Internet GW(VRF Route Leaking による外部接続)の順に積み上げていきます。 主な登場人物は以下の通りです。 ノード 役割 ASN Loopback spine1 Spine #1 64512 10.255.255.1 spine2 Spine #2 64513 10.255.255.2 leaf1-1 Underlay Leaf(HV=ハイパーバイザー収容) 65000 10.255.255.11 leaf2-1 / leaf2-2 Overlay Leaf(BM=ベアメタルサーバー収容、ESI-LAG ペア検証) 65000 10.255.255.21 / .22 leaf3-1 Border Leaf(Internet GW 収容) 65000 10.255.255.31 rr1 Route Reflector(経路情報を集めて他に配る中継役) 65000 10.255.255.101 hv1 ハイパーバイザー模擬(Linux + FRR、VTEP=VXLANトンネルの端点 を持つ) 65000 10.255.255.201 bm1 ベアメタルサーバー模擬(Linux) — — inet-gw1 Internet Gateway 模擬(vJunos-router) 65002 198.51.100.1 isp1 外部 ISP 模擬 65001 192.0.2.1 用語解説 Underlay(アンダーレイ) … 物理スイッチ・ルータが実際に IP パケットを転送する「土台」のネットワーク層です。本記事では Leaf-Spine 間の P2P リンクと eBGP がこれにあたります。 Overlay(オーバーレイ) … Underlay の上に「論理的に重ねた」仮想ネットワーク層です。本記事では VXLAN がデータのカプセル化(D-Plane)、EVPN が経路情報の交換(C-Plane)を担い、テナントの L2 セグメントを物理的に離れたノード間へ延伸します。Underlay が「道路」なら Overlay は「宅配便」のようなイメージです。 ポイント Spine ごとに ASN を分ける (64512 / 64513)。Leaf 側は multipath multiple-as で Spine 2 台への ECMP(Equal-Cost Multi-Path)を有効にしています。この設定により、障害発生時はベストパス再選定なしで残存パスに切り替わります。 Leaf は全て同じ ASN(65000) にして増設コストを下げています。詳細は以下を参照。 RR は Underlay にも参加 しますが、直接データを転送せず Overlay の経路反射(他のノードの経路情報をまとめて再配布する役割)を担当します。 HV 側は FRR で EVPN ピアリングを代用 し、RR と EVPN ピアを張ります(実際のクラウドでは SDN コントローラが HV 上の経路を収集し EVPN に変換します)。 Q. なぜ Leaf を全て同じ ASN にするのか? RFC 7938 は「Leaf ごとに別 ASN」を推奨していますが、本構成では共通 ASN(65000)を採用しました。トレードオフは次の通り。 共通 ASN(本記事) 別 ASN(RFC 7938 推奨) 増設運用 ✅ Leaf テンプレ流用、Spine 側も peer-as 1 つ ❌ Leaf ごとに ASN 採番、Spine 側も増やすたび neighbor 別設定 AS-PATH ループ防止 ❌ as-override で無効化される ✅ そのまま効く トラブルシュート ❌ AS-PATH に Leaf 識別子が出ない ✅ どの Leaf 経由か AS-PATH で分かる 進め方 Containerlab で機器を起動 Underlay(IP / eBGP)構築 Overlay(iBGP EVPN / VXLAN / ESI-LAG)構築 Border Leaf + Internet GW 構築 各セクションの末尾には「動作確認」と「完成状態チェックリスト」を載せています。 前提とする環境 以下を準備してください。 項目 内容 マシンの推奨スペック メモリ 32GB 以上(vJunos は 1 ノードあたり 4GB ほど使います)、ディスク空き容量 20GB 以上 (vJunos の qcow2 は 1 イメージ約 5GB、Docker ビルド後は合計 10GB 超になります) ホスト OS Linux(Ubuntu 24.04 で検証)。Docker が動く環境ならOK Docker v29.2.0 で検証 Containerlab v0.75.0 で検証。 インストール手順 vJunos イメージ vJunos-switch-25.4R1.12 , vJunos-router-25.4R1.12 (手順は以下) ゲスト OS 軽量 Linux nicolaka/netshoot (HV / BM 用)。コンテナ内の FRR は v10.6.1 で検証 エディタ VS Code + Containerlab 拡張があると便利 vJunos イメージの準備(vrnetlab でコンテナ化) vJunos は Juniper が 無償で公開している仮想ルータ/スイッチイメージ です。ただし配布形式は qcow2(KVM 用)なので、Containerlab で使うには vrnetlab で Docker イメージに変換する必要があります。詳細は こちら を参照。 # 1. vrnetlab をクローン git clone https://github.com/srl-labs/vrnetlab && cd vrnetlab/juniper # 2. Juniper 公式サイトからダウンロードした qcow2 を vrnetlab 下に配置 # https://support.juniper.net/support/downloads で vjunos-switch (または vjunos-router) で検索 cp ~/Downloads/vJunos-router-25.4R1.12.qcow2 vjunosrouter/ cp ~/Downloads/vJunos-switch-25.4R1.12.qcow2 vjunosswitch/ # 3. Docker イメージをビルド(それぞれ数分かかる) cd vjunos-switch && make && cd .. cd vjunos-router && make && cd .. # 4. ビルド結果を確認 docker images | grep vjunos # vrnetlab/juniper_vjunos-switch 25.4R1.12 ... # vrnetlab/juniper_vjunos-router 25.4R1.12 ... # HV / BM 用イメージ docker pull nicolaka/netshoot:v0.15 ⚠️ vJunos のライセンスについて vJunos は 評価・検証・学習用途で無償利用可能 です(商用サポートなし)。以下の点に注意してください。 機能制限はほぼありませんが、 commit 時に warning: requires 'bgp' license 等の警告が出ます。 これはライセンスキーを投入していないだけで、BGP 自体は問題なく動作します (本記事の全手順はライセンスなしで完走できます) 本番環境や商用目的での利用には正規ライセンスが必要です。詳しくは Juniper vJunos ページ を参照してください 1. 環境構築 — Containerlab で機器を起動 この章では、下図のように Spine / Leaf / RR / サーバー模擬など全 11 ノードを Containerlab で一括起動し、SSH でログインできる状態を目指します。 1.1 トポロジ定義(clos-network.clab.yml) name : clos-network topology : nodes : # --- SPINE --- spine1 : kind : juniper_vjunosswitch image : vrnetlab/juniper_vjunos-switch:25.4R1.12 spine2 : kind : juniper_vjunosswitch image : vrnetlab/juniper_vjunos-switch:25.4R1.12 # --- LEAF --- leaf1-1 : kind : juniper_vjunosswitch image : vrnetlab/juniper_vjunos-switch:25.4R1.12 leaf2-1 : kind : juniper_vjunosswitch image : vrnetlab/juniper_vjunos-switch:25.4R1.12 leaf2-2 : kind : juniper_vjunosswitch image : vrnetlab/juniper_vjunos-switch:25.4R1.12 leaf3-1 : kind : juniper_vjunosswitch image : vrnetlab/juniper_vjunos-switch:25.4R1.12 # --- Route Reflector --- rr1 : kind : juniper_vjunosrouter image : vrnetlab/juniper_vjunos-router:25.4R1.12 # --- HV / BM 模擬 --- hv1 : kind : linux image : nicolaka/netshoot:v0.15 bm1 : kind : linux image : nicolaka/netshoot:v0.15 # --- Internet Gateway / 外部 ISP 模擬 --- inet-gw1 : kind : juniper_vjunosrouter image : vrnetlab/juniper_vjunos-router:25.4R1.12 isp1 : kind : juniper_vjunosrouter image : vrnetlab/juniper_vjunos-router:25.4R1.12 links : # Spine <-> Leaf - endpoints : [ "spine1:eth1" , "leaf1-1:eth1" ] - endpoints : [ "spine1:eth2" , "leaf2-1:eth1" ] - endpoints : [ "spine1:eth3" , "leaf2-2:eth1" ] - endpoints : [ "spine1:eth4" , "leaf3-1:eth1" ] - endpoints : [ "spine2:eth1" , "leaf1-1:eth2" ] - endpoints : [ "spine2:eth2" , "leaf2-1:eth2" ] - endpoints : [ "spine2:eth3" , "leaf2-2:eth2" ] - endpoints : [ "spine2:eth4" , "leaf3-1:eth2" ] # Spine <-> RR - endpoints : [ "spine1:eth10" , "rr1:eth1" ] - endpoints : [ "spine2:eth10" , "rr1:eth2" ] # Server / GW - endpoints : [ "leaf1-1:eth3" , "hv1:eth1" ] - endpoints : [ "leaf2-1:eth3" , "bm1:eth1" ] - endpoints : [ "leaf2-2:eth3" , "bm1:eth2" ] - endpoints : [ "leaf3-1:eth3" , "inet-gw1:eth1" ] - endpoints : [ "inet-gw1:eth2" , "isp1:eth1" ] 1.2 デプロイ clab deploy -t clos-network.clab.yml # トポロジを Web UI で確認(リモートサーバーの場合はポートフォワード) clab graph -t clos-network.clab.yml # 全部壊してやり直したくなった時は clab destroy -t clos-network.clab.yml ノードへの SSH は ssh admin@clab-clos-network-spine1 (初期パスワードは admin@123 )。なお、Linux コンテナ(hv1 / bm1)は docker exec -it clab-clos-network-hv1 bash のように直接シェルに入る方が確実です。 ContainerlabのVS Code拡張を入れておくと、コンテナをまとめて管理できて便利です。 Spine・Leaf・RR・Inet-GW・ISPにおいて、あらかじめ以下の手順で root パスワードを設定して commit しておきます。これは以降の設定をコミットする上で必須の操作です。admin ユーザーのパスワード変更ではないことに留意。 configure set system root-authentication plain-text-password commit ✅ 完成状態チェックリスト clab deploy がエラーなく完了する docker ps で全 11 ノードが Up になっている ssh admin@clab-clos-network-spine1 でログインできる clab graph の Web UI でトポロジが想定通り表示される ここまでで、冒頭の図で示した全ノードが起動し、各機器へログインできる状態になりました。まだ NW 設定は入っていないので、次のセクションで Underlay から構築していきます。 2. Underlay の構築 — eBGP で Loopback 同士を疎通させる この章では、下図のように各ノードに IP アドレスを振り、Spine-Leaf 間で eBGP を張ることで、全ノードの Loopback 同士が疎通できる状態を目指します。この「下地」が後の Overlay(EVPN/VXLAN)の土台になります。 2.1 IP アドレス設計 P2P リンク(機器同士を 1対1 でつなぐリンク)は /30 (IP 2 個分)、Loopback は /32 (IP 1 個)。Spine 側を .1 、Leaf 側を .2 の規則で設計しています。 リンク Spine 側 Leaf 側 spine1 ↔ leaf1-1 10.1.11.1/30 10.1.11.2/30 spine1 ↔ leaf2-1 10.1.21.1/30 10.1.21.2/30 spine1 ↔ leaf2-2 10.1.22.1/30 10.1.22.2/30 spine1 ↔ leaf3-1 10.1.31.1/30 10.1.31.2/30 spine1 ↔ rr1 10.1.101.1/30 10.1.101.2/30 spine2 ↔ * 10.2.x.1/30 10.2.x.2/30(同様) leaf1-1 ↔ hv1 10.11.201.1/30 10.11.201.2/30 2.2 各ノードの IP / Loopback 設定 代表として spine1, hv1 を掲載します。他のノードも同じパターン(IP のみ差し替え)。 spine1 configure set routing-options router-id 10.255.255.1 set interfaces lo0 unit 0 family inet address 10.255.255.1/32 set interfaces ge-0/0/0 unit 0 family inet address 10.1.11.1/30 set interfaces ge-0/0/1 unit 0 family inet address 10.1.21.1/30 set interfaces ge-0/0/2 unit 0 family inet address 10.1.22.1/30 set interfaces ge-0/0/3 unit 0 family inet address 10.1.31.1/30 set interfaces ge-0/0/9 unit 0 family inet address 10.1.101.1/30 commit spine2 / leaf1-1 / leaf2-1 / leaf2-2 / leaf3-1 / rr1 のコマンドを開く spine2 configure set routing-options router-id 10.255.255.2 set interfaces lo0 unit 0 family inet address 10.255.255.2/32 set interfaces ge-0/0/0 unit 0 family inet address 10.2.11.1/30 set interfaces ge-0/0/1 unit 0 family inet address 10.2.21.1/30 set interfaces ge-0/0/2 unit 0 family inet address 10.2.22.1/30 set interfaces ge-0/0/3 unit 0 family inet address 10.2.31.1/30 set interfaces ge-0/0/9 unit 0 family inet address 10.2.101.1/30 commit leaf1-1 configure set routing-options router-id 10.255.255.11 set interfaces lo0 unit 0 family inet address 10.255.255.11/32 set interfaces ge-0/0/0 unit 0 family inet address 10.1.11.2/30 set interfaces ge-0/0/1 unit 0 family inet address 10.2.11.2/30 set interfaces ge-0/0/2 unit 0 family inet address 10.11.201.1/30 commit leaf2-1 configure set routing-options router-id 10.255.255.21 set interfaces lo0 unit 0 family inet address 10.255.255.21/32 set interfaces ge-0/0/0 unit 0 family inet address 10.1.21.2/30 set interfaces ge-0/0/1 unit 0 family inet address 10.2.21.2/30 commit leaf2-2 configure set routing-options router-id 10.255.255.22 set interfaces lo0 unit 0 family inet address 10.255.255.22/32 set interfaces ge-0/0/0 unit 0 family inet address 10.1.22.2/30 set interfaces ge-0/0/1 unit 0 family inet address 10.2.22.2/30 commit leaf3-1 configure set routing-options router-id 10.255.255.31 set interfaces lo0 unit 0 family inet address 10.255.255.31/32 set interfaces ge-0/0/0 unit 0 family inet address 10.1.31.2/30 set interfaces ge-0/0/1 unit 0 family inet address 10.2.31.2/30 commit rr1 configure set routing-options router-id 10.255.255.101 set interfaces lo0 unit 0 family inet address 10.255.255.101/32 set interfaces ge-0/0/0 unit 0 family inet address 10.1.101.2/30 set interfaces ge-0/0/1 unit 0 family inet address 10.2.101.2/30 commit hv1 (Linux なので別物) # FRR のインストール apk add frr sed -i 's/bgpd=no/bgpd=yes/' /etc/frr/daemons /usr/lib/frr/frrinit.sh start # IP 設定 ip addr add 10.255.255.201/32 dev lo ip addr add 10.11.201.2/30 dev eth1 ip link set eth1 up ip route del default ip route add default via 10.11.201.1 ⚠️ ip route del default を実行すると management NW 経由の SSH が切れます。以降 hv1 への操作は docker exec -it clab-clos-network-hv1 bash で入ってください。 直結リンクで ping が通れば OK です。 2.3 eBGP の設定 Underlay の目標は「全ノードの Loopback 同士を疎通させること」。これができれば、あとで Overlay (EVPN/VXLAN)がその「下地」の上に乗れます。Spine と Leaf で eBGP(異なる ASN 同士の BGP)を張り、Loopback 経路を広告します。 ポイント Spine ごとに ASN を分ける : spine1=64512 , spine2=64513 Spine 側に as-override :Leaf 共通 ASN 方式の代償として、BGP の「AS-PATH(経路が通ってきた ASN の履歴)に同じ ASN があるとループとみなして破棄する」ルールを回避するため、Spine 側で AS-PATH 上の Leaf ASN を Spine 自身の ASN に書き換えます Leaf 側に multipath multiple-as :spine1/spine2 の ASN が異なるため、両方を ECMP として使うために必須 ECMP 有効化 : load-balance per-packet という名前ですがこれは Junos のレガシーな仕様で、実態は 5-tuple(送信元/宛先 IP・ポート・プロトコル)のハッシュによるフロー単位の負荷分散 です 広告経路は Loopback のみ : from interface lo0.0 で Loopback に絞ることで、リンク IP が広告されず経路がスッキリします commit 時に以下の警告が出ますが、無視して OK です(詳しくは「前提とする環境」のライセンス注記を参照)。 warning: requires 'bgp' license commit complete spine1 configure # ECMP 有効化 set policy-options policy-statement PFE-LB term 1 then load-balance per-packet set routing-options forwarding-table export PFE-LB # 経路広告ポリシー(Loopback + BGP 経路) set policy-options policy-statement EXPORT-UNDERLAY term ALLOW-BGP from protocol bgp set policy-options policy-statement EXPORT-UNDERLAY term ALLOW-BGP then accept set policy-options policy-statement EXPORT-UNDERLAY term ALLOW-DIRECT from interface lo0.0 set policy-options policy-statement EXPORT-UNDERLAY term ALLOW-DIRECT then accept # BGP(ASN 64512) set routing-options autonomous-system 64512 set protocols bgp group UNDERLAY type external set protocols bgp group UNDERLAY multipath set protocols bgp group UNDERLAY export EXPORT-UNDERLAY set protocols bgp group UNDERLAY peer-as 65000 set protocols bgp group UNDERLAY as-override # 各 Leaf / RR への neighbor set protocols bgp group UNDERLAY neighbor 10.1.11.2 set protocols bgp group UNDERLAY neighbor 10.1.21.2 set protocols bgp group UNDERLAY neighbor 10.1.22.2 set protocols bgp group UNDERLAY neighbor 10.1.31.2 set protocols bgp group UNDERLAY neighbor 10.1.101.2 commit spine2 のコマンドを開く configure set policy-options policy-statement PFE-LB term 1 then load-balance per-packet set routing-options forwarding-table export PFE-LB set policy-options policy-statement EXPORT-UNDERLAY term ALLOW-BGP from protocol bgp set policy-options policy-statement EXPORT-UNDERLAY term ALLOW-BGP then accept set policy-options policy-statement EXPORT-UNDERLAY term ALLOW-DIRECT from interface lo0.0 set policy-options policy-statement EXPORT-UNDERLAY term ALLOW-DIRECT then accept # BGP(ASN 64513) set routing-options autonomous-system 64513 set protocols bgp group UNDERLAY type external set protocols bgp group UNDERLAY multipath set protocols bgp group UNDERLAY export EXPORT-UNDERLAY set protocols bgp group UNDERLAY peer-as 65000 set protocols bgp group UNDERLAY as-override set protocols bgp group UNDERLAY neighbor 10.2.11.2 set protocols bgp group UNDERLAY neighbor 10.2.21.2 set protocols bgp group UNDERLAY neighbor 10.2.22.2 set protocols bgp group UNDERLAY neighbor 10.2.31.2 set protocols bgp group UNDERLAY neighbor 10.2.101.2 commit leaf1-1 leaf1-1 は HV1(FRR)が直接 BGP を喋らないため、HV1 Loopback 宛の static route を広告に含めます。 configure # ECMP set policy-options policy-statement PFE-LB term 1 then load-balance per-packet set routing-options forwarding-table export PFE-LB # Loopback + static を広告 set policy-options policy-statement EXPORT-UNDERLAY term ALL-DIRECT from interface lo0.0 set policy-options policy-statement EXPORT-UNDERLAY term ALL-DIRECT then accept set policy-options policy-statement EXPORT-UNDERLAY term ALL-STATIC from protocol static set policy-options policy-statement EXPORT-UNDERLAY term ALL-STATIC then accept # BGP(multiple-as は必須) set routing-options autonomous-system 65000 set protocols bgp group UNDERLAY type external set protocols bgp group UNDERLAY multipath multiple-as set protocols bgp group UNDERLAY export EXPORT-UNDERLAY set protocols bgp group UNDERLAY neighbor 10.1.11.1 peer-as 64512 set protocols bgp group UNDERLAY neighbor 10.2.11.1 peer-as 64513 # HV1 Loopback への static route set routing-options static route 10.255.255.201/32 next-hop 10.11.201.2 commit leaf2-1 / leaf2-2 / leaf3-1 / rr1 のコマンドを開く leaf2-1 configure set policy-options policy-statement PFE-LB term 1 then load-balance per-packet set routing-options forwarding-table export PFE-LB set policy-options policy-statement EXPORT-UNDERLAY term ALL-DIRECT from interface lo0.0 set policy-options policy-statement EXPORT-UNDERLAY term ALL-DIRECT then accept set routing-options autonomous-system 65000 set protocols bgp group UNDERLAY type external set protocols bgp group UNDERLAY multipath multiple-as set protocols bgp group UNDERLAY export EXPORT-UNDERLAY set protocols bgp group UNDERLAY neighbor 10.1.21.1 peer-as 64512 set protocols bgp group UNDERLAY neighbor 10.2.21.1 peer-as 64513 commit leaf2-2 configure set policy-options policy-statement PFE-LB term 1 then load-balance per-packet set routing-options forwarding-table export PFE-LB set policy-options policy-statement EXPORT-UNDERLAY term ALL-DIRECT from interface lo0.0 set policy-options policy-statement EXPORT-UNDERLAY term ALL-DIRECT then accept set routing-options autonomous-system 65000 set protocols bgp group UNDERLAY type external set protocols bgp group UNDERLAY multipath multiple-as set protocols bgp group UNDERLAY export EXPORT-UNDERLAY set protocols bgp group UNDERLAY neighbor 10.1.22.1 peer-as 64512 set protocols bgp group UNDERLAY neighbor 10.2.22.1 peer-as 64513 commit leaf3-1 configure set policy-options policy-statement PFE-LB term 1 then load-balance per-packet set routing-options forwarding-table export PFE-LB set policy-options policy-statement EXPORT-UNDERLAY term ALL-DIRECT from interface lo0.0 set policy-options policy-statement EXPORT-UNDERLAY term ALL-DIRECT then accept set routing-options autonomous-system 65000 set protocols bgp group UNDERLAY type external set protocols bgp group UNDERLAY multipath multiple-as set protocols bgp group UNDERLAY export EXPORT-UNDERLAY set protocols bgp group UNDERLAY neighbor 10.1.31.1 peer-as 64512 set protocols bgp group UNDERLAY neighbor 10.2.31.1 peer-as 64513 commit rr1 configure set policy-options policy-statement PFE-LB term 1 then load-balance per-packet set routing-options forwarding-table export PFE-LB set policy-options policy-statement EXPORT-UNDERLAY term ALL-DIRECT from interface lo0.0 set policy-options policy-statement EXPORT-UNDERLAY term ALL-DIRECT then accept set routing-options autonomous-system 65000 set protocols bgp group UNDERLAY type external set protocols bgp group UNDERLAY multipath multiple-as set protocols bgp group UNDERLAY export EXPORT-UNDERLAY set protocols bgp group UNDERLAY neighbor 10.1.101.1 peer-as 64512 set protocols bgp group UNDERLAY neighbor 10.2.101.1 peer-as 64513 commit 2.4 動作確認 admin@spine1# run show bgp summary ... Peer AS InPkt OutPkt ... State|#Active/Received/Accepted/Damped... 10.1.11.2 65000 6 8 ... 58 Establ 10.1.21.2 65000 5 7 ... 33 Establ 10.1.22.2 65000 4 7 ... 22 Establ 10.1.31.2 65000 4 7 ... 13 Establ 10.1.101.2 65000 4 7 ... 6 Establ Spine から各 Leaf / RR とのピアが Establ (Established) になっていれば OK です。最終的に Border Leaf (leaf3-1) から HV1 の Loopback まで疎通できます。 admin@leaf3-1# run ping 10.255.255.201 source 10.255.255.31 count 3 64 bytes from 10.255.255.201: icmp_seq=0 ttl=62 time=3.254 ms ... 3 packets transmitted, 3 packets received, 0% packet loss ✅ 完成状態チェックリスト Spine から見て、全 Leaf / RR の eBGP セッションが Establ show route 10.255.255.0/24 で全ノードの Loopback が学習されている 任意の Leaf から任意の Leaf の Loopback へ ping が通る HV1 の Loopback ( 10.255.255.201/32 ) が leaf3-1 から見える ここまでで Underlay が完成し、全ノードの Loopback 同士が IP で疎通できる「下地」が整いました。次のセクションで、この上に EVPN/VXLAN の Overlay を被せます。 3. Overlay の構築 — EVPN/VXLAN ここからが核心です。Underlay の上に EVPN(C-Plane) + VXLAN(D-Plane) を被せ、テナントの L2 セグメントを複数 Leaf 間で拡張します。 Q. なぜ VLAN ではダメなのか? データセンターでは複数のテナント(利用者)が同じ物理スイッチを共有します。テナント同士のトラフィックを分離する最も基本的な手段が VLAN (Virtual LAN)です。しかし VLAN には以下の限界があります。 課題 VLAN の限界 EVPN/VXLAN での解決 ID 数 最大 4,094 個 → 大規模クラウドでは枯渇する VNI は最大約 1,600 万個(VNIについては後述) L2 の拡張 VLAN をラック間に伸ばすにはループ対策(STP)が必要になり、構成が複雑化する VXLAN で L3(IP Underlay)上にトンネルを張るため、STP 不要で任意のラック間へ L2 を延伸可能 MAC 学習のスケーラビリティ データプレーンのフラッディングで MAC を学習するため、規模拡大に伴い帯域を圧迫する EVPN が制御プレーンで MAC/IP を配布するため、不要なフラッディングを抑制できる つまり VLAN は「1 台のスイッチ内 or 隣接スイッチ間」の L2 分離 、 VXLAN は「DC 全体規模」の L2 分離 と役割が違います。本記事で構築するのは後者です。 テナントごとに L3(ルーティング)も分離 したい場合は VRF (Virtual Routing and Forwarding)を使います。VRF はスイッチ / ルータの中に「テナント専用の経路表」を作る技術で、テナント A とテナント B が同じ 192.168.1.0/24 を使っていてもルーティングが混ざりません。本記事のセクション 4 で VRF を使った外部接続を構築します。 3.1 アーキテクチャの整理 各ノードが Overlay において担う役割を整理します。 役割 C-Plane D-Plane Spine (単なる中継) (単なる IP 転送) RR (rr1) iBGP RR、EVPN 経路反射 — Underlay Leaf (leaf1-1) 参加しない 参加しない Overlay Leaf (leaf2-1/2-2/3-1) iBGP/EVPN ピア VTEP(VXLAN トンネルの出入口) HV1 (FRR) iBGP/EVPN ピア VTEP Q. なぜ leaf1-1 は EVPN に参加しないのか? HV1 が VTEP を持つので、leaf1-1 は単なる IP ルータとして VXLAN パケットを Underlay 越しに転送するだけで済みます。実環境でも同様で、HV 上のソフトウェア VTEP(Contrail vRouter 等)が VTEP の役割を担います。本記事ではそれを FRR で代用しています。 3.2 C-Plane: iBGP EVPN ピア leaf2-1 configure # RR との iBGP(Overlay) set protocols bgp group OVERLAY type internal set protocols bgp group OVERLAY local-address 10.255.255.21 set protocols bgp group OVERLAY neighbor 10.255.255.101 set protocols bgp group OVERLAY family evpn signaling # EVPN/VXLAN 基本設定 set switch-options vtep-source-interface lo0.0 set switch-options route-distinguisher 10.255.255.21:1 set protocols evpn encapsulation vxlan # IRB(L3 ゲートウェイ)を使わない宣言。Type-2 ルートに default-gateway コミュニティを付けない set protocols evpn default-gateway no-gateway-community set protocols evpn extended-vni-list all # RT を明示指定。FRR の advertise-all-vni は AS:VNI 形式(65000:10010)で RT を生成するため、 # Junos 側も同じ値を使う(Junos の vrf-target auto は AS:(VNI+0x10000000) と計算式が異なり互換性がない) set switch-options vrf-target target:65000:10010 commit leaf2-2 / leaf3-1 のコマンドを開く leaf2-2 configure set protocols bgp group OVERLAY type internal set protocols bgp group OVERLAY local-address 10.255.255.22 set protocols bgp group OVERLAY neighbor 10.255.255.101 set protocols bgp group OVERLAY family evpn signaling set switch-options vtep-source-interface lo0.0 set switch-options route-distinguisher 10.255.255.22:1 set protocols evpn encapsulation vxlan set protocols evpn default-gateway no-gateway-community set protocols evpn extended-vni-list all set switch-options vrf-target target:65000:10010 commit leaf3-1 configure set protocols bgp group OVERLAY type internal set protocols bgp group OVERLAY local-address 10.255.255.31 set protocols bgp group OVERLAY neighbor 10.255.255.101 set protocols bgp group OVERLAY family evpn signaling set switch-options vtep-source-interface lo0.0 set switch-options route-distinguisher 10.255.255.31:1 set protocols evpn encapsulation vxlan set protocols evpn default-gateway no-gateway-community set protocols evpn extended-vni-list all set switch-options vrf-target target:65000:10010 commit rr1 configure set protocols bgp group OVERLAY type internal set protocols bgp group OVERLAY cluster 10.255.255.101 set protocols bgp group OVERLAY local-address 10.255.255.101 set protocols bgp group OVERLAY neighbor 10.255.255.21 set protocols bgp group OVERLAY neighbor 10.255.255.22 set protocols bgp group OVERLAY neighbor 10.255.255.31 set protocols bgp group OVERLAY neighbor 10.255.255.201 set protocols bgp group OVERLAY family evpn signaling commit hv1(FRR) vtysh configure terminal router bgp 65000 bgp router-id 10.255.255.201 no bgp ebgp-requires-policy neighbor 10.255.255.101 remote-as 65000 neighbor 10.255.255.101 update-source 10.255.255.201 address-family l2vpn evpn neighbor 10.255.255.101 activate exit-address-family exit end write exit 確認 admin@rr1# run show bgp summary group OVERLAY ... 10.255.255.21 65000 ... Establ bgp.evpn.0: 0/0/0/0 10.255.255.22 65000 ... Establ bgp.evpn.0: 0/0/0/0 10.255.255.31 65000 ... Establ bgp.evpn.0: 0/0/0/0 10.255.255.201 65000 ... Establ bgp.evpn.0: 0/0/0/0 全ピアが Establ (Established) になれば完成です。まだ VNI を作っていないので EVPN 経路は 0 件です。 3.3 D-Plane: VXLAN セグメントを作る VNI 10010 (VLAN 10)を用意し、 VM1(HV1 上、192.168.10.10) と BM1(leaf2-1 配下、192.168.10.101) が同じ L2(同一サブネット、つまり「同じ LAN」)で通信できるようにします。 Q. VNI とは? VXLAN Network Identifier の略。VLAN ID の「拡張版」のようなもので、最大約 1,600 万のセグメントを作れます(VLAN は 4,094 まで)。 ⚠️ 本番では MTU 設計が必須 VXLAN は外側に IP(20) + UDP(8) + VXLAN(8) + Inner Ethernet(14) = 50 バイトのオーバーヘッド が乗ります。テナントが MTU 1500 で通信したいなら、Underlay の物理 MTU を 9000(Jumbo Frame) にするのが定番です。 hv1:Linux Kernel + FRR # VM 模擬の Network Namespace 作成 ip netns add vm1 ip link add veth-host type veth peer name veth-vm ip link set veth-vm netns vm1 ip netns exec vm1 ip link set dev veth-vm address 02:00:00:00:01:10 ip netns exec vm1 ip addr add 192.168.10.10/24 dev veth-vm ip netns exec vm1 ip link set veth-vm up ip netns exec vm1 ip link set lo up # VTEP(VXLAN I/F)作成 ip link add vxlan10 type vxlan id 10010 local 10.255.255.201 dstport 4789 nolearning # Bridge 経由で VM 側と VXLAN を接続 ip link add br10 type bridge ip link set veth-host master br10 ip link set vxlan10 master br10 ip link set vxlan10 up ip link set veth-host up ip link set br10 up vtysh configure terminal router bgp 65000 address-family l2vpn evpn advertise-all-vni exit-address-family end write exit leaf2-1 configure set vlans v10 vlan-id 10 set vlans v10 vxlan vni 10010 set vlans v10 vxlan ingress-node-replication # BM1 接続ポート set interfaces ge-0/0/2 unit 0 family ethernet-switching interface-mode trunk set interfaces ge-0/0/2 unit 0 family ethernet-switching vlan members v10 commit Q. ingress-node-replication とは? SDPF クラウドでは、お客さまに自由な L2 ネットワークを構成していただけるよう、Overlay ネットワークになるべく制限を与えない形でサービスを提供します。そのため、BUM(Broadcast / Unknown unicast / Multicast)トラフィックも通す必要があります。 ingress-node-replication は、この BUM パケットをフラッドする際の方式を指定する設定です。これを有効にすると、Type-3(IM)ルートで学習した各リモート VTEP に対して ユニキャストで複製送信 します。 bm1 ip link set eth1 up ip link add link eth1 name eth1.10 type vlan id 10 ip link set eth1.10 up ip addr add 192.168.10.101/24 dev eth1.10 動作確認 VM1 ↔ BM1 で ping が通り、HV1 で tcpdump を取ると UDP/4789 の VXLAN にカプセル化 されているのが分かります。 # BM1で実行 ~ # ping 192.168.10.10 64 bytes from 192.168.10.10: icmp_seq=1 ttl=64 time=3.35 ms ... # HV1で実行 ~ # tcpdump -i eth1 -n -vv udp port 4789 tcpdump: listening on eth1, link-type EN10MB (Ethernet), snapshot length 262144 bytes ... IP (tos 0x0, ttl 253, id 21304, offset 0, flags [none], proto UDP (17), length 134) 10.255.255.21.55534 > 10.255.255.201.4789: [no cksum] VXLAN, flags [I] (0x08), vni 10010 IP (tos 0x0, ttl 64, id 44875, offset 0, flags [DF], proto ICMP (1), length 84) 192.168.10.101 > 192.168.10.10: ICMP echo request, id 102, seq 8, length 64 ... IP (tos 0x0, ttl 64, id 21000, offset 0, flags [none], proto UDP (17), length 134) 10.255.255.201.49139 > 10.255.255.21.4789: [udp sum ok] VXLAN, flags [I] (0x08), vni 10010 IP (tos 0x0, ttl 64, id 6907, offset 0, flags [none], proto ICMP (1), length 84) 192.168.10.10 > 192.168.10.101: ICMP echo reply, id 102, seq 8, length 64 leaf2-1 側でも EVPN Type-2(MAC/IP)と Type-3(IM)の経路がリモート VTEP 宛に学習されています。 admin@leaf2-1# run show route table bgp.evpn.0 bgp.evpn.0: 5 destinations, 5 routes (5 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 2:10.255.255.21:1::10010::aa:c1:ab:0a:18:4a/304 MAC/IP *[EVPN/170] 00:01:12 Indirect 2:10.255.255.201:2::0::02:00:00:00:01:10/304 MAC/IP *[BGP/170] 00:03:21, localpref 100, from 10.255.255.101 AS path: I, validation-state: unverified to 10.1.21.1 via ge-0/0/0.0 > to 10.2.21.1 via ge-0/0/1.0 2:10.255.255.21:1::10010::aa:c1:ab:0a:18:4a::192.168.10.101/304 MAC/IP *[EVPN/170] 00:01:05 Indirect 3:10.255.255.21:1::10010::10.255.255.21/248 IM *[EVPN/170] 00:03:09 Indirect 3:10.255.255.201:2::0::10.255.255.201/248 IM *[BGP/170] 00:03:10, localpref 100, from 10.255.255.101 AS path: I, validation-state: unverified > to 10.1.21.1 via ge-0/0/0.0 to 10.2.21.1 via ge-0/0/1.0 確認のポイントを整理します。 [EVPN/170] Indirect のエントリ(RD 10.255.255.21:1 )は leaf2-1 自身がローカルで生成した EVPN 経路(自分のポートに接続された BM1 の MAC/IP、および自分が属する VNI の IM ルート)。 [BGP/170] from 10.255.255.101 のエントリ(RD 10.255.255.201:2 )は RR(rr1)経由で受け取ったリモート VTEP(HV1)からの経路。 to 10.1.21.1 / to 10.2.21.1 の 2 経路が並んでいるのは、spine1・spine2 の両方を経由した ECMP が有効になっているためです。 EVPN の経路情報は BGP によって制御プレーン上でやり取りされ、実際のパケット転送は VXLAN(UDP/4789)がデータプレーンとして担います。tcpdump で確認した通り、 vni 10010 のカプセル化で転送されていることが確認できます。 3.4 EVPN Multihoming(ESI-LAG)で BM の接続を冗長化 セクション 3.3 で VXLAN の疎通は確認できましたが、このままでは BM1 が leaf2-1 の 1 本だけでぶら下がっている状態です。クラウドサービスでは物理故障の単一障害点を排除することが基本要件であり、リンクやスイッチの障害でサーバーが孤立しないよう、複数 Leaf へ冗長接続します。 ここからは BM1 を leaf2-1 / leaf2-2 の両方に接続して冗長化します。BM1 のネットワーク設定をいったん削除して bond に組み直すため、一時的に BM1 ↔ VM1 間の通信が途絶えます。 EVPN Type-1 / Type-4 を活かす ESI-LAG(All-Active) で構成します。 EVPN Multihoming の商用導入事例として、SDPF クラウド開発メンバーが JANOG48 で発表した EVPN Anycast Gateway を商用導入した話 も大変参考になります。 Q. ESI-LAG とは? 通常の LAG(Link Aggregation)は 1 台のスイッチへの束ねですが、ESI-LAG は 複数台のスイッチをまたいで LAG を組める技術です。サーバーから見ると 1 台のスイッチにつないでいるように見えます。 方針 2 台の Leaf で 同じ ESI と 同じ LACP System ID を設定 → BM1 から見ると単一の LAG 相手に見える BM1 側は Linux bond(mode=802.3ad) leaf2-1(既存設定の置き換え) configure delete interfaces ge-0/0/2 unit 0 set chassis aggregated-devices ethernet device-count 1 set interfaces ge-0/0/2 ether-options 802.3ad ae0 set interfaces ae0 unit 0 family ethernet-switching interface-mode trunk set interfaces ae0 unit 0 family ethernet-switching vlan members v10 # ESI(leaf2-1/2-2 で完全一致させる) set interfaces ae0 esi 00:00:00:00:00:00:00:00:00:01 set interfaces ae0 esi all-active set interfaces ae0 aggregated-ether-options lacp active set interfaces ae0 aggregated-ether-options lacp periodic fast set interfaces ae0 aggregated-ether-options lacp system-id 00:00:00:00:00:01 commit leaf2-2(新規) leaf2-1 と完全に同じ ESI / LACP System ID を投入します。VLAN/VNI/RT もここで作成。 configure set vlans v10 vlan-id 10 set vlans v10 vxlan vni 10010 set vlans v10 vxlan ingress-node-replication set chassis aggregated-devices ethernet device-count 1 set interfaces ge-0/0/2 ether-options 802.3ad ae0 set interfaces ae0 unit 0 family ethernet-switching interface-mode trunk set interfaces ae0 unit 0 family ethernet-switching vlan members v10 set interfaces ae0 esi 00:00:00:00:00:00:00:00:00:01 set interfaces ae0 esi all-active set interfaces ae0 aggregated-ether-options lacp active set interfaces ae0 aggregated-ether-options lacp periodic fast set interfaces ae0 aggregated-ether-options lacp system-id 00:00:00:00:00:01 commit bm1(Linux Bond) ip addr flush dev eth1.10 ip link del eth1.10 ip link add bond0 type bond mode 802.3ad miimon 100 lacp_rate 1 xmit_hash_policy layer3+4 ip link set eth1 down ip link set eth2 down ip link set eth1 master bond0 ip link set eth2 master bond0 ip link set bond0 up ip link set eth1 up ip link set eth2 up ip link add link bond0 name bond0.10 type vlan id 10 ip link set bond0.10 up ip addr add 192.168.10.101/24 dev bond0.10 切断試験 BM1 から VM1 に ping を流したまま、leaf2-1 → leaf2-2 の順にリンクを落とすと、片方が生きている間は ping が継続することを確認できます。 # leaf2-1 で接続断 → ping 継続 configure set interfaces ge-0/0/2 disable commit # leaf2-2 でも接続断 → ping 停止 configure set interfaces ge-0/0/2 disable commit # leaf2-1 を復活 → ping 復活 configure delete interfaces ge-0/0/2 disable commit # leaf2-2 で実行 configure delete interfaces ge-0/0/2 disable commit HV1 から見ると、BM1 の bond0 MAC が leaf2-1 / leaf2-2 の両方から同じ ESI で広告 されています。 ~ # vtysh -c "show bgp l2vpn evpn" Route Distinguisher: 10.255.255.21:1 *>i [2]:[10010]:[48]:[xx:xx:xx:xx:xx:xx] ← bond0 の MAC 10.255.255.21 ESI:00:00:00:00:00:00:00:00:00:01 RT:65000:10010 Route Distinguisher: 10.255.255.22:1 *>i [2]:[10010]:[48]:[xx:xx:xx:xx:xx:xx] 10.255.255.22 ESI:00:00:00:00:00:00:00:00:00:01 RT:65000:10010 💡 bond0 の MAC はカーネルが自動付与します(通常 eth1 の MAC を継承)。実際の値は ip link show bond0 で確認してください。 ESI が両ノードで一致しているため、HV1 はこの 2 経路を Aliasing (ECMP 的にロードバランス)して扱います。つまり、「leaf2-1 および leaf2-2 のいずれを経由しても、BM1 に届く」状態が完成しています。これが ESI-LAG の本質です。 ✅ 完成状態チェックリスト(Overlay全体) RR の OVERLAY グループで全 Leaf / HV1 が Establ HV1 で show evpn vni に VNI 10010 が表示される BM1 → VM1(VXLAN 経由)の ping が通る HV1 の tcpdump -i eth1 udp port 4789 で VXLAN ヘッダ(vni 10010)が見える leaf2-1/2-2 のどちらかのリンクを落としても BM1 → VM1 の通信が継続する show bgp l2vpn evpn で BM1 の MAC が leaf2-1/2-2 の両方から同じ ESI で広告されている ここまでで、EVPN/VXLAN によるテナント L2 拡張と ESI-LAG による冗長接続が完成しました。VM1(HV1 上)と BM1 が物理的に離れていても同一 L2 で通信でき、かつ片方のリンクが落ちても通信が継続する状態です。 4. Border Leaf と Internet Gateway 最後に、テナント網(VRF = 仮想ルーティングテーブル、「テナント専用の経路表」と考えてOK)と外部網(Global = インターネット側)を接続します。 leaf3-1 を VTEP 化 して Overlay の VLAN10 を Internet GW まで延伸 inet-gw1 で VRF-User と Global を Route Leaking inet-gw1 ↔ isp1 で eBGP 、isp1 から default route を受け取る 以下の内容を構成します。 4.1 leaf3-1(Border Leaf として VTEP 化) configure set vlans v10 vlan-id 10 set vlans v10 vxlan vni 10010 set vlans v10 vxlan ingress-node-replication # inet-gw1 接続ポート set interfaces ge-0/0/2 unit 0 family ethernet-switching interface-mode trunk set interfaces ge-0/0/2 unit 0 family ethernet-switching vlan members v10 commit 4.2 inet-gw1: 共通の下準備(I/F + ASN) configure set routing-options router-id 198.51.100.1 set routing-options autonomous-system 65002 # I/F set interfaces ge-0/0/0 vlan-tagging set interfaces ge-0/0/0 unit 10 vlan-id 10 set interfaces ge-0/0/0 unit 10 family inet address 192.168.10.1/24 set interfaces ge-0/0/1 unit 0 family inet address 203.0.113.2/30 set interfaces lo0 unit 0 family inet address 198.51.100.1/32 commit ge-0/0/0.10 がテナント側(leaf3-1 経由で BM1 と同セグ)、 ge-0/0/1.0 が インターネット側(外部)です。 4.3 inet-gw1: VRF と Route Leaking ユーザーの VRF( VRF-User )と Global テーブル( inet.0 = Junos の通常の経路表)を分離しつつ、必要な経路だけ相互にリーク(漏らす)します。これが「Route Leaking」で、「テナント内部の経路をインターネット側に教える(またはその逆)」ことで、テナント内のサーバーがインターネットと通信できるようになります。 configure # Route Leaking ポリシー(双方向) # Global -> VRF: default route のみ VRF に流す set policy-options policy-statement LEAK-GLOBAL-TO-VRF term ALLOW-DEFAULT from instance master set policy-options policy-statement LEAK-GLOBAL-TO-VRF term ALLOW-DEFAULT from route-filter 0.0.0.0/0 exact set policy-options policy-statement LEAK-GLOBAL-TO-VRF term ALLOW-DEFAULT then accept set policy-options policy-statement LEAK-GLOBAL-TO-VRF term DENY-REST then reject # VRF -> Global: BM1 の Global IP(/32)のみ Global へ流す set policy-options policy-statement LEAK-VRF-TO-GLOBAL term ALLOW-BM1 from instance VRF-User set policy-options policy-statement LEAK-VRF-TO-GLOBAL term ALLOW-BM1 from route-filter 198.51.100.41/32 exact set policy-options policy-statement LEAK-VRF-TO-GLOBAL term ALLOW-BM1 then accept set policy-options policy-statement LEAK-VRF-TO-GLOBAL term DENY-REST then reject # VRF 本体 set routing-instances VRF-User instance-type virtual-router set routing-instances VRF-User interface ge-0/0/0.10 set routing-instances VRF-User routing-options instance-import LEAK-GLOBAL-TO-VRF # BM1 の Global IP への static set routing-instances VRF-User routing-options static route 198.51.100.41/32 next-hop 192.168.10.101 # Global 側にも VRF からの経路を取り込む set routing-options instance-import LEAK-VRF-TO-GLOBAL commit 4.4 inet-gw1: 外部 ISP との eBGP 最後に、上で Global にリークした経路を eBGP で 外部 ISP へ広告します。 configure # 外部 ISP へ広告するポリシー(static のみ → 198.51.100.41/32 が乗る) set policy-options policy-statement ADVERTISE-TO-ISP term 1 from protocol static set policy-options policy-statement ADVERTISE-TO-ISP term 1 then accept set protocols bgp group TO-ISP type external set protocols bgp group TO-ISP peer-as 65001 set protocols bgp group TO-ISP neighbor 203.0.113.1 set protocols bgp group TO-ISP export ADVERTISE-TO-ISP commit 4.5 isp1 (外部 ISP 模擬) configure set routing-options router-id 192.0.2.1 set routing-options autonomous-system 65001 set interfaces ge-0/0/0 unit 0 family inet address 203.0.113.1/30 set interfaces lo0 unit 0 family inet address 192.0.2.1/32 set protocols bgp group TO-GW type external set protocols bgp group TO-GW peer-as 65002 set protocols bgp group TO-GW neighbor 203.0.113.2 set policy-options policy-statement SEND-DEFAULT term 1 from protocol static set policy-options policy-statement SEND-DEFAULT term 1 from route-filter 0.0.0.0/0 exact set policy-options policy-statement SEND-DEFAULT term 1 then accept set protocols bgp group TO-GW export SEND-DEFAULT set routing-options static route 0.0.0.0/0 discard commit 4.6 bm1 (Global IP 付与とデフォルトゲートウェイ) ip addr add 198.51.100.41/32 dev bond0.10 ip route replace default via 192.168.10.1 Q. なぜ /32 で付与するのか BM1 が「自分は 198.51.100.41 である」とさえ名乗れれば十分です。戻りパケットのルーティングは inet-gw1 の VRF 内に 198.51.100.41/32 next-hop 192.168.10.101 の static route があるため、ISP → inet-gw1 → (VRF) → leaf3-1 → VXLAN → leaf2-1/2-2 → BM1 と正しく転送されます。 4.7 動作確認 inet-gw1 で Global の inet.0 にも 198.51.100.41/32 が現れます (= VRF からのリーク成功)。 admin@inet-gw1# run show route 198.51.100.41 inet.0: 198.51.100.41/32 *[Static/5] > to 192.168.10.101 via ge-0/0/0.10 VRF-User.inet.0: 198.51.100.41/32 *[Static/5] > to 192.168.10.101 via ge-0/0/0.10 そして BM1 → 外部 ISP(192.0.2.1)への ping 、および逆方向の 外部 ISP → BM1(198.51.100.41)への ping がともに通れば、End-to-End の経路が完成です。 ~ # ping -c 3 -I 198.51.100.41 192.0.2.1 64 bytes from 192.0.2.1: icmp_seq=1 ttl=63 time=5.87 ms ... 3 packets transmitted, 3 received, 0% packet loss admin@isp1# run ping 198.51.100.41 count 3 64 bytes from 198.51.100.41: icmp_seq=0 ttl=63 time=6.070 ms ... 3 packets transmitted, 3 packets received, 0% packet loss ✅ 完成状態チェックリスト(Border GW) inet-gw1 の inet.0 と VRF-User.inet.0 の両方に 198.51.100.41/32 が存在 inet-gw1 ↔ isp1 の eBGP が Establ 、isp1 から default route を受信 BM1 → 192.0.2.1 (外部 ISP) の ping が通る( -I 198.51.100.41 で source 指定) 外部 ISP → 198.51.100.41 (BM1) の ping が通る ここまでで、テナント内の BM1 が VRF Route Leaking を経由して外部 ISP と双方向に通信できる End-to-End の経路が完成しました。本記事で目標としていた全構成の構築が完了です。 全体の完成確認 全セクションを通して構築した結果、冒頭で掲げたゴール — 物理的に離れた HV1 上の VM と BM1 が同一 L2 で通信でき、さらにインターネットへ抜けられる — が達成できています。完成した NW で実現できていることを整理します。 通信パス 経由するレイヤ VM1(HV1)↔ BM1 HV1 (VTEP) → VXLAN → Underlay (Spine経由) → leaf2-1/2-2 (VTEP) → BM1 BM1 → インターネット BM1 → leaf2-1/2-2 → VXLAN → leaf3-1 → inet-gw1 ( VRF Route Leaking ) → isp1 インターネット → BM1 isp1 → inet-gw1 (Global→VRF) → leaf3-1 → VXLAN → leaf2-1/2-2 → BM1 Underlay :eBGP + ECMP により、どちらの Spine を経由しても全ノードの Loopback が到達可能 Overlay :EVPN/VXLAN により、異なるラックの VM1 と BM1 が同一 L2(VNI 10010)で通信 冗長化 :ESI-LAG により、leaf2-1 または leaf2-2 のどちらか一方が故障しても BM1 の通信が継続 外部接続 :VRF Route Leaking により、テナント内部の経路とインターネット側の経路を相互にリークし、BM1 が外部と双方向に通信可能 これらが組み合わさることで、クラウド NW の基本構成 — マルチテナント対応の L2 延伸・物理冗長・外部接続 — が 1 つのラボ上で再現できています。 おまけ: ハマったら見るところ(Troubleshooting) 手順通りやってもうまくいかないとき、上から順に切り分けると早いです。 症状 確認ポイント BGP が Active から進まない 直結 ping → Loopback 間 ping → peer-as の値 → ポリシーで自分の経路を絞ってないか Underlay は OK だが Overlay iBGP が Active Loopback 間の ping、 local-address が自分の Loopback になっているか EVPN ピアは張れたが経路が来ない 両端の RT が一致しているか、 extended-vni-list の VNI 範囲 ESI-LAG で片側だけしか流れない 2 台の esi と lacp system-id が 完全に 一致しているか Junos 側で何が起きているか覗くコマンド run show bgp summary run show route table bgp.evpn.0 run show route advertising-protocol bgp <neighbor> run show route receive-protocol bgp <neighbor> run show ethernet-switching vxlan-tunnel-end-point remote run show evpn database FRR 側 vtysh -c "show bgp l2vpn evpn summary" vtysh -c "show evpn vni" vtysh -c "show evpn mac vni all" まとめ Containerlab + vJunos でクラウド NW の王道構成を一通り体験しました。しかし、本記事はあくまで学習用であり、実際の運用では次のような事項も検討が必要です。 IRB / Anycast Gateway (各 Leaf に同じ GW IP を持たせる分散 L3 ルーティング) MTU 設計 (Underlay 9000 / テナント 1500) BGP 認証 (MD5) マルチテナント運用 (VNI 数千規模の管理) セキュリティポリシー (マイクロセグメンテーション、ACL) 監視連携 本記事を通じてクラウド NW を少しでも知っていただき、「面白い!」と思っていただけましたら幸いです。 クラウド NW 開発に興味を持っていただけた学生の方は、ぜひインターンのポスト「 【B19】エンタープライズ向け大規模クラウド/ネットワークサービスを支えるコントローラ開発 」や「 【B25】エンタープライズ向け大規模クラウドサービスを支える仮想ネットワークソフトウェア開発 」にご応募ください。
はじめに さくらインターネットの黒澤です。 2026年2月11-13日(水-金)に大阪にてJANOG57ミーティングが行われました。JANOGでは毎回、さくらのエンジニアがプログラムの募集に応募し、選考に通って発表してい […]
はじめに こんにちは。普段はネットワークエンジニアとして法人系の堅いネットワークを作っています。 今回はデータセンタネットワーク等で使われるEVPN-VXLAN (Ethernet VPN over VXLAN)に触れてみたいと思います。 クラウド事業者では以前から用いられていたEVPN-VXLANですが、最近EVPN-VXLANの利用が必須となる規模ではないデータセンタ案件でも検討対象となる機会が増えてきています。 一方でネットワークエンジニア目線ではEVPNは独特な用語や概念が多く、なかなか触れる機会も学習機会も少ないと思います。 本ガイドではLinuxとオープンソースソフトウェ

動画

該当するコンテンツが見つかりませんでした

書籍