CNIとPodネットワークモデルの原理
なぜKubernetesではPodが互いにIPで直接届くのか。NATなしのフラット到達性を支えるCNIの責務、VXLANオーバーレイとBGPルーティングの違い、IPAMの仕組みを原理から解きほぐす。
- 1.Kubernetesのネットワークモデルは「全Podが互いにNATなしで直接到達でき、PodはIPを自分のものとして見る」ことを要求する。CNIはこの前提を実装するプラグイン規約。
- 2.実装はオーバーレイ(VXLANでL2をカプセル化)とルーティング(BGPで各ノードのPod CIDRを広告)の2方式が中心。前者はネットワーク非依存だがカプセル化コスト、後者は高速だが下層への要求が強い。
- 3.IPAMがPodごとにIPを払い出し、CNIプラグインがveth・ルート・iptables/eBPFを設定する。kubeletがコンテナ作成時にADD/DELを呼ぶのが起動点。
Kubernetesネットワークモデルが課す3つの前提
CNIを理解する前に、Kubernetesがネットワークに課す要件を押さえる必要があります。Kubernetesは具体的な実装を指定せず、満たすべき不変条件だけを定義します。
- すべてのPodは、NATなしで他のすべてのPodと通信できる。
- すべてのノードは、NATなしでそのノード上の全Podと通信できる。
- Podが自分自身に見えるIPと、他者がそのPodを指すために使うIPが一致する。
3点目が肝です。一般的なコンテナ(/devops/container-vs-vm/)はNAT越しに外へ出るため、Pod内から見た自分のIPと外から見たIPが食い違いがちです。Kubernetesはこれを禁じ、フラットなIPアドレス空間を要求します。アプリは相手のPod IPへ素直にパケットを投げれば届く——この「土管」を用意するのがCNIの仕事です。
CNIという規約:kubeletとプラグインの契約
CNI(Container Network Interface)は、CNCF傘下の薄い規約です。実体は「コンテナのネットワーク名前空間を渡すので設定してくれ」という関数呼び出しに過ぎません。
kubelet → CRI(containerd等)→ CNIプラグイン実行ファイル
ADD : Pod作成時。netnsにveth/IP/ルートを設定し、割当IPを返す
DEL : Pod削除時。割当IP・配線を解放する
CHECK : 設定が期待どおりか検証する
kubeletがPodのサンドボックス(pauseコンテナ)を作ると、CRI経由でCNIプラグインのバイナリが起動されます。プラグインは標準入力でJSON設定(/etc/cni/net.d/ 配置)を受け取り、環境変数で対象netnsのパスやCNI_COMMAND=ADDを受け取ります。1コンテナ=1回のADD呼び出しが基本単位で、ここが全ての起点です。
Pod内の各コンテナはネットワーク名前空間を共有します。その器を持つのが、何もしないpause(sandbox)コンテナです。アプリコンテナが再起動してもnetnsとIPは保たれる——Podが「IPを持つ最小単位」である理由がこれです。
ADDの内部:vethペアとルートの実体
ADDで典型的なプラグイン(bridge系)が行う配線は、Linuxの素朴な道具立てです。
1. vethペアを作る: eth0(Pod netns内) ⇔ vethXXXX(ホスト側)
2. Pod側eth0にIPAMが払い出したIPとサブネットを設定
3. ホスト側vethをノードのブリッジ(cni0)やルートに接続
4. Pod内デフォルトルートをゲートウェイ(cni0)へ向ける
5. 必要なiptables/nftables/eBPFルールを書く(外向きNAT等)
vethは仮想イーサネットのトンネルで、片端に入ったフレームがもう片端から出ます。Pod内 eth0 から出たパケットはホスト側のveth端に現れ、そこからノードのルーティング判断に乗ります。同一ノード内のPod間はブリッジ/ローカルルートで完結しますが、問題はノードをまたぐときです。相手Podは別ノードにいる——ここで方式が分岐します。
方式1:オーバーレイ(VXLAN)
オーバーレイは、Podパケットを別のパケットで包んで(カプセル化)、ノード間の物理ネットワーク上を運ぶ方式です。代表はVXLANで、Flannel(vxlanバックエンド)やCalicoのVXLANモードが採用します。
[Pod A] -- Podフレーム --> [VTEP: ノードX]
ノードXがPodフレームを UDP(VXLAN) で包む
外側IP = ノードX → ノードY(物理NICのIP)
内側 = 元のPod間フレームをそのまま保持
[VTEP: ノードY] が剥がして --> [Pod B]
各ノードはVTEP(VXLAN Tunnel Endpoint)として振る舞い、宛先Pod IPがどのノードにいるかの対応表を持ちます。利点は下層ネットワークへの要求がほぼゼロな点——ノード同士がIP到達可能でUDPが通れば動くため、クラウド/オンプレを問いません。代償はカプセル化のオーバーヘッドです。
外側ヘッダ(VXLANで概ね50バイト)の分だけ、内側で使えるMTUが縮みます。Pod側MTUを下げ忘れると、断片化や通信失敗(特にPMTUDが効かない経路)を招きます。さらにカプセル化/復号のCPUコストが乗り、高スループット時のボトルネックになり得ます。
方式2:ルーティング(BGP)
ルーティング方式は、カプセル化せず素のPodパケットをそのままルーティングします。鍵は「どのPod CIDRがどのノードにあるか」を、L3ネットワークに教え込むこと。これを動的に行う定番がBGPで、CalicoのBGPモードが代表です。
各ノードは自分が担当するPodサブネット(例 10.244.3.0/24)を、BGPで経路広告します。ピアであるノード群やトップオブラックのルーターがこれを学習すると、宛先Pod IP宛のパケットは通常のIPルーティングで正しいノードへ届きます。届いた先ではローカルルートでPodへ。カプセル化が無いぶん高速でMTU劣化もありません。
| 観点 | オーバーレイ(VXLAN) | ルーティング(BGP) |
|---|---|---|
| 下層への要求 | ノード間IP到達のみ。物理網に無干渉 | 下層ルーターがPod経路を学習する必要(BGPピア等) |
| 性能 | カプセル化のCPU/MTUコスト | 素のパケットで高速・MTU劣化なし |
| 可視性 | 物理網からはPod IPが見えない | Pod IPが物理網にそのまま露出 |
| 向く環境 | クラウド/制御外の網・多様な構成 | ネットワークを制御できるオンプレ・自前データセンター |
実装は二者択一ではありません。CalicoのIP-in-IPは最小限のカプセル化で「BGPが届かないサブネット境界だけ包む」折衷で、CrossSubnetモードでは同一サブネット内は素のルーティング、跨ぐ時だけカプセル化と使い分けます。
IPAM:誰がIPを払い出すか
到達性の前提は「IPの重複が無いこと」です。これを担うのがIPAM(IP Address Management)で、CNI設定内の独立した責務として分離されています。原理はアドレス空間の階層的分割です。
クラスタ全体の Pod CIDR : 10.244.0.0/16
└ ノードごとに /24 を割当 : ノードA=10.244.0.0/24, ノードB=10.244.1.0/24 ...
└ Podごとに /32 を払い出し : 10.244.0.7 など
ノードにブロック(サブネット)を割り当てておけば、各ノードのIPAMはそのブロック内からローカルに重複なくPodへ払い出せます。毎回中央へ問い合わせずに済むため高速で、中央障害にも強い。ブロック割当の調停には、KubernetesのNode.spec.podCIDRやCNI独自データストア(CalicoのIPAMブロック)が使われ、枯渇したノードは追加ブロックを要求します。
最も素朴なhost-localプラグインは、ノードに与えられたCIDRとディスク上の割当ファイルだけで動きます。中央データベースを持たず、ノードに閉じて重複を避ける——分散システムで「調停をいかに減らすか」(/devops/gossip-protocol/ 等で問われる主題)の、最小実装の好例です。
チェイン構成とデータプレーンの実装差
CNIはプラグインをチェインできます。1つのADDで「bridge(配線)→ portmap(ポート転送)→ bandwidth(帯域制限)」と順に適用し、各段が前段の結果(割当IP等)を受け取って責務を積み重ねます。
データプレーン(実際にパケットを捌く層)も進化しています。初期はiptablesでServiceのDNAT等を実現していましたが、ルール数がサービス数に比例して線形探索となり大規模で劣化しました。Calico/CiliumはこれをeBPF(/devops/ebpf-observability/)で置き換え、カーネル内のハッシュマップ参照で高速に転送・負荷分散します。CiliumはService処理をkube-proxy(iptables)から奪う設計で、通信機能を外側レイヤーへ寄せる流れ(/devops/service-mesh/)とも地続きです。
まとめ
- KubernetesはNATなしのフラット到達性と自他で一致するPod IPを要求し、CNIはこの前提を満たすための薄い規約。
- kubeletがコンテナ作成時にADD/DELを呼び、プラグインがveth・ルート・IPAM払い出しを実行する。
- ノード跨ぎの実現は**オーバーレイ(VXLANで包む、網に非依存だがコスト)とルーティング(BGPで経路広告、高速だが下層へ要求)**の2系統。
- IPAMはアドレス空間をノード単位ブロックへ階層分割し、ローカルに重複なく払い出すことで調停を最小化する。
- データプレーンはiptablesからeBPFへ移行し、大規模時のService処理を高速化している。
DevOps/インフラ Article
CNIとPodネットワークモデルの原理を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
CNI
比較で見る軸
難易度: advanced / カテゴリ: DevOps/インフラ / タグ数: 5
導入後に効く点
実装はオーバーレイ(VXLANでL2をカプセル化)とルーティング(BGPで各ノードのPod CIDRを広告)の2方式が中心。前者はネットワーク非依存だがカプセル化コスト、後者は高速だが下層への要求が強い。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- DevOps/インフラ
- タグ数
- 5
判断チェックリスト
- 自社の用途が「CNI / Kubernetes」に近いか確認する。
- 強みである「Kubernetesのネットワークモデルは「全Podが互いにNATなしで直接到達でき、PodはIPを自分のものとして見る」ことを要求する。CNIはこの前提を実装するプラグイン規約。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。