Cilium on Ubuntu K8s — eBPFベースのCNIプラグインとネットワークポリシー

Kubernetes

この記事のポイント

  • Cilium は Linux eBPF を使い、iptables ではなくカーネルレベルでパケットを制御する CNI プラグインです
  • Ubuntu 24.04 + kind(Kubernetes in Docker)で Cilium v1.17.4 を Helm でインストールし、実際に動作を確認しました
  • CiliumNetworkPolicy を適用すると、eBPF マップにポリシーが書き込まれ、cilium bpf policy list でパケット数まで確認できます
  • Hubble UI(可視化ダッシュボード)を port-forward で起動し、フロー観測ができます
  • 本記事のすべてのコマンド出力は Ubuntu 24.04.4 LTS 上で 2026-06-20 に実測しています

Kubernetes のネットワーク周りで「CNI って何?」「Cilium を試してみたいけど難しそう」と感じている方に向けて書きました。

Cilium の大きな特徴は eBPF(extended Berkeley Packet Filter) を使っている点で、従来の iptables ベースの CNI と仕組みが根本的に違います。実際にインストールして動かしてみないと感覚がつかみにくいので、この記事では Ubuntu 24.04 + kind(Kubernetes in Docker)を使って一から手を動かします。

eBPF ポリシーの適用確認(cilium bpf policy list でパケットカウントまで見える)と、Hubble UI のスクリーンショットも載せています。

動作確認済み環境

  • OS:Ubuntu 24.04.4 LTS(Noble Numbat)
  • カーネル:6.8.0-83-generic
  • Docker:29.5.3
  • kind:v0.24.0 / Kubernetes v1.31.0
  • Cilium:v1.17.4(Helm chart 1.17.4)
  • cilium-cli:v0.19.4
  • 検証日:2026-06-20
Ubuntu 24.04.4 LTS 実行環境(実測)
Ubuntu 24.04.4 LTS 実行環境(実測)

CNI と Cilium の基本を5分でおさらい

Kubernetes では Pod 間の通信を担う「CNI(Container Network Interface)プラグイン」が必須です。代表的なものに Flannel・Calico・kindnet などがあり、どれも iptables ルールを積み上げて通信を制御していました。ノードが増え Pod 数が増えると iptables テーブルが肥大化し、ルール追加のたびにカーネルへのロックが走る——これが大規模クラスタで問題になってきました。

Cilium はこの問題を eBPF で解決するアプローチです。eBPF は Linux 5.x 以降(Ubuntu 22.04 以上)でまともに使えるようになったカーネル技術で、カーネルコードを書き換えずにネットワーク処理をカーネル内に「注入」できます。iptables を介さずパケットを処理するため、ルール追加のコストが桁違いに小さくなります。

加えて Cilium には Hubble(可視化・監視レイヤー)が付属しており、Pod 間のネットワークフローをリアルタイムで見られる UI も使えます。

前提:ツールのインストール

Ubuntu 24.04 の環境で以下の3つをインストールします。手元にすでに動いている Kubernetes クラスタがあれば kind は不要です。

手順1:kubectl をインストールする




ubuntu@linuxlab: ~
$ curl -LO “https://dl.k8s.io/release/$(curl -Ls https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl”
$ chmod +x kubectl && sudo mv kubectl /usr/local/bin/
$ kubectl version –client
Client Version: v1.36.2

手順2:kind をインストールする




ubuntu@linuxlab: ~
$ curl -Lo kind https://kind.sigs.k8s.io/dl/v0.24.0/kind-linux-amd64
$ chmod +x kind && sudo mv kind /usr/local/bin/
$ kind version
kind v0.24.0 go1.22.6 linux/amd64

手順3:cilium-cli と Helm をインストールする




ubuntu@linuxlab: ~
$ CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
$ curl -L “https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-amd64.tar.gz” | tar xz
$ sudo mv cilium /usr/local/bin/
$ cilium version –client
cilium-cli: v0.19.4 compiled with go1.26.3 on linux/amd64
$ curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

kind クラスタを作成する

kind でシングルノードのクラスタを作ります。ここでは kindnet(kind のデフォルト CNI)を有効にしたまま Cilium を追加インストールします。CNI を完全に置き換える構成(disableDefaultCNI: true)も可能ですが、このホスト環境では kube-proxy が起動しきらない問題があったため、Helm の k8sServiceHost/k8sServicePort オプションで API サーバーを直指定する方法を採りました。




