こんにちは!クラウドインフラとSREの世界へようこそ。
Kubernetes(k8s)を学び始めると、避けて通れないのが「コンテナ同士がどうやって通信しているのか?」というネットワークの仕組みです。そして、多くの人が「`kube-proxy`」や「`iptables`」という言葉の複雑さに一度は頭を抱えます。
「設定が難しそう…」「なぜかパフォーマンスが出ない…」「障害が起きた時に中身がブラックボックスで見えない…」
そんな悩みを根本から解決し、k8sネットワークの未来を切り拓いているのがeBPF(Extended Berkeley Packet Filter)であり、それを駆使した次世代CNIプラグインCilium(シリウム)です。
この記事では、インフラの最前線で培った知見をギュッと凝縮し、初心者の方でも絶対に挫折しないよう、概念から実践まで丁寧に導いていきます。これをマスターすれば、あなたのk8s運用の負荷は劇的に軽くなり、セキュリティと可視化のレベルが別次元に引き上がりますよ。
一緒にステップ・バイ・ステップで進めていきましょう!
—
1. 従来のiptables方式の限界と、eBPFという革命
まずは「なぜ今、従来の仕組みを変える必要があるのか?」という疑問から紐解いていきましょう。
従来の`kube-proxy`(iptablesモード)の限界
k8sの標準的なネットワークでは、Service宛ての通信をPodへ振り分けるロードバランシングにLinuxの`iptables`という仕組みが使われてきました。
しかし、`iptables`は本来「ファイアウォール」として作られた古くからの仕組みです。ServiceやPodの数が増えると、以下のような深刻な課題が発生します。
1. 計算量の爆発($O(N)$の課題):
`iptables`はルールを上から順番に評価します。Serviceが1,000個、2,000個と増えると、ルール数が数万件に達し、パケット処理の遅延(レイテンシ)が目に見えて悪化します。
2. CPU負荷とルールの更新遅延:
Podが1つ追加・削除されるたびに、カーネル内の全ルールテーブルを再構築して書き換える必要があります。大規模環境ではこれだけでノードのCPUが高負荷になります。
eBPF(Extended Berkeley Packet Filter)とは?
この問題を解決する救世主がeBPFです。
eBPFを一言で言うなら、「Linuxカーネルを改造することなく、カーネル内部で安全に独自のカスタムコード(プログラム)を高速実行できる技術」です。
【従来のiptables】
[ パケット到着 ] ➔ [ ルール1 ] ➔ [ ルール2 ] ➔ … ➔ [ ルール10,000 ] (遅い…)
【eBPF (Cilium)】
[ パケット到着 ] ➔ [ eBPFプログラム (ハッシュテーブル参照: O(1)) ] ➔ [ 目的のPodへ直行 ] (爆速!)
eBPFを使えば、パケットがLinuxカーネルに入ってきた瞬間にハッシュテーブルを使って一瞬で宛先(Pod)を特定できます。Serviceがいくつ増えても処理時間は一定($O(1)$)。しかもカーネル空間で処理が完結するため、無駄なコンテキストスイッチが発生しません。
Ciliumは、このeBPF技術をフル活用してk8sネットワークを爆速にし、さらに強固なセキュリティとリアルタイム可視化を提供するオープンソースソフトウェアです。
—
2. 実践!Ciliumを導入してkube-proxyを完全置き換え(No kube-proxy)
論より証拠です!ローカル環境(`kind`)を使って、`kube-proxy`を完全に排除し、Ciliumのみで動く「完全eBPF駆動のk8sクラスタ」を構築してみましょう。
前置準備:Kindクラスタの作成
まず、`kube-proxy`と標準CNIを無効化したKindクラスタを準備します。
以下の内容で `kind-config.yaml` を作成してください。
kind-config.yaml
kube-proxyとデフォルトCNIを無効化した純粋なクラスタを作成する設定
apiVersion: kind.x-k8s.io/v1alpha4
kind: Cluster
networking:
disableDefaultCNI: true # 標準のFlannel等のCNIを無効化
kubeProxyMode: “none” # kube-proxyを完全に無効化!
nodes:
- role: control-plane
- role: worker
- role: worker
次のコマンドでクラスタを起動します。
kind create cluster –name cilium-demo –config kind-config.yaml
この時点ではCNIが存在しないため、ノードは `NotReady` ステータスになりますが、正常な動作です。
Helmを使ってCiliumをインストール
次に、Ciliumをインストールします。ここでは `kubeProxyReplacement=true` オプションを渡し、`kube-proxy` の役割(Serviceのロードバランシング等)をすべてCiliumのeBPFプログラムに任せます。
Helmリポジトリの追加と更新
helm repo add cilium https://helm.cilium.io/
helm repo update
Ciliumのインストール(kube-proxy完全置き換えモード)
helm install cilium cilium/cilium –version 1.14.5 \
–namespace kube-system \
–set kubeProxyReplacement=true \
–set k8sServiceHost=cilium-demo-control-plane \
–set k8sServicePort=6443
動作確認(HelloWorld)
インストール完了後、Cilium CLI(またはkubectl)を使って状態を確認してみましょう。
CiliumのポッドがすべてRunningになるまで待ちます
kubectl get pods -n kube-system -w
Cilium CLIをインストールしている場合は、以下のコマンドでeBPFによる`kube-proxy`置き換えが成功しているか一目瞭然で確認できます。
cilium status
出力結果の中に、以下のような表示があれば大成功です!
Status: OK
KubeProxyReplacement: Strict [ebpf] # <-- eBPFがkube-proxyを完全代替している証拠!
`kube-proxy`のPodを一切起動することなく、NodePortやClusterIPなどのk8s Service機能が完全にeBPF上で動作しています。素晴らしいですね!
---
3. L7セキュリティポリシーとHubbleによるリアルタイム可視化
Ciliumの真価は、単なる高速化だけに留まりません。従来のk8sでは難しかった「L7(アプリケーション層)の制御」と「通信の完全可視化(Hubble)」が標準で手に入ります。
① L7レイヤー(HTTPレベル)のネットワークポリシー
通常のk8s `NetworkPolicy` はIPアドレスやポート番号(L3/L4)までしか制御できませんでした。しかしCiliumなら「`GET /public` は許可するが、`POST /admin` は拒否する」といった高度なセキュリティ制御が書けます。
実験用に、簡単な通信テスト用環境を作ってみましょう。
app-demo.yaml
テスト用のWebAPI(Backend)とクライアント(Client)をデプロイ
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-backend
spec:
replicas: 1
selector:
matchLabels:
app: my-backend
template:
metadata:
labels:
app: my-backend
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
—
apiVersion: v1
kind: Service
metadata:
name: my-backend-svc
spec:
selector:
app: my-backend
ports:
- port: 80
targetPort: 80
—
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-client
spec:
replicas: 1
selector:
matchLabels:
app: my-client
template:
metadata:
labels:
app: my-client
spec:
containers:
- name: curl
image: curlimages/curl
command: [“sleep”, “3600”]
適用します。
kubectl apply -f app-demo.yaml
次に、「ClientからBackendへのアクセスは HTTP GET パス `/` のみ許可する」 というCilium専用のL7ポリシーを適用します。
l7-policy.yaml
apiVersion: “cilium.io/v2”
kind: CiliumNetworkPolicy
metadata:
name: limit-http-route
spec:
endpointSelector:
matchLabels:
app: my-backend # 対象のBackendを指定
ingress:
- fromEndpoints:
- matchLabels:
app: my-client # Clientからの通信を制限
toPorts:
- ports:
- port: “80”
protocol: TCP
rules:
http: # L7 (HTTP) ルールを定義
- method: “GET”
path: “/$” # トップページのみ許可
これを適用してみましょう。
kubectl apply -f l7-policy.yaml
通信テスト
Clientポッドからリクエストを送って挙動を確認します。
CLIENT_POD=$(kubectl get pod -l app=my-client -o jsonpath='{.items[0].metadata.name}’)
1. 許可されたパス (GET /) ➔ 200 OK が返る!
kubectl exec $CLIENT_POD — curl -s -o /dev/null -w “%{http_code}\n” http://my-backend-svc/
出力: 200
2. 許可されていないパス (GET /admin) ➔ CiliumがL7で遮断(403 Access Denied)!
kubectl exec $CLIENT_POD — curl -s -o /dev/null -w “%{http_code}\n” http://my-backend-svc/admin
出力: 403
IPやポートレベルではなく、HTTPのリクエスト内容を見てカーネルレベル(eBPF)で瞬時にブロックしてくれました。これがCiliumの強力なセキュリティ機能です。
—
② Hubbleを使ったリアルタイム通信の可視化
「どのPodとどのPodが、どんなHTTPステータスで通信しているか」を可視化ツールHubble(ハブル)で見てみましょう。
CiliumにHubble機能を有効化します。
helm upgrade cilium cilium/cilium –version 1.14.5 \
–namespace kube-system \
–reuse-values \
–set hubble.enabled=true \
–set hubble.ui.enabled=true
Hubble UI(グラフィカルなWeb画面)にアクセスするためのポートフォワードを行います。
cilium hubble ui
ブラウザで `http://localhost:12000` を開いてみてください。
そこには、あなたのクラスタ内で飛び交うパケットがリアルタイムで美しくフロー図として描かれ、先ほどブロックされた `403 Access Denied` の通信が赤くハイライトされているはずです!
ブラウザを使わなくても、CLIから直接ネットワークフローを監視することも可能です。
Hubble CLIを使ったリアルタイム通信ログのストリーミング
cilium hubble observe –path /admin
パケットキャプチャ(tcpdump)を苦労して仕込む時代は終わりました。CiliumとHubbleを使えば、クラスタ内の全ての通信が最初から可視化されているのです。
—
4. まとめ:次世代のKubernetes運用へ
お疲れ様でした!今回のハンズオンで体験した内容を振り返ってみましょう。
1. eBPFの優位性: 従来の `iptables` による遅延をなくし、計算量 $O(1)$ の超爆速なロードバランシングを実現。
2. kube-proxy完全脱却: `kubeProxyReplacement=true` で、シンプルかつ高性能なインフラを構築。
3. 高度なL7セキュリティ: アプリケーション層に踏み込んだきめ細やかな `CiliumNetworkPolicy` の設定。
4. Hubbleによる可視化: ネットワークのブラックボックス化を解消し、障害解析を一瞬にするオブザーバビリティの獲得。
一見難しそうに見えるeBPFやCiliumですが、一度仕組みを理解して導入してしまえば、「これなしでのk8s運用は考えられない」と思えるほど強力なツールです。
これをマスターすれば、毎日のインフラ構築や障害対応、セキュリティ設計が劇的に楽になり、自信を持って大きな規模のクラスタを運用できるようになりますよ!
ぜひご自身の開発環境やテスト環境で色々触って、その圧倒的なパワーを実感してみてくださいね。応援しています!