Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kubernetesの上にVPCを作る — eBPF + BGPで実現するマルチテナントネットワーク

Avatar for MuNeNiCK MuNeNiCK
August 28, 2026
130

Kubernetesの上にVPCを作る — eBPF + BGPで実現するマルチテナントネットワーク

Kubernetesをマルチテナントな基盤として使うと、VPCのようなネットワークも作れます。

今回は、Namespaceごとにネットワークを分離し、異なるVPCでは同じIPアドレスも使える自作CNIについて紹介します。

eBPFやVXLAN、BGPを使ってどのように実現しているのかを話します。

Avatar for MuNeNiCK

MuNeNiCK

August 28, 2026

Transcript

  1. 自己紹介 宮田 宗幸 MuNeNiCK 所属 株式会社フォーセシステム 仕事 インフラ系SIer 最近やっていること •

    オンプレKubernetes上に、EKS FargateのようなサーバーレスKaaSを構築中 • JPNICからAS番号を取得し、BGP接続に向けてネットワークを構築中 X @nick_mune0127 GitHub MuNeNiCK 2
  2. パブリッククラウドでは、顧客ごとにネットワークを分け られる VPC のような仮想ネットワークで、顧客ごとに独立したアドレス空間を持てる 顧客 A 顧客 B VPC VPC

    10.0.0.0/16 10.0.0.0/16 VM / Pod 10.0.1.10 VM / Pod 10.0.1.10 同じCIDR・同じIPでも、VPCが違えば独立 例:Amazon VPC / Google Cloud VPC / Azure Virtual Network 4
  3. Kubernetes上でも、同じことができる? 標準のままでは、VPCのようなアドレス空間の分離はできない Kubernetes Cluster Namespace: 顧客 A Pod 10.0.1.10 Namespace:

    顧客 B 1つの Pod Network Namespace:管理の境界 Pod 10.0.2.10 NetworkPolicy:通信の許可 / 拒否 どちらも「顧客ごとに同じCIDRを再利用するVPC」ではない Source: Kubernetes Docs — Services, Load Balancing, and Networking / Multi-tenancy 5
  4. なら、自作しよう Podのネットワークを作る CNI Plugin を自分で実装する kubelet / runtime CNI 自作

    CNI Plugin Pod veth / IPAM / route + 独自の処理 CNIが決めるのはインターフェース。中身はPlugin側で実装できる 今回、VPCを実現するためのCNIを作った 6
  5. 今回の実装:必要な機能を4つに分ける やりたいこと 使うもの 役割 顧客ごとのVPCを識別 → VNI VPCごとにIDを持たせる パケットを転送 →

    eBPF Podの通信をNode上で処 理 Nodeをまたいで通信 → VXLAN VNIを保持したまま別 Nodeへ 外部ネットワークと接続 → BGP 外部IPの経路を上流へ通 知 VPC / Subnet はCRDとして管理し、Controllerから各Nodeへ設定を反映 7
  6. 顧客ごとにVPCを分ける:VNI 同じIPでも、VNIが違えば別のVPCとして扱える Node 1 Node 2 VPC-A VNI 100 /

    Pod 10.0.1.10 VPC-B VNI 200 / Pod 10.0.1.10 Node間は VXLANで VNIをそのま ま運ぶ VPC-A VNI 100 / Pod 10.0.1.20 VPC-B VNI 200 / Pod 10.0.1.30 VXLANは「Node間でVNIを運ぶ手段」。主役はVPCを識別するVNI。 9
  7. VPCを作る仕組み:VNI + FIB 転送は「VPCを識別 → そのVPCの経路を引く」の2段階 受信したパケット VPCを特定 経路を検索 転送先

    VNI 100 dst 10.0.1.20 → VNI 100 = VPC-A → FIB Lookup 10.0.1.20 → VPC-A内の Pod / Node VNI 200 dst 10.0.1.20 → VNI 200 = VPC-B → FIB Lookup 10.0.1.20 → VPC-B内の Pod / Node 同じ宛先IPでも、VNIが違えば「別のVPCの経路」として処理できる
  8. パケット処理は eBPF Podから出たパケットをeBPFで見て、転送先を決める 同じNode → Podへ Pod eBPF (TC) 別Node

    → VXLANへ 外部 → NAT / 外部IP へ 経路情報は eBPF Map に保持。FIB Lookup / LPM Trie などの詳細は Appendix。 11
  9. なぜ eBPF を使うのか? VPCの L2 / L3 / NAT を、Node上の1つのデータプレーンで処理したい

    今回必要だったこと eBPFでどう実現するか Pod / Hostのパケットを直接処理したい → TC hook veth / Host IF でパケット を処理 経路・NAT状態を動的に更新したい → eBPF Map ControllerからFIB / NAT 状態を更新 同一Node / VXLAN / 外部を一貫して判 断したい → 1つのデータ プレーン 同じLookup結果から転送 処理を分岐 Controller が状態を更新 → eBPF Mapへ反映 → パケットの転送結果が変わる
  10. VPCを外につなぐ:外部IP + BGP 外部IPをVPC内のPod / VMへ紐付け、その経路を上流ルーターへ知らせる VPC内 Pod / VM

    10.0.1.10 FIP EIP 203.0.113.10 EIP (ExternalIP) 外部から到達するためのIP FIP (FloatingIP) EIPとVPC内のPod / VMを紐付ける BGP 「このEIP宛てはこのNodeへ」と上流ルーターへ経路を広報 BIRD BGP 上流 Router 12
  11. 実際に動いている:mNi Cloud mNi Cloud Kubernetes ベースの IaaS / コンテナサービス •

    VPC / VM / VPN / ブロックストレージ / コンテナ • 最近はマネージドKubernetesサービスができてたり… • 2006年, 2008年生まれの学生アルバイトとともに開発中 開発ブログ https://zenn.dev/mnicloud 13
  12. eBPF データプレーン pod_egress Pod veth → L2 判定 VXLAN IF

    → デカプセル化 → VNI → Subnet特定 Host IF → デフォルト Subnet判定 → 宛先Pod 検索 Pod → 外部 vxlan_ingress VXLAN → Pod host_egress Host → Pod ARP応答 → L3ルーティング → FIB Lookup (LPM Trie) → VXLAN カプセル化 → 宛先Pod 検索 → Pod veth へ転送 → Pod veth へ転送 → Remote Node FIB は eBPF Map(LPM Trie)上に構築。 16
  13. BGP + BIRD で実現する EIP / FIP 3 つの CRD

    で BIRD を制御 AddressPool 外部IPアドレス帯 → BGPPeer ASN / ピアアドレス → BGPAdvertisement 広報対象プール指定 Inbound(外部 → Pod) 外部クライアント → 上流ルーター → BIRD (BGP受信) → eBPF FIB Lookup → VPC 内 Pod → EIP で送出 → 上流ルーター → 外部 Outbound(Pod → 外部) VPC 内 Pod → eBPF NAT (SNAT) ※ iptables を一切使わず、eBPF の FIB テーブル更新だけで NAT を実現 17
  14. 既存実装(Kube-OVN)との比較 以前は Kube-OVN を利用していたが、OVS ベースゆえの課題があった。 自作 CNI ではこれらを根本的に解決している。 Kube-OVN(従来) 自作

    CNI データプレーン OVS (Open vSwitch) eBPF (TC) NAT / FIP iptables (IptablesEIP / FIPRule) eBPF FIB テーブル iptables 不要 外部接続 OVN Gateway BIRD (BGP) で広報 テナント隔離 OVN Logical Switch VXLAN VNI (Namespace 単位) デバッグ容易性 難しい (OVS の内部状態) bpftool / tcpdump で直接確認可能 18