ubuntu@linuxlab: ~
$ kind create cluster –name cilium-demo
✓ Ensuring node image (kindest/node:v1.31.0)
✓ Preparing nodes
✓ Starting control-plane
✓ Installing CNI
Set kubectl context to “kind-cilium-demo”
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
cilium-demo-control-plane Ready control-plane 24s v1.31.0

Cilium を Helm でインストールする

Cilium の公式 Helm リポジトリを追加して v1.17.4 をインストールします。hubble.relay.enabled=truehubble.ui.enabled=true を付けることで、Hubble UI もまとめてデプロイされます。

Cilium v1.17.4 インストールログ(実測)
Cilium v1.17.4 インストールログ(実測)



ubuntu@linuxlab: ~
$ helm repo add cilium https://helm.cilium.io/ && helm repo update
$ CONTROL_PLANE_IP=$(docker inspect cilium-demo-control-plane –format ‘{{.NetworkSettings.Networks.kind.IPAddress}}’)
$ helm install cilium cilium/cilium \
–version 1.17.4 \
–namespace kube-system \
–set ipam.mode=kubernetes \
–set hubble.relay.enabled=true \
–set hubble.ui.enabled=true \
–set k8sServiceHost=”${CONTROL_PLANE_IP}” \
–set k8sServicePort=6443
NAME: cilium STATUS: deployed REVISION: 1
You have successfully installed Cilium with Hubble Relay and Hubble UI.

ポイント:k8sServiceHost を指定する理由

Cilium の init コンテナはクラスタ内サービス IP(10.96.0.1)経由で API サーバーに接続しようとします。kube-proxy が正常動作していない環境では、このサービス IP への経路が張られておらず接続タイムアウトが発生します。k8sServiceHost に control-plane ノードの実 IP を渡すことで回避できます。

起動確認

インストール後、cilium status で稼働状況を確認します。私の環境では cilium-agent と Hubble UI が約2分で起動しました。




ubuntu@linuxlab: ~
$ cilium status
DaemonSet cilium Desired: 1, Ready: 1/1, Available: 1/1
DaemonSet cilium-envoy Desired: 1, Ready: 1/1, Available: 1/1
Deployment cilium-operator Desired: 2, Ready: 1/2
Deployment hubble-ui Desired: 1, Ready: 1/1, Available: 1/1
Helm chart version: 1.17.4
cilium status 実測結果
cilium status 実測結果

Hubble UI でフローを可視化する

Hubble は Cilium に組み込まれた可視化エンジンで、Pod 間のネットワークフローをリアルタイムに観測できます。起動後は kubectl port-forward でローカルに転送してブラウザから確認します。




ubuntu@linuxlab: ~
$ kubectl port-forward -n kube-system svc/hubble-ui 12000:80
Forwarding from 127.0.0.1:12000 -> 8081
# ブラウザで http://localhost:12000/ を開く
Hubble UI メイン画面(実測スクリーンショット)
Hubble UI メイン画面(実測スクリーンショット)

Hubble UI を開くと namespace のドロップダウンが表示されます。Pod 間の通信をグラフで俯瞰できます。フロー観測は Hubble Relay 経由になるため、Relay の起動も必要です(cilium hubble enable または Helm の hubble.relay.enabled=true)。

Hubble UI フロービュー(実測スクリーンショット)
Hubble UI フロービュー(実測スクリーンショット)

CiliumNetworkPolicy でアクセス制御する

Cilium の最大の特徴が CiliumNetworkPolicy(CNP)です。通常の Kubernetes NetworkPolicy とほぼ同じ書き方ですが、L7(HTTP メソッドやパスレベル)のフィルタや DNS ベースのルールも書けます。

手順1:テスト Pod をデプロイする




ubuntu@linuxlab: ~
$ kubectl create namespace demo
$ kubectl run web-server -n demo –image=nginx:alpine –labels=app=web
$ kubectl run client-pod -n demo –image=curlimages/curl –labels=app=client \
— sh -c “sleep 3600”
$ kubectl expose pod web-server -n demo –port=80 –name=web-service
$ kubectl get pods -n demo
NAME READY STATUS RESTARTS AGE
client-pod 1/1 Running 0 30s
web-server 1/1 Running 0 30s

手順2:CiliumNetworkPolicy を適用する

次の YAML は「demo namespace 内の app=web という Pod へのアクセスを、app=client ラベルを持つ Pod からの port 80 のみ許可する」ポリシーです。




ubuntu@linuxlab: ~ (cilium-netpol.yaml)
apiVersion: “cilium.io/v2”
kind: CiliumNetworkPolicy
metadata:
name: allow-client-to-web
namespace: demo
spec:
endpointSelector:
matchLabels:
app: web # このPodへの通信を制御
ingress:
– fromEndpoints:
– matchLabels:
app: client # app=client からのみ許可
toPorts:
– ports:
– port: “80”
protocol: TCP



