Kubernetesのネットワークを触っていると、最初は「CNIはCalicoかCiliumか」といった製品選定の話が出てきます。
ただ、実際に調べ始めると、Pod IPの割り当て、ノード間ルーティング、Service、NetworkPolicyがそれぞれ別の仕組みで動いていて、「結局、このパケットはどこを通っているんだ?」となることが何度もありました。
私自身、GKEのDataplane V2と従来のCalico構成を調べる中で、CNIという一言でまとめて理解しようとすると、かえって混乱することに気づきました。
実際に、Kubernetesクラスターを構築して運用する際、Pod間のネットワーク通信を司るCNI(Container Network Interface)の選定は、システム全体のパフォーマンスやセキュリティに決定的な影響を与えます。しかし、CNIが裏側でパケットをどのように配送し、アクセス制御ルールをどう評価しているのか、その物理的なネットワークやOSカーネル層の仕組みは、公式ドキュメントだけでは全貌を掴みきれない部分があります。
本記事では、Pod間のパケット配送モデルである「アンダーレイ」と「オーバーレイ」の一般的な概念を整理した上で、ServiceやNetworkPolicyのデータプレーンとして使われるiptablesと、現代のコンテナネットワークで採用が進むeBPF(Extended Berkeley Packet Filter)について解説します。さらに、これらの一般的な仕組みが、AWS(EKS)、Azure(AKS)、GCP(GKE)といった主要パブリッククラウドのマネージドサービスにおいてどのように実装されているのか、実例を交えて説明していきます。
CNIとは?
CNI(Container Network Interface)は、コンテナのネットワークインターフェースを構成するための標準仕様です。Kubernetesでは、Podの作成・削除にあわせてCNIプラグインが呼び出され、PodへのIPアドレスの割り当てやネットワークインターフェースの設定、ノードや外部ネットワークとの接続に必要な処理を行います。
代表的なCNIプラグインにはFlannel、Calico、Ciliumがあり、AWS VPC CNIやAzure CNIのようにクラウドプロバイダーが提供する実装もあります。
ただし、「CNI」と「実際にパケットをどう配送するか」は同じ概念ではありません。Pod間通信にアンダーレイを使うかオーバーレイを使うか、ServiceやNetworkPolicyをiptablesやeBPFのどちらで処理するかは、それぞれ別の設計要素です。
まずは、Podのパケット配送を決めるアンダーレイとオーバーレイの違いから見ていきます。
パケット配送を決定づける二大通信モデル:アンダーレイとオーバーレイ
Pod宛てのパケットを、物理ノードをまたいでどのように配送するか。ここにはアンダーレイとオーバーレイという、全くアプローチの異なる二つの一般的な通信モデルが存在します。
アンダーレイネットワーク
仮想的なトンネルを構築するのではなく、既存の物理ネットワークやパブリッククラウドのVPCが持つルーターにPodのパケットルーティングを直接委ねる方式です。
-
仕組みとパケットの流れ:
Podが送信したパケットは、カプセル化(別のIPパケットの中に包み込まれる処理)されることなく、そのままホストノードのインターフェースを経由して物理・VPCルーターへと流れます。ルーターはPodのIPアドレスを認識し、宛先ノードへのルーティングテーブルに従ってパケットを転送します。 -
メリット:
パケットのカプセル化・解除が発生しないため、その処理に伴うCPU負荷やMTUへの影響を避けやすく、低遅延・高スループットを実現しやすい方式です。 -
課題:
Podが物理ネットワークやVPC上の「本物のIPアドレス」を直接消費するため、IPアドレスの消費スピードが極めて速くなります。また、ノードが属するサブネットの大きさによって、1つのクラスターやノードあたりに配置できるPod数が厳しく制限されるという制約があります。
オーバーレイネットワーク
ノードが接続されている既存の物理・VPCネットワーク(アンダーレイ)の上に、ソフトウェアによって仮想的なネットワークを重ね合わせる方式です。
-
仕組みとパケットの流れ:
Podには物理・VPCネットワークとは独立したIPアドレス空間が割り当てられ、CNIやクラウド側のネットワーク機構によってノード間を配送されます。VXLANやGeneve、IPIPなどでカプセル化する実装もありますが、Azure CNI Overlayのようにカプセル化せずに配送する実装もあります。 -
メリット:
PodごとにVPC/VNetサブネットのIPアドレスを消費する必要がないため、IPアドレス枯渇を回避しやすくなります。また、Pod用のCIDRを独立して設計できます。 -
課題:
トンネルを利用する実装では、カプセル化・解除によるCPU負荷やMTUへの影響を考慮する必要があります。
個人的には、この2つを「どちらが高性能か」だけで比較すると、本質を見失いやすいと感じています。
クラウド環境では、IPアドレス空間そのものが設計上のかなり大きな制約になります。小規模なクラスターでは気にならなくても、Pod数やクラスター数が増えた途端、「VPC/VNetのCIDRをどう確保するか」がネットワーク方式の選択を左右します。
そのため、アンダーレイとオーバーレイは性能比較というより、IPアドレスをクラウド側のネットワークとどこまで共有するかという設計判断として見るほうが理解しやすいと思います。
代表的なオープンソースCNIプラグインの特徴
パケット配送モデルを理解したところで、実際に多くのKubernetes環境で広く採用されている代表的な3つのオープンソースCNIプラグイン(Flannel, Calico, Cilium)について、それぞれの具体的な仕様と役割の違いを見ていきます。
| CNIプラグイン名 | 主な通信モデル | 主なパケット処理方式 | NetworkPolicy対応 | 主な強みと弱み |
|---|---|---|---|---|
| Flannel | オーバーレイ(VXLANなど) | VXLAN、host-gwなど | 単体では非対応(公式HelmでNetwork Policy Controllerを追加可能) | シンプルで軽量 / ポリシー制御には別コンポーネントが必要 |
| Calico | オーバーレイ または アンダーレイ(BGP) | iptables、nftables、eBPF、VPP | 非常に強力(GlobalNetworkPolicyなど) | 安定性と高いポリシー制御機能 / データプレーンによって運用特性が異なる |
| Cilium | オーバーレイ または Native Routing | eBPF中心 | L7、FQDNポリシーなどに対応 | 高性能、Hubbleによる可視化 / 比較的新しいLinuxカーネルが必要、デバッグ手法が従来と異なる |
1. Flannel:軽量さと引き換えの極めてシンプルな機能
CoreOSが開発した、歴史が長くシンプルなCNIプラグインの1つです。設定が容易でリソース消費量も比較的少ない一方、flanneld 自体はKubernetes NetworkPolicyを適用しません。ただし、Flannel v0.25.5以降では、公式Helm Chartの netpol.enabled を有効化することでKubernetes SIGsのNetwork Policy Controllerを追加できます。
2. Calico:業界標準としての地位を確立した万能プレイヤー
最も広く普及しているCNIプラグインの1つであり、クラスター全体にまたがる GlobalNetworkPolicy や、ノード自体を保護する Host Endpoint 制御など、強力なポリシー制御機能を備えています。データプレーンも、標準的なiptablesのほかに、nftablesやeBPF、VPPなどを選択できます。オンプレミスの物理ルーターとBGPピアリングを結び、Podの経路を社内ネットワークに広告する構成では、Calicoは代表的な選択肢の1つです。
3. Cilium:eBPFによる次世代ネットワークの旗手
CNCF(Cloud Native Computing Foundation)の卒業プロジェクトであり、最初からeBPFを使用することを前提に設計された先進的なCNIです。
kube-proxy replacementを有効化することで、Kubernetes ServiceのロードバランシングをeBPFで処理できます。さらに、L7プロキシなどと連携することで、HTTPのパスやDNS名、FQDNといったL7情報を利用したポリシーも構成できます。
近年では、多くのプラットフォームでデータプレーンの刷新としてCiliumの統合が進んでいます。
パケットフィルタリングとプロキシの進化:iptables と eBPF
Kubernetesネットワークを調べていて、私が最初につまずいたのがここでした。
「CiliumだからeBPF」「Calicoだからiptables」と単純に対応づけたくなるのですが、実際にはPodの配送方式、Serviceの転送、NetworkPolicyの実装は別々に考える必要があります。
特に障害調査では、「iptablesを見ればいい環境なのか」「eBPF mapを見るべき環境なのか」で調査方法そのものが変わります。そこで、ここからはiptablesとeBPFの違いを少し掘り下げます。
【従来の iptables 方式】
新規コネクションの最初のパケット -> [ iptablesルールを評価 ] -> Podへ
※ ServiceやEndpointが増えるほどルール数や更新コストが増え、大規模環境では性能上の課題になりやすい。
【現代の eBPF 方式】
パケット受信 -> [ eBPFプログラム実行 / eBPF mapを参照 ] -> Podへ
※ 大量のiptablesルールを逐次評価する方式を避け、Serviceやポリシー情報を効率的に検索できる。
従来の iptables 方式(Calico標準データプレーンなど)
Kubernetesの Service (ロードバランシングを行うための仮想IP)は、長年 kube-proxy がLinuxのiptablesルールを動的に書き換えることで実装されてきました。 また、Pod間のアクセス制御を行う NetworkPolicy は、CalicoなどのCNI・NetworkPolicy実装がiptablesやeBPFなどを利用して適用します。
-
仕組みの限界:
iptablesベースのkube-proxyでは、ServiceやEndpointが増えるほどルール数や更新量が増加します。特に新規コネクションの最初のパケットにおけるルール評価や、ルール同期にかかるCPU負荷・反映時間が、大規模クラスターでは課題になることがあります。
現代の eBPF 方式(Cilium、GKE Dataplane V2など)
eBPF(Extended Berkeley Packet Filter)は、Linuxカーネルを改造することなく、カーネル内の特定のフックポイント(ネットワークデバイスのパケット受信時など)で、安全にコンパイルされた独自プログラムを動的実行できる技術です。
-
技術的ブレイクスルー:
iptablesとkube-proxyの組み合わせに代えて、Serviceやポリシーなどの情報をeBPF mapに保持し、カーネル内で効率的に検索できます。これにより、大量のiptablesルールを生成・評価する方式と比べて、大規模環境でのパケット処理やルール更新を効率化できます。
なお、Kubernetes 1.33ではkube-proxyの nftables モードもGAになっています。iptablesモードと比べてServiceやEndpointの更新を効率化でき、大規模クラスターでのスケーラビリティを改善する選択肢です。eBPFとは異なるアプローチですが、iptablesとeBPFだけが選択肢ではない点には注意が必要です。
各種パブリッククラウドにおけるCNIの実装事例
ここまで解説した「パケット配送モデル」や「パケット処理のデータプレーン」は、主要なパブリッククラウドのマネージドKubernetesサービス(EKS / AKS / GKE)において、どのように実装され、どのようなトレードオフが存在するのでしょうか。それぞれの設計思想に基づいた実装アプローチを客観的に見ていきます。
AWS (Amazon EKS:AWS VPC CNI)
Amazon EKSでは、パブリッククラウドのVPCネットワークとの親和性と統合を重視し、アンダーレイ方式が採用されています。
-
優れたVPC統合機能:
EC2のENI(ネットワークインターフェース)に割り当てられたセカンダリプライベートIPをPodに直接付与するAWS VPC CNIが動作します。PodがVPCのネイティブIPを持つため、AWS Load Balancer ControllerでIP target typeを利用すると、Application Load Balancer (ALB) やNetwork Load Balancer (NLB) のターゲットグループへPod IPを直接登録し、NodePort経由の転送をバイパスできます。さらに、VPCセキュリティグループをPod単位で適用できるSecurity Group for Podsを使用することで、RDSなどクラスター外のAWSリソースへのアクセスにも、既存のVPCセキュリティグループによるネットワーク制御を適用できます。 -
Pod高密度化への対応:
インスタンスタイプに依存するENI/IPの上限により、起動できるPod数が制限されるという特性がありますが、Prefix Delegationを利用すると、/28のIPプレフィックスをENIに割り当てることで1ノードあたりのPod収容密度を大幅に向上できます。ただし、PodIP自体はVPCサブネットから消費するため、サブネットのIPアドレス設計は引き続き重要です。また、利用には連続した/28の空きアドレス空間を確保できることが望まれます。
なお、AWS VPC CNIは主にPodへのIP割り当てとVPCへの接続性を担い、Kubernetes Serviceの転送処理そのものは通常 kube-proxy が担当します。また、Amazon VPC CNIのNetworkPolicy機能ではeBPFが利用されます。 このようにEKSでも、「Podの接続性」「Serviceの転送」「NetworkPolicy」は、それぞれ異なる仕組みで実装される場合があります。
Azure (Azure Kubernetes Service:Azure CNI)
Azure AKSでは、エンタープライズの多様なインフラ要件に適合できるよう、柔軟な構成アプローチが選択できるように設計されています。
-
要件に応じた構成の自由度:
VNetのIPアドレスをPodに直接割り当てるAzure CNIに加えて、VNetとは独立したPod CIDRを利用するAzure CNI Overlayも選択できます。OverlayではPodごとにVNetサブネットのIPを消費しないため、大規模環境でのIPアドレス消費を抑えやすくなります。 -
eBPFデータプレーンの提供:
Azure CNI Powered by Ciliumでは、CiliumをベースにしたeBPFデータプレーンを利用し、NetworkPolicyやServiceのロードバランシングを処理できます。Pod IPの割り当て方式とは独立したデータプレーンとして、Overlayを含む複数のAzure CNIネットワーク構成と組み合わせて利用できます。
GCP (Google Kubernetes Engine:GKE Dataplane V2)
Google CloudのGKEでは、VPC-native(Alias IP)というアンダーレイのルーティングが組み込まれています。
-
効率的なPodIP管理:
各ノードに割り当てられたAlias IPレンジからPodへIPを割り当てます。GKE Standardでは1ノードあたりの最大Pod数のデフォルトは110ですが、設定によって変更できます。 -
eBPFとのネイティブ統合:
Google Cloudが推奨するGKE Dataplane V2では、VPC-nativeのAlias IPルーティングと、CiliumをベースにしたeBPFデータプレーンが統合されています。
GKE環境におけるDataplane V2とLegacy Calicoの運用設計
ここからは少し一般論を離れて、私たちが普段触っているGKEの話をします。
CNIを調べ始めたきっかけも、実際にはこのDataplane V2でした。eBPFを使うことで「iptablesより高速になる」という説明だけなら理解しやすいのですが、運用する側から見ると、気になるのはむしろ別のところです。
既存クラスターから移行できるのか
障害時に何を見ればいいのか
eBPF mapに上限はないのか
Kubernetes/GKEのアップデートで何が変わるのか
調べてみると、このあたりは単純な「eBPFのメリット・デメリット」では語れませんでした。以下は、実際にGKEで運用する前提で特に気になったポイントです。
1. クラスターのライフサイクルと移行における制約
GKE Dataplane V2は、クラスター新規作成時のみ有効化できます。稼働中の既存クラスターからオンラインのままDataplane V2へとアップグレードする機能は提供されていません。CNIの実装方式を変更するには、新たなクラスターを構築してトラフィックを段階的に切り替える必要があるため、初期のアーキテクチャ設計段階での慎重な決定が求められます。
2. anetdコントロールプレーンに起因するCPU負荷
eBPFを採用したGKE Dataplane V2では、各ノードに anetd と呼ばれる管理用のDaemonSetが配置され、eBPFマップの書き換えを担います。
個人的に意外だったのは、eBPFにすればCPU負荷の問題がすべてなくなるわけではない、という点です。
データプレーンが効率化されても、その状態を管理するコントロールプレーン側には当然仕事が残ります。anetd の挙動は、そのことを分かりやすく示しているように思います。
3. eBPF Serviceマップに存在する上限値
GKE Dataplane V2は、ServiceとそのバックエンドとなるPodの対応関係をeBPFのServiceマップで管理します。このマップには、クラスター全体で最大260,000 endpointsという上限があります。
$$\sum (\text{各ServiceのバックエンドPod数}) \le 260,000$$
260,000と聞くと、普通のクラスターではまず到達しない数字に見えます。私も最初はそう思いました。
ただしこれは単純なPod数ではなく、Serviceとbackendの組み合わせの合計です。Service数とレプリカ数が両方増える環境では、思ったより速く膨らみます。
4. GKE 1.34以降における最新の仕様変更
GKE 1.34以降のバージョンでは、Dataplane V2の内部アーキテクチャにさらなる最適化が施されています。
-
cni-writerへの処理移行: 従来、GKE固有のネットワーク設定を担当していた
netdDaemonSetから、CNI構成の書き込み処理がanetd内のcni-writerコンテナへと移行され、ライフサイクル管理が効率化されました。 -
Podネットワークインターフェース名の変更: ノードにデプロイされるPodのインターフェース名称が、従来の
gke-から始まる形式からlxc-で始まるハッシュ形式へと変更されています。 -
ptpプラグインの削除: CNIの処理フローから、不要となったPoint-to-Point接続用の
ptpプラグインが排除され、データパスの整理が進められています。
ネットワーク要件に基づくCNI選定の指針
ここまで調べて、自分の中では「CNIを選ぶ」という問い自体が少し雑だったのだと思うようになりました。
実際に決めるべきなのは、
Pod IPをどこから払い出すか、ノード間をどう配送するか、Serviceをどう処理するか、NetworkPolicyをどこで適用するか、という複数の選択です。
CiliumかCalicoか、という製品名から考え始めるより、この4つを先に決めたほうが設計しやすい。今回調べた中での一番大きな学びはそこでした。
| 満たすべき優先要件 | 推奨されるCNIアーキテクチャ | クラウドでの具体例 | 理由と考慮点 |
|---|---|---|---|
| カプセル化なしの極小レイテンシーと最大スループット | アンダーレイ(カプセル化なし) | AWS VPC CNI (Prefix Delegation推奨) / GKE VPC-native | 物理/VPCレイヤーでの直接転送。AWSではノードあたりのPod上限やPrefix DelegationによるIP管理コストに注意。 |
| VPC/VNetネットワークのIPアドレス消費を抑えたい | オーバーレイ(Pod CIDRをVPC/VNetと分離) | Azure CNI Overlay / 各種オーバーレイCNI | PodごとにVPC/VNetサブネットのIPアドレスを消費しない。実装によってはカプセル化を利用するため、その場合はCPU負荷やMTUへの影響も考慮する。 |
| 数千以上のサービス、ポリシーが並行動作する大規模環境 | eBPFベースのデータプレーン | GKE Dataplane V2 / Azure CNI Powered by Cilium | 大量のiptablesルールへの依存を減らし、Serviceやポリシー情報をeBPF mapから効率的に参照できる。 |
| 既存のLinuxネットワーク技術での運用性・安定性を最優先する | iptablesベースのデータプレーン | EKS (標準) / GKE Legacy (Calico) / AKS (Legacy) | 標準的なツールでノード上のパケットルールを直接参照・追跡可能。ただし大規模スケール時の遅延とCPU負荷増大を許容する必要あり。 |
今回CNI周辺を整理してみて、改めて感じたのは、Kubernetesネットワークの難しさは「技術が難しい」こと以上に、複数の仕組みがCNIという言葉の周辺にまとめて語られがちなことにある、という点でした。
Pod IPの割り当て、ノード間配送、Service、NetworkPolicy。この4つを分けて見るだけでも、EKS・AKS・GKEの違いはかなり理解しやすくなります。
私自身、以前は「Dataplane V2=Cilium=eBPF」くらいの粒度で捉えていましたが、今回調べる中で、それだけでは運用設計には足りないことがよく分かりました。
特にGKEを運用している方には、性能だけではなく、移行制約やanetd、Service mapの上限まで含めて一度確認しておくことをおすすめします。
Kubernetesのネットワークで何か問題が起きたときに、「とりあえずCNIを見る」のではなく、「いま問題になっているのはどのレイヤーなのか」を切り分ける。そのための整理として、この記事が役立てばうれしいです。
参照ソース (References)
-
Kubernetes
- Network Plugins: https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/
- NFTables mode for kube-proxy: https://kubernetes.io/blog/2025/02/28/nftables-kube-proxy/
-
Flannel
- Network Policy Controller: https://github.com/flannel-io/flannel/blob/master/Documentation/netpol.md
-
Calico
- Overlay networking: https://docs.tigera.io/calico/latest/networking/configuring/vxlan-ipip
- eBPF data plane: https://docs.tigera.io/calico/latest/operations/ebpf/enabling-ebpf
-
Cilium
- kube-proxy replacement: https://docs.cilium.io/en/stable/network/kubernetes/kubeproxy-free/
- L7 Network Policy: https://docs.cilium.io/en/stable/security/policy/layer7/
- DNS / FQDN Policy: https://docs.cilium.io/en/stable/security/dns/
- System Requirements: https://docs.cilium.io/en/stable/operations/system_requirements/
-
Amazon EKS / AWS VPC CNI
- Amazon VPC CNI: https://docs.aws.amazon.com/eks/latest/userguide/managing-vpc-cni.html
- Prefix Mode for Linux: https://docs.aws.amazon.com/eks/latest/best-practices/prefix-mode-linux.html
- Security Groups for Pods: https://docs.aws.amazon.com/eks/latest/userguide/security-groups-pods-deployment.html
-
Azure Kubernetes Service / Azure CNI
- Azure CNI networking overview: https://learn.microsoft.com/en-us/azure/aks/concepts-network-cni-overview
- Azure CNI Overlay: https://learn.microsoft.com/en-us/azure/aks/concepts-network-azure-cni-overlay
- Azure CNI Powered by Cilium: https://learn.microsoft.com/en-us/azure/aks/azure-cni-powered-by-cilium
-
Google Kubernetes Engine / GKE Dataplane V2
- GKE Dataplane V2: https://cloud.google.com/kubernetes-engine/docs/concepts/dataplane-v2
- GKE Dataplane V2 troubleshooting: https://cloud.google.com/kubernetes-engine/docs/how-to/dataplane-v2
- VPC-native clusters / Alias IP: https://cloud.google.com/kubernetes-engine/docs/concepts/alias-ips
- GKE Release Notes: https://cloud.google.com/kubernetes-engine/docs/release-notes-new-features