CiliumとeBPFで進化するKubernetesネットワーク:kube-proxy置き換えのメリットと高度なセキュリティ可視化
こんにちは。テックリードの私だ。
日々のKubernetes運用で、こんな悪夢にうなされていないだろうか?
「クラスタの規模が数千ノードを超えた途端、`iptables`のルール更新がCPUを焼き尽くし、Pod間の通信レイテンシーがスパイクする」
「セキュリティ監査から『L7レベルでの外向き通信制御と、その完全な監査ログを出せ』と言われたが、サイドカープロキシだらけになってメモリが枯渇する」
もし心当たりがあるなら、そろそろ従来のネットワークスタックを捨てる時期だ。
今回は、eBPF(Extended Berkeley Packet Filter)とCiliumを組み合わせ、`kube-proxy`を完全に駆逐して「真のモダンインフラ」を構築する極限の知見を授けよう。
—
1. 従来の `iptables` 方式の限界と eBPF のパラダイムシフト
`iptables` / `IPVS` が抱える構造的負債
これまでのKubernetesは、Serviceへのトラフィック負荷分散やネットワークポリシーの強制を `kube-proxy`(`iptables` または `IPVS` モード)に依存してきた。
だが、考えてみてほしい。`iptables` はパケットが流れるたびに、カーネル空間内の巨大なルールチェーンを線形探索する。クラスタ内のServiceやPodが増え、ルールが数万件に達するとどうなるか?
- パケット処理のCPUコスト(CPUサイクルの無駄遣い)が跳ね上がる。
- ネットワークポリシーの適用とルーティングの整合性を保つために、ユーザースペースとカーネル間で無駄なコンテキストスイッチが発生する。
eBPFがもたらす「カーネルのプログラミング」
eBPFは、Linuxカーネルのソースコードを書き換えることなく、安全なサンドボックス化されたプログラムをカーネル内で直接実行する技術だ。
Ciliumは、このeBPFをフル活用し、ネットワークパケットのフックポイント(TC: Traffic ControlやXDP: eXpress Data Pathなど)に直接プログラムをアタッチする。
これにより、`iptables` や `kube-proxy` を完全にバイパスし、ソケットレイヤー(sockops)やネットワークドライバ層で直接ルーティングとポリシー判定を行うことが可能になる。結果として、圧倒的なスループットの向上とレイテンシーの劇的な削減が達成される。
—
2. Cilium導入:kube-proxy完全置き換えの実践
ここからが本番だ。妥協のないプロダクション環境を想定し、`kube-proxy` を完全に排除したCiliumのデプロイメント構成を解説する。
前提条件
- Linux Kernel 5.10以上(できれば 5.15+ 推奨。eBPFマップの効率やBTFサポートのため)
- `kube-proxy` の無効化(Kubeadm等であれば `–skip-phases=addon/kube-proxy`、または既存クラスタからの削除が必要)
実用的な Helm Values(`values.yaml`)
チーム開発でインフラの再現性と冪等性を担保するため、Helmを用いた宣言的管理を行う。以下の設定は、`kube-proxy` を完全に排除し、ネイティブ・ルーティングとネイティブなIPAM(IP Address Management)を行うためのベストプラクティスだ。
チーム共通で利用する Cilium のプロダクション向け設定
cluster:
name: production-k8s-cluster-01
id: 1
kube-proxyの完全置き換えを宣言
kubeProxyReplacement: “strict”
eBPFベースのホストルーティングを有効化
bpf:
masquerade: true
# ソケットレイヤーでのロードバランスを有効化し、レイテンシーを極限まで削る
socketLoadbalancing: true
ネイティブなルーティング(クラウドプロバイダのCNI機能やDirect Routingを使用する場合)
tunnel: “disabled”
autoDirectNodeRoutes: true
IPAM設定 (Kubernetes標準のNode IPAM、またはCilium独自のCRDベースIPAM)
ipam:
mode: “kubernetes”
Hubble (可視化・監視コンポーネント) の有効化
hubble:
enabled: true
relay:
enabled: true
ui:
enabled: true
metrics:
enabled:
- “dns:query”
- “drop”
- “tcp”
- “flow”
- “http”
監視・メトリクス公開用設定
prometheus:
enabled: true
serviceMonitor:
enabled: true
ログ出力レベル
logOptions:
format: “json”
デプロイメント手順(ArgoCD等でのGitOps前提)
手動オペレーションはヒューマンエラーの温床だ。以下のようにHelmコマンド、またはArgoCDのApplicationマニフェストとして組み込む。
公式リポジトリの追加
helm repo add cilium https://helm.cilium.io/
helm repo update
宣言的設定を用いたインストール
helm upgrade –install cilium cilium/cilium \
–version 1.14.5 \
–namespace kube-system \
-f values.yaml
`kubeProxyReplacement: “strict”` を指定することで、Ciliumは `kube-proxy` がなくてもクラスタ内のすべてのServiceルーティングを自律的にハンドリングする。
—
3. L7レイヤーのネットワークポリシーと Hubble による可視化
従来のネットワークポリシー(NetworkPolicy)は、L3/L4(IPアドレスとポート番号)の制御に限定されていた。「特定のPodから、外部APIの特定のパス(例: `/v1/users`)以外へのアクセスを禁止したい」といった要件を満たすには、Envoyなどのサイドカーを個別に挟むしかなかった。
しかし、Ciliumは eBPFと統合されたL7プロキシ(Envoy) をネイティブで内包している。サイドカーをアプリケーションPodに注入する必要はない。
L7ポリシーの実践例:HTTPメソッドとパスの制限
以下のCiliumNetworkPolicyは、`frontend` というラベルを持つPodから、外部の決済API(`payment-service`)への通信のうち、`POST /pay` 以外のリクエストを厳格にブロックする設定だ。
apiVersion: “cilium.io/v2”
kind: “CiliumNetworkPolicy”
metasata:
name: “secure-payment-policy”
namespace: “production”
spec:
endpointSelector:
matchLabels:
app: “frontend”
egress:
- toEndpoints:
- matchLabels:
app: “payment-service”
toPorts:
- ports:
- port: “443”
protocol: “TCP”
# L7レイヤー(HTTP)のインスペクションを有効化
layer7:
http:
- method: “POST”
path: “/pay”
この設定により、カーネルレベルでパケットをキャッチし、L7のペイロードを解析した上で安全にフィルタリングが行われる。アプリケーションの変更やサイドカーのメモリオーバヘッドは一切不要だ。
—
Hubble によるリアルタイム可視化とデバッグ
ネットワークポリシーを適用した際、「なぜこの通信がドロップされたのか?」を瞬時に特定できなければ、SRE失格だ。ここで Hubble が真価を発揮する。
Hubble CLIの活用と隠れた便利コマンド
ローカル環境のターミナルから、クラスタ内のトラフィックをリアルタイムで覗き見するための必須コマンドを伝授する。
.1
ポートフォワードをバックグラウンドで張る(またはKubeLens等のGUIを使う)
cilium hubble port-forward &
【神コマンド1】ドロップされたパケットをリアルタイムで監視(原因特定に最適)
hubble observe –type drop –follow
【神コマンド2】特定のNamespace間で行われているHTTP通信をL7パースして表示
hubble observe –namespace production –protocol http –follow
【神コマンド3】フローの統計情報を視覚的に確認
hubble observe –from-pod frontend-xyz –to-service payment-service –output json
HubbleのUI(Webブラウザ)を有効化していれば、サービス間の依存関係グラフ(Service Map)がリアルタイムで描画される。どのマイクロサービスがどのエンドポイントと通信し、どこでドロップが発生しているのかが、視覚的かつ一目瞭然で把握できる。
—
プロからの実践アドバイス:チーム開発における運用ルール
1. Kernelのバージョンの統一
eBPFの機能(特にCO-RE: Compile Once – Run Everywhere)によりカーネル互換性は劇的に向上したが、ノード間でLinux Kernelのバージョンがバラバラな状態は避けること。マネージドKubernetes(EKS, GKE, AKS)を使用する場合も、ノードAMI/OSイメージのバージョン固定を強く推奨する。
2. NetworkPolicyのドライラン(Audit mode)の活用
本番環境に突然L7ポリシーを適用すると、既存の通信を破壊して障害を引き起こす恐れがある。最初は `enforcementMode: disabled`(またはAuditモード)でデプロイし、Hubbleのログで「拒否されるはずだった通信」が正しく検知されることを確認してから厳格な適用(Enforce)に移行せよ。
まとめ
`kube-proxy` をCiliumとeBPFに置き換えることは、単なる「流行りの技術の導入」ではない。それは、Kubernetesインフラのパフォーマンス、セキュリティ、そして可観測性を次の次元へ引き上げるための必然の投資だ。
カーネルの深淵を理解したSREとして、今すぐ古い `iptables` の呪縛からクラスタを解放しよう。あなたの手元で動くそのパケットは、もう誰にも止められない。