ubuntu@linuxlab: ~
$ kubectl apply -f cilium-netpol.yaml
ciliumnetworkpolicy.cilium.io/allow-client-to-web created
$ kubectl get cnp -n demo
NAME AGE VALID
allow-client-to-web 5s True

手順3:eBPF ポリシーマップを直接確認する

ここが Cilium の面白いところです。ポリシーを適用すると iptables ルールではなく eBPF マップ に書き込まれます。cilium bpf policy list コマンドで、エンドポイント単位のポリシーを低レイヤーで確認できます。

CiliumNetworkPolicy 適用とeBPFポリシー確認(実測)
CiliumNetworkPolicy 適用とeBPFポリシー確認(実測)



ubuntu@linuxlab: ~
$ kubectl exec -n kube-system cilium-7fcpv — cilium bpf policy list 578
Endpoint ID: 578 (app=web)
POLICY DIRECTION LABELS PORT/PROTO BYTES PACKETS
Allow Ingress k8s:app=client 80/TCP 546 7
k8s:namespace=demo
$ kubectl exec -n demo client-pod — curl -s -o /dev/null \
-w ‘%{http_code}’ http://10.96.15.165/ –connect-timeout 5
200

BYTES: 546 / PACKETS: 7 というカウンタが実際に通過したパケット数です。iptables の場合は「ルールの一致件数」を iptables -nvL で見ますが、Cilium は eBPF マップを直接確認するためより精度の高い観測ができます。

コンポーネントバージョン一覧(実測)

Ciliumコンポーネントバージョン一覧(実測)
Ciliumコンポーネントバージョン一覧(実測)
コンポーネント バージョン 役割 状態(実測)
cilium-agent v1.17.4 各ノードで eBPF プログラムを管理 Running 1/1
cilium-envoy v1.32.6 L7 プロキシ(HTTP/gRPC フィルタ用) Running 1/1
cilium-operator v1.17.4 CRD 管理・IPAM 制御 Running 1/2
hubble-ui v0.13.2 フロー可視化 UI(nginx + React) Running 1/1
hubble-relay v1.17.4 Hubble gRPC 集約ハブ Running

よくあるエラーと解決策

①「cilium init container: i/o timeout」

Cilium の init コンテナがクラスタ内のサービス IP(10.96.0.1:443)に接続できない場合に発生します。kube-proxy の問題や、CNI なしクラスタでのサービス IP 未設定が原因のことが多いです。Helm インストール時に --set k8sServiceHost=<control-plane-IP> --set k8sServicePort=6443 を追加すると回避できます。

②「too many open files」(kubelet/kube-proxy)

コンテナ環境(kind 内の kind ネスト)で起きやすいカーネルリソース上限の問題です。ホスト側の /proc/sys/fs/file-max を増やすか、単ノードで試すと解消します。

③「ciliumnetworkpolicy.cilium.io not found」

Cilium Operator が CRD を登録する前に YAML を apply しようとすると出ます。cilium status で Operator が Ready になってから適用してください。

まとめ

Cilium は eBPF をフル活用した CNI プラグインで、iptables を使わずにカーネル内でパケット処理するのが最大の特徴です。Ubuntu 24.04 + kind 環境で実際に動かすと、cilium bpf policy list コマンドで eBPF マップのパケットカウンタを直に確認できて、「iptables とは別物だ」という感触がつかめます。

  • Helm でのインストールは helm install cilium cilium/cilium --version 1.17.4 一発(Hubble UI も同時にデプロイ可能)
  • CiliumNetworkPolicy は標準 NetworkPolicy と互換性があり、L7 フィルタや DNS ポリシーも書ける
  • Hubble UI(port-forward で http://localhost:12000/)でフローをリアルタイム可視化できる
  • 本番クラスタへの導入は Cilium 公式の「Installation Guide」を参照。kube-proxy 置き換えや BPFマスカレードなど追加の設定が必要です
著者アイコン
著者アイコン

正直、cilium bpf policy list でパケットカウンタが見えたときは面白かったです。iptables の世界ではこの粒度の可視化は難しい。大規模クラスタで本気で使うなら Hubble Relay 込みの構成を検討する価値があります。

より本格的な Kubernetes 運用をするなら、クラウド VPS での環境構築もご検討ください。

VPS 選びで迷ったら、こちらの比較記事も参考にしてください:https://linuxlab.jp/ubuntu-server-setup/

コメント

タイトルとURLをコピーしました