K8s Cilium eBPFネットワークポリシー実践:ゼロトラストPodセキュリティの5つのコアパターン

技术架构

2026年のKubernetesネットワークはeBPF時代に完全に移行しました。CNCF卒業プロジェクトであるCiliumは、カーネルレベルのプログラマブルネットワーク機能により、ゼロトラストPodセキュリティの事実上の標準となっています。従来のiptablesからeBPFデータプレーンへ、L3/L4ネットワークポリシーからL7アプリケーション層フィルタリングへ、単一クラスタからCluster Meshマルチクラスタネットワークへ——Ciliumはクラウドネイティブネットワークの境界を再定義しています。本記事では5つのコア実践パターンを深く掘り下げ、インストールから本番運用まで、Cilium eBPFネットワークポリシーを完全にマスターします。

コア概念

概念 説明 従来手法との比較
eBPF カーネルプログラマブルサンドボックス、カーネルソースを変更せずにネットワーク機能を拡張 iptablesルールチェーン、ルール増加時にO(n)マッチング
Cilium eBPFベースのK8s CNIプラグイン、ネットワーク・セキュリティ・オブザーバビリティを提供 Calico/Flannel、L3/L4ポリシーのみ
アイデンティティラベル IPアドレスではなくLabelに基づくセキュリティアイデンティティ IPベースのNetworkPolicy
L7ポリシー HTTP/gRPCアプリケーション層フィルタリング、APIパスまで精密制御 L4ポートレベルのフィルタリングのみ
Cluster Mesh マルチクラスタネットワーク相互接続、クラスタ間Pod直接通信 VPN/ゲートウェイ転送
Hubble Ciliumネットワークオブザーバビリティプラットフォーム、リアルタイムトラフィック可視化 tcpdump/Wiresharkの手動パケットキャプチャ

問題分析:従来のK8sネットワークポリシーの5つの課題

課題1:iptablesパフォーマンスのボトルネック——大規模クラスターではiptablesルール数が数万に達し、ルール変更のたびに全量置換が発生し、ネットワーク遅延のジッターが深刻化。

課題2:L3/L4ポリシーの粒度不足——ネイティブNetworkPolicyはポートレベルのアクセス制御しかできず、GET /api/usersDELETE /api/usersを区別できない。

課題3:IPベースのセキュリティポリシーの脆弱性——Pod再作成後にIPが変化し、IPベースのファイアウォールルールが即座に無効化、ゼロトラストが不可能に。

課題4:マルチクラスタネットワークの分断——クラスタ間サービス通信がIngress/ゲートウェイ転送に依存し、遅延が高く、ポリシーの統一が困難。

課題5:ネットワーク障害調査のブラックボックス——Pod間通信障害はtcpdumpでホップバイホップで調査するしかなく、エンドツーエンドのトラフィック可視化がない。

パターン1:Cilium基本インストールとeBPFネットワーク原理

eBPFネットワーク原理

eBPFプログラムはカーネルネットワークフック(xdp、tc、cgroup等)にアタッチされ、パケットがプロトコルスタックに到達する前に処理を完了し、iptablesのルールチェーン走査オーバーヘッドを回避します:

パケット受信 → XDP(eBPF) → tc ingress(eBPF) → プロトコルスタック → tc egress(eBPF) → 送信
                   ↓              ↓                              ↓
             DDoS防御       ポリシーマッチ/ルーティング        ポリシーマッチ/NAT

Helmインストール(kube-proxy置き換え)

# cilium-values.yaml
# Cilium Helmインストール設定、kube-proxy置き換えモード
kubeProxyReplacement: true
operator:
  replicas: 2

# eBPFマップサイズ(大規模クラスタチューニング)
bpf:
  mapDynamicSizeRatio: 0.0025
  lbMapMax: 65536
  ctMapMax: 524288

# ノードネットワーク自動検出
autoDirectNodeRoutes: true
tunnel: vxlan

# アイデンティティ割り当てモード
identityAllocationMode: kvstore

# モニタリングとオブザーバビリティ
hubble:
  enabled: true
  listenAddress: ":4244"
  metrics:
    enabled:
      - dns
      - drop
      - tcp
      - flow
      - port-distribution
      - http
  relay:
    enabled: true
    replicas: 2
  ui:
    enabled: true

# リソース制限
resources:
  requests:
    cpu: 200m
    memory: 256Mi
  limits:
    cpu: "1"
    memory: 1Gi

# セキュリティコンテキスト
securityContext:
  capabilities:
    add:
      - NET_ADMIN
      - SYS_MODULE
#!/bin/bash
# install-cilium.sh
# Ciliumインストールスクリプト

set -euo pipefail

CLUSTER_NAME="prod-cluster"
NAMESPACE="kube-system"

echo "=== Step 1: Cilium Helmリポジトリを追加 ==="
helm repo add cilium https://helm.cilium.io/
helm repo update

echo "=== Step 2: API Serverアドレスを取得 ==="
API_SERVER_IP=$(kubectl get endpoints kubernetes -o jsonpath='{.subsets[0].addresses[0].ip}')
API_SERVER_PORT=$(kubectl get endpoints kubernetes -o jsonpath='{.subsets[0].ports[0].port}')

echo "API Server: ${API_SERVER_IP}:${API_SERVER_PORT}"

echo "=== Step 3: Ciliumをインストール ==="
helm install cilium cilium/cilium \
  --namespace ${NAMESPACE} \
  --values cilium-values.yaml \
  --set kubeProxyReplacement=true \
  --set hubble.enabled=true \
  --set hubble.relay.enabled=true \
  --set hubble.ui.enabled=true \
  --wait

echo "=== Step 4: Ciliumの準備完了を待機 ==="
kubectl -n ${NAMESPACE} rollout status ds/cilium --timeout=300s
kubectl -n ${NAMESPACE} rollout status deploy/cilium-operator --timeout=120s

echo "=== Step 5: eBPFプログラムのロードを確認 ==="
kubectl -n ${NAMESPACE} exec ds/cilium -- cilium bpf lb list
kubectl -n ${NAMESPACE} exec ds/cilium -- cilium status

echo "=== Step 6: kube-proxy置き換えを確認 ==="
kubectl -n ${NAMESPACE} exec ds/cilium -- cilium service list

echo "=== Step 7: ステータスチェック ==="
cilium status --wait

echo "✅ Ciliumインストール完了!"

eBPFデータプレーンの検証

#!/bin/bash
# verify-ebpf.sh
# eBPFデータプレーンの動作確認

echo "=== Cilium eBPFプログラムを確認 ==="
kubectl -n kube-system exec ds/cilium -- cilium bpf tunnel list
kubectl -n kube-system exec ds/cilium -- cilium bpf ct list global

echo "=== アイデンティティマッピングを確認 ==="
kubectl -n kube-system exec ds/cilium -- cilium identity list

echo "=== ネットワーク接続性テスト ==="
kubectl run test-net --image=cilium/cilium:latest --restart=Never -- sleep infinity
kubectl exec test-net -- curl -s https://kubernetes.default.svc.cluster.local:443/api/v1/namespaces

echo "=== 帯域幅ベンチマーク ==="
kubectl run iperf3-server --image=networkstatic/iperf3 --restart=Never -- iperf3 -s
kubectl run iperf3-client --image=networkstatic/iperf3 --restart=Never -- sleep infinity
CLIENT_POD=$(kubectl get pods -l run=iperf3-client -o jsonpath='{.items[0].metadata.name}')
SERVER_IP=$(kubectl get pod iperf3-server -o jsonpath='{.status.podIP}')
kubectl exec ${CLIENT_POD} -- iperf3 -c ${SERVER_IP} -t 10 -P 4

echo "✅ eBPFデータプレーン検証完了!"

パターン2:L3/L4ネットワークポリシーとアイデンティティラベル

Ciliumアイデンティティラベルメカニズム

CiliumはIPアドレスではなくLabelを使用してセキュリティアイデンティティ(Identity)を計算します。同じLabelを持つPodは同じIdentityを共有し、ポリシーマッチングはIPではなくIdentityに基づきます:

Pod(app=api, env=prod) → Identity: 1001 → ポリシー許可 Identity:1001 → Identity:2001
Pod(app=web, env=prod) → Identity: 2001

基本L3/L4ネットワークポリシー

# cilium-l3-l4-policy.yaml
# L3/L4ネットワークポリシー:アイデンティティラベルに基づくゼロトラストアクセス制御
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: api-server-policy
  namespace: production
spec:
  description: "APIサービスはフロントエンドと内部サービスのアクセスのみを許可し、他のすべてのトラフィックを拒否"
  endpointSelector:
    matchLabels:
      app: api-server
      env: production
  ingress:
    # ルール1:フロントエンドPodのAPI 8080ポートへのアクセスを許可
    - fromEndpoints:
        - matchLabels:
            app: web-frontend
            env: production
      toPorts:
        - ports:
            - port: "8080"
              protocol: TCP
          rules:
            http:
              - method: GET
                path: "/api/v1/.*"
              - method: POST
                path: "/api/v1/.*"

    # ルール2:内部マイクロサービスのgRPCポートへのアクセスを許可
    - fromEndpoints:
        - matchLabels:
            app: internal-service
            env: production
      toPorts:
        - ports:
            - port: "9090"
              protocol: TCP

    # ルール3:Prometheusモニタリングスクレイプを許可
    - fromEndpoints:
        - matchLabels:
            app.kubernetes.io/name: prometheus
      toPorts:
        - ports:
            - port: "9090"
              protocol: TCP
              endPort: 9091

  egress:
    # データベースへのアクセスを許可
    - toEndpoints:
        - matchLabels:
            app: postgres
            env: production
      toPorts:
        - ports:
            - port: "5432"
              protocol: TCP

    # DNS解決を許可
    - toEndpoints:
        - matchLabels:
            k8s:io.kubernetes.pod.namespace: kube-system
            k8s-app: kube-dns
      toPorts:
        - ports:
            - port: "53"
              protocol: UDP

    # 外部API呼び出しを許可
    - toFQDNs:
        - matchName: "api.stripe.com"
        - matchPattern: "*.amazonaws.com"
      toPorts:
        - ports:
            - port: "443"
              protocol: TCP
---
# デフォルト拒否ポリシー(ゼロトラスト基盤)
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
  name: default-deny-all
spec:
  description: "デフォルトですべてのイングレストラフィックを拒否、ゼロトラストベースラインポリシー"
  endpointSelector: {}
  ingressDeny:
    - fromRequires:
        - {}
---
# ネームスペース分離ポリシー
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
  name: namespace-isolation
spec:
  description: "ネームスペースレベルの分離、同じネームスペース内の通信のみを許可"
  endpointSelector:
    matchLabels: {}
  ingress:
    - fromEndpoints:
        - matchLabels: {}

エンティティベースのネットワークポリシー

# entity-based-policy.yaml
# エンティティベースのネットワークポリシー:クラスタ内外のトラフィック制御
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
  name: entity-policy
spec:
  description: "Podとクラスタエンティティ間のネットワークアクセスを制御"
  endpointSelector:
    matchLabels:
      app: api-server
  ingress:
    # クラスタ内からのトラフィックを許可
    - fromEntities:
        - cluster
        - host
        - remote-node
  egress:
    # クラスタ外部へのアクセスを許可
    - toEntities:
        - world
    # K8s API Serverへのアクセスを許可
    - toEntities:
        - kube-apiserver

パターン3:L7アプリケーション層ポリシー(HTTP/gRPCフィルタリング)

HTTP層のきめ細かいアクセス制御

# cilium-l7-policy.yaml
# L7アプリケーション層ポリシー:HTTP/gRPCきめ細かいフィルタリング
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: l7-api-policy
  namespace: production
spec:
  description: "L7ポリシー:HTTPメソッド+パスの精密制御、APIレベルのゼロトラストを実現"
  endpointSelector:
    matchLabels:
      app: api-server
      env: production
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: web-frontend
      toPorts:
        - ports:
            - port: "8080"
              protocol: TCP
          rules:
            http:
              # 読み取り専用APIを許可
              - method: GET
                path: "/api/v1/users(/.*)?"
              - method: GET
                path: "/api/v1/products(/.*)?"
              - method: GET
                path: "/api/v1/orders(/.*)?"
              # 注文作成を許可
              - method: POST
                path: "/api/v1/orders"
              # 削除操作を拒否(このリストにないリクエストは拒否される)
---
# gRPCメソッドレベルフィルタリング
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: grpc-policy
  namespace: production
spec:
  description: "gRPCメソッドレベルのアクセス制御"
  endpointSelector:
    matchLabels:
      app: order-service
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: api-gateway
      toPorts:
        - ports:
            - port: "50051"
              protocol: TCP
          rules:
            http:
              - method: POST
                path: "/order.OrderService/GetOrder"
              - method: POST
                path: "/order.OrderService/ListOrders"
              - method: POST
                path: "/order.OrderService/CreateOrder"
---
# HTTPヘッダーフィルタリングポリシー
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: header-filter-policy
  namespace: production
spec:
  description: "HTTPヘッダーベースのアクセス制御"
  endpointSelector:
    matchLabels:
      app: internal-api
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: gateway
      toPorts:
        - ports:
            - port: "8080"
              protocol: TCP
          rules:
            http:
              - method: GET
                path: "/internal/.*"
                headers:
                  - "X-Internal-Token: ^secret-token-.*$"
---
# Kafkaプロトコル認識ポリシー
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: kafka-policy
  namespace: production
spec:
  description: "Kafkaトピックレベルのアクセス制御"
  endpointSelector:
    matchLabels:
      app: kafka-broker
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: order-processor
      toPorts:
        - ports:
            - port: "9092"
              protocol: TCP
          rules:
            kafka:
              - role: produce
                topic: orders
              - role: consume
                topic: orders
    - fromEndpoints:
        - matchLabels:
            app: analytics
      toPorts:
        - ports:
            - port: "9092"
              protocol: TCP
          rules:
            kafka:
              - role: consume
                topic: orders

L7ポリシー検証スクリプト

#!/bin/bash
# verify-l7-policy.sh
# L7アプリケーション層ポリシーの検証

echo "=== HTTP GET許可テスト ==="
kubectl exec deploy/web-frontend -- curl -s -o /dev/null -w "%{http_code}" http://api-server:8080/api/v1/users
# 期待値: 200

echo ""
echo "=== HTTP DELETE拒否テスト ==="
kubectl exec deploy/web-frontend -- curl -s -o /dev/null -w "%{http_code}" -X DELETE http://api-server:8080/api/v1/users/123
# 期待値: 403

echo ""
echo "=== ヘッダーなしアクセス拒否テスト ==="
kubectl exec deploy/gateway -- curl -s -o /dev/null -w "%{http_code}" http://internal-api:8080/internal/config
# 期待値: 403

echo ""
echo "=== Tokenヘッダー付きアクセス許可テスト ==="
kubectl exec deploy/gateway -- curl -s -o /dev/null -w "%{http_code}" -H "X-Internal-Token: secret-token-abc" http://internal-api:8080/internal/config
# 期待値: 200

echo ""
echo "=== Cilium L7ポリシーステータス確認 ==="
kubectl -n kube-system exec ds/cilium -- cilium policy get
kubectl -n kube-system exec ds/cilium -- cilium policy select

echo "✅ L7ポリシー検証完了!"

パターン4:Cluster Meshマルチクラスタネットワーク

Cluster Meshアーキテクチャ

Cluster A (us-west)          Cluster B (eu-central)
┌─────────────────┐          ┌─────────────────┐
│  Pod: api-server │◄────────►│  Pod: api-server │
│  Identity: 1001  │          │  Identity: 1001  │
│  Service: global  │          │  Service: global  │
└─────────────────┘          └─────────────────┘
        │                            │
        └──────── etcd同期 ──────────┘

Cluster Mesh設定

# cluster-mesh-config.yaml
# Cluster Meshマルチクラスタネットワーク設定
# クラスターA: us-west
apiVersion: v1
kind: ConfigMap
metadata:
  name: cilium-clustermesh
  namespace: kube-system
data:
  cluster-id: "1"
  cluster-name: "us-west"
---
# クラスターB: eu-central
apiVersion: v1
kind: ConfigMap
metadata:
  name: cilium-clustermesh
  namespace: kube-system
data:
  cluster-id: "2"
  cluster-name: "eu-central"
---
# グローバルService(クラスタ間ロードバランシング)
apiVersion: v1
kind: Service
metadata:
  name: global-api-server
  namespace: production
  annotations:
    service.cilium.io/global: "true"
    service.cilium.io/affinity: "local"
spec:
  type: ClusterIP
  ports:
    - port: 8080
      targetPort: 8080
  selector:
    app: api-server
---
# クラスタ間ネットワークポリシー
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: cross-cluster-policy
  namespace: production
spec:
  description: "クラスタ間ネットワークポリシー:us-westとeu-centralの相互アクセスを許可"
  endpointSelector:
    matchLabels:
      app: api-server
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: api-server
            io.cilium.k8s.policy.cluster: us-west
        - matchLabels:
            app: api-server
            io.cilium.k8s.policy.cluster: eu-central
      toPorts:
        - ports:
            - port: "8080"
              protocol: TCP
#!/bin/bash
# setup-cluster-mesh.sh
# Cluster Meshセットアップスクリプト

set -euo pipefail

CLUSTER_A="us-west"
CLUSTER_B="eu-central"
CONTEXT_A="kind-${CLUSTER_A}"
CONTEXT_B="kind-${CLUSTER_B}"

echo "=== Step 1: 両クラスターでCluster Meshを有効化 ==="
kubectl --context ${CONTEXT_A} -n kube-system exec ds/cilium -- \
  cilium clustermesh enable --cluster-id 1 --cluster-name ${CLUSTER_A}

kubectl --context ${CONTEXT_B} -n kube-system exec ds/cilium -- \
  cilium clustermesh enable --cluster-id 2 --cluster-name ${CLUSTER_B}

echo "=== Step 2: Cluster Mesh APIの準備完了を待機 ==="
kubectl --context ${CONTEXT_A} -n kube-system rollout status deploy/clustermesh-apiserver --timeout=120s
kubectl --context ${CONTEXT_B} -n kube-system rollout status deploy/clustermesh-apiserver --timeout=120s

echo "=== Step 3: 2つのクラスターを接続 ==="
kubectl --context ${CONTEXT_A} -n kube-system exec ds/cilium -- \
  cilium clustermesh connect --destination-context ${CONTEXT_B}

echo "=== Step 4: クラスタ接続ステータスを確認 ==="
kubectl --context ${CONTEXT_A} -n kube-system exec ds/cilium -- \
  cilium clustermesh status

kubectl --context ${CONTEXT_B} -n kube-system exec ds/cilium -- \
  cilium clustermesh status

echo "=== Step 5: クラスタ間サービスディスカバリをテスト ==="
kubectl --context ${CONTEXT_A} run test-cross-cluster \
  --image=cilium/cilium:latest --restart=Never -- \
  curl -s http://global-api-server.production.svc.cluster.local:8080/health

echo "=== Step 6: グローバルServiceを確認 ==="
kubectl --context ${CONTEXT_A} get svc global-api-server -n production -o yaml
kubectl --context ${CONTEXT_B} get svc global-api-server -n production -o yaml

echo "✅ Cluster Meshセットアップ完了!"

クラスタ間フェイルオーバーテスト

#!/bin/bash
# test-cross-cluster-failover.sh
# クラスタ間フェイルオーバーテスト

CLUSTER_A="us-west"
CLUSTER_B="eu-central"
CONTEXT_A="kind-${CLUSTER_A}"
CONTEXT_B="kind-${CLUSTER_B}"

echo "=== ベースラインテスト:正常なクラスタ間アクセス ==="
for i in $(seq 1 10); do
  RESULT=$(kubectl --context ${CONTEXT_A} exec deploy/test-client -- \
    curl -s http://global-api-server.production.svc.cluster.local:8080/cluster-name)
  echo "Request ${i}: ${RESULT}"
done

echo ""
echo "=== クラスタB障害をシミュレート ==="
kubectl --context ${CONTEXT_B} scale deploy api-server -n production --replicas=0

echo "=== トラフィックがクラスタAに自動切り替えされることを確認 ==="
for i in $(seq 1 10); do
  RESULT=$(kubectl --context ${CONTEXT_A} exec deploy/test-client -- \
    curl -s http://global-api-server.production.svc.cluster.local:8080/cluster-name)
  echo "Failover Request ${i}: ${RESULT}"
done

echo "=== クラスタBを復旧 ==="
kubectl --context ${CONTEXT_B} scale deploy api-server -n production --replicas=3

echo "✅ フェイルオーバーテスト完了!"

パターン5:Hubbleオブザーバビリティとネットワークトレーシング

Hubbleデプロイと設定

# hubble-values.yaml
# Hubbleオブザーバビリティ設定
hubble:
  enabled: true
  listenAddress: ":4244"
  metrics:
    enabled:
      - dns:query
      - drop
      - tcp
      - flow
      - port-distribution
      - http:method;path;status
      - icmp
    serviceMonitor:
      enabled: true
    dashboards:
      enabled: true
      namespace: monitoring
  relay:
    enabled: true
    replicas: 2
    rollOutPods: true
  ui:
    enabled: true
    replicas: 1
    rollOutPods: true
    ingress:
      enabled: true
      className: nginx
      hosts:
        - hubble.example.com
      tls:
        secretName: hubble-tls

Hubble CLIネットワークトレーシング

#!/bin/bash
# hubble-observability.sh
# Hubbleオブザーバビリティとネットワークトレーシング

echo "=== リアルタイムトラフィックモニタリング ==="
hubble observe --since 1m --output json | jq -r '
  select(.source.namespace == "production") |
  "\(.timestamp) \(.source.pod_name) → \(.destination.pod_name) \(.event.type) \(.l7.protocol // "L4") \(.l7.method // "") \(.l7.path // "") \(.response_status // "")"
'

echo ""
echo "=== 特定Podのトラフィックをトレース ==="
hubble observe --pod api-server-7d9f8b6c4-x2k1p --since 5m

echo ""
echo "=== 拒否されたトラフィックを検出 ==="
hubble observe --since 10m --type trace --verdict DROPPED | head -50

echo ""
echo "=== HTTPトラフィック分析 ==="
hubble observe --since 5m --protocol http --output json | jq -r '
  "\(.source.pod_name) → \(.destination.pod_name) [\(.l7.method)] \(.l7.path) → \(.l7.response_code)"
' | sort | uniq -c | sort -rn | head -20

echo ""
echo "=== DNSクエリモニタリング ==="
hubble observe --since 5m --protocol dns --output json | jq -r '
  "\(.source.pod_name) → \(.l7.dns.query) \(.l7.dns.rcode // "OK")"
' | sort | uniq -c | sort -rn | head -20

echo ""
echo "=== ネットワークレイテンシ分析 ==="
hubble observe --since 5m --type trace --output json | jq -r '
  select(.latency_ns != null) |
  "\(.source.pod_name) → \(.destination.pod_name) latency: \(.latency_ns / 1000000)ms"
' | sort -t: -k2 -n | tail -20

echo "✅ Hubbleオブザーバビリティ分析完了!"

Hubble Prometheusメトリクス

# hubble-prometheus-rules.yaml
# Hubbleアラートルール
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: hubble-alerts
  namespace: monitoring
spec:
  groups:
    - name: hubble-network
      rules:
        # 高ドロップ率アラート
        - alert: CiliumHighDropRate
          expr: |
            rate(hubble_drop_total{verdict="DROPPED"}[5m]) > 10
          for: 5m
          labels:
            severity: warning
          annotations:
            summary: "Ciliumが高ドロップ率を検出"
            description: "ネームスペース {{ $labels.namespace }} のPod {{ $labels.source_pod }} のドロップ率が10/sを超過"

        # DNS解決失敗アラート
        - alert: CiliumDNSFailures
          expr: |
            rate(hubble_dns_responses_total{rcode="NXDOMAIN"}[5m]) > 5
          for: 5m
          labels:
            severity: warning
          annotations:
            summary: "DNS解決失敗率が異常"
            description: "ネームスペース {{ $labels.namespace }} のDNS NXDOMAINレスポンスが5/sを超過"

        # TCP接続リセットアラート
        - alert: CiliumTCPResets
          expr: |
            rate(hubble_tcp_flags_total{flag="RST"}[5m]) > 50
          for: 5m
          labels:
            severity: critical
          annotations:
            summary: "TCP RSTパケットが異常"
            description: "ネームスペース {{ $labels.namespace }} のTCP RSTパケットが50/sを超過"

        # クラスタ間レイテンシアラート
        - alert: CiliumCrossClusterLatency
          expr: |
            histogram_quantile(0.99, rate(hubble_flows_processed_duration_seconds_bucket{source_cluster!=""}[5m])) > 0.5
          for: 10m
          labels:
            severity: warning
          annotations:
            summary: "クラスタ間ネットワークレイテンシが高すぎる"
            description: "P99レイテンシが500msを超過"

よくある落とし穴

落とし穴1:Ciliumインストール後にPodが通信できない

# ❌ 誤り:tunnelモードが正しく設定されておらず、ノードネットワークと互換性がない
tunnel: disabled
autoDirectNodeRoutes: false

# ✅ 正解:ネットワーク環境に応じてtunnelモードを選択
# クラウド環境(VPCがルーティングをサポート)
tunnel: disabled
autoDirectNodeRoutes: true
directRoutingSkipUnreachable: true

# 汎用環境(VXLANオーバーレイ)
tunnel: vxlan
tunnelPort: 8473

落とし穴2:L7ポリシーが有効にならない

# ❌ 誤り:L7ポリシーにtoPorts定義がなく、Ciliumがプロキシを注入できない
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: bad-l7-policy
spec:
  endpointSelector:
    matchLabels:
      app: api-server
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: frontend
      rules:
        http:
          - method: GET
            path: "/api/.*"

# ✅ 正解:L7ルールはtoPortsの下に定義する必要がある
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: good-l7-policy
spec:
  endpointSelector:
    matchLabels:
      app: api-server
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: frontend
      toPorts:
        - ports:
            - port: "8080"
              protocol: TCP
          rules:
            http:
              - method: GET
                path: "/api/.*"

落とし穴3:Cluster Mesh接続失敗

# ❌ 誤り:etcd証明書が正しく同期されていない
cilium clustermesh connect --destination-context other-cluster

# ✅ 正解:まずetcd証明書が正しいことを確認してから接続
# Cluster Mesh API Serverのステータスを確認
kubectl -n kube-system get deploy/clustermesh-apiserver
kubectl -n kube-system logs deploy/clustermesh-apiserver

# 証明書Secretの存在を確認
kubectl -n kube-system get secret clustermesh-apiserver-server-certs
kubectl -n kube-system get secret clustermesh-apiserver-remote-certs

# 正しい接続方法を使用
cilium clustermesh connect \
  --destination-context other-cluster \
  --destination-name other-cluster

落とし穴4:Hubble UIにトラフィックが表示されない

# ❌ 誤り:Hubble RelayがCilium Agentに接続できない
hubble:
  relay:
    enabled: true
    # dialTimeout設定が欠落しタイムアウトが発生

# ✅ 正解:Hubble Relayのタイムアウトとリトライを設定
hubble:
  relay:
    enabled: true
    dialTimeout: "5s"
    retryTimeout: "30s"
    maxFlows: 10000
    sortBufferLenMax: 1000
    sortBufferFlushInterval: "1s"
    port: 4245
    resources:
      requests:
        cpu: 100m
        memory: 128Mi
      limits:
        cpu: 500m
        memory: 512Mi

落とし穴5:eBPFプログラムのロード失敗

# ❌ 誤り:カーネルバージョンと互換性がないままインストール
helm install cilium cilium/cilium

# ✅ 正解:まずカーネル互換性を確認
# カーネルバージョンを確認(>= 5.4が必要、>= 5.10を推奨)
uname -r

# eBPF機能サポートを確認
kubectl -n kube-system exec ds/cilium -- cilium-dbg features

# カーネルバージョンが低い場合、互換モードを有効化
helm install cilium cilium/cilium \
  --set bpf.preallocateMaps=false \
  --set bpf.tproxy=false \
  --set hostFirewall.enabled=false

# eBPFプログラムのロードステータスを確認
kubectl -n kube-system exec ds/cilium -- cilium-dbg bpf lb list
kubectl -n kube-system exec ds/cilium -- cilium-dbg status

エラートラブルシューティング表

エラー現象 考えられる原因 診断コマンド 解決策
Podがクラスタ間ノードで通信できない tunnel設定エラー cilium bpf tunnel list tunnelモードを確認、VXLANポート8473が開いていることを確認
Cilium Pod CrashLoopBackOff カーネルバージョン非互換 dmesg | grep -i bpf カーネルを5.10+にアップグレードまたは互換モードを有効化
L7ポリシーが有効にならない toPorts定義の欠落 cilium policy get L7ルールはtoPorts.ports.rulesの下にネストする必要がある
Cluster Mesh接続タイムアウト etcd証明書の期限切れ kubectl logs -n kube-system deploy/clustermesh-apiserver 証明書を再生成:cilium clustermesh enable
Hubbleにトラフィックデータがない RelayがAgentに接続失敗 kubectl logs -n kube-system deploy/hubble-relay dialTimeoutとAgentポート4244を確認
DNS解決失敗 eBPF DNSプロキシ異常 cilium bpf ct list global | grep 53 DNSポリシーを確認、kube-dnsラベルが正しいことを確認
ネットワークレイテンシ急増 eBPF map満杯 cilium bpf ct list global | wc -l ctMapMaxを増加、GCを有効化
Serviceにアクセスできない kube-proxy残存との競合 iptables -L -n | grep KUBE iptablesルールを完全にクリーンアップ、kube-proxyが削除されていることを確認
アイデンティティ割り当て競合 KVStoreバックエンド異常 cilium identity list etcd接続を確認、cilium-operatorを再起動
クラスタ間Pod到達不能 グローバルService未設定 kubectl get svc -o yaml | grep global service.cilium.io/global: "true"アノテーションを追加

高度な最適化

1. eBPF Mapチューニング

# 大規模クラスタのeBPF Map設定
bpf:
  mapDynamicSizeRatio: 0.0025
  ctMapMax: 524288        # コネクショントラッキングテーブル
  ctTcpMax: 262144        # TCPコネクショントラッキング
  ctAnyMax: 262144        # 非TCPコネクショントラッキング
  lbMapMax: 65536         # ロードバランシングマップ
  lbServiceMapMax: 65536
  lbBackendMapMax: 65536
  natMapMax: 524288        # NATマップ
  neighMapMax: 524288      # ネイバーテーブル
  policyMapMax: 16384      # ポリシーマップ
  fragmentsMapMax: 8192    # フラグメントマップ

2. 帯域幅管理(EDT)

# eBPFベースの帯域幅管理
bandwidthManager:
  enabled: true
  bbr: true               # BBR輻輳制御を有効化
# Podに帯域幅制限を設定
kubectl annotate pod api-server-xxx \
  kubernetes.io/egress-bandwidth=100M \
  kubernetes.io/ingress-bandwidth=100M

3. Big TCP最適化

# 大規模TCP最適化(カーネル5.19+)
bpf:
  tcpRto: 100ms           # TCP再送タイムアウト
  tproxy: true
kubeProxyReplacement:
  true
hostPort:
  enabled: true
externalIPs:
  enabled: true
nodePort:
  enabled: true
hostLegacyRouting:
  enabled: false

4. eBPFホストルーティング

# ホストルーティング最適化
bpf:
  hostLegacyRouting: false  # eBPFでホストルーティングを代替
  lbExternalClusterIP: true
autoDirectNodeRoutes: true

5. セキュリティ強化

# Ciliumセキュリティ強化設定
securityContext:
  capabilities:
    add:
      - NET_ADMIN
      - SYS_MODULE
    drop:
      - ALL
  seccompProfile:
    type: RuntimeDefault
  readOnlyRootFilesystem: true

# 暗号化を有効化
encryption:
  enabled: true
  type: wireguard
  nodeEncryption: true

比較表

機能 Cilium eBPF Calico Flannel Weave
データプレーン eBPF iptables/eBPF VXLAN VXLAN
L3/L4ポリシー
L7ポリシー ✅ HTTP/gRPC/Kafka
オブザーバビリティ ✅ Hubble
Cluster Mesh
kube-proxy置き換え
帯域幅管理 ✅ EDT/BBR
WireGuard暗号化
FQDNポリシー
大規模パフォーマンス O(1) O(n) O(n) O(n)
カーネル要件 ≥5.4 ≥4.9 ≥3.10 ≥3.10

💡 まとめ:Cilium eBPFネットワークポリシーは、K8sネットワークセキュリティの未来の方向性を示しています。L3/L4アイデンティティラベルからL7アプリケーション層フィルタリング、単一クラスタのゼロトラストからCluster Meshマルチクラスタ相互接続、HubbleのリアルタイムオブザーバビリティからeBPFパフォーマンス最適化まで——5つのコアパターンが完全なクラウドネイティブネットワークセキュリティ体系を構築します。覚えておいてください:ゼロトラストは製品ではなく、アーキテクチャの理念であり、Ciliumはそれを実現する最適なツールです

オンラインツール推奨

  • JSONフォーマッター — CiliumポリシーJSON出力をフォーマット、ポリシー設定をトラブルシューティング
  • cURL to Code — Hubble APIクエリをコードに変換、オブザーバビリティを統合
  • ハッシュ計算 — ポリシー署名ハッシュを計算、設定の完全性を検証

ブラウザローカルツールを無料で試す →

#Cilium#eBPF#K8s网络#网络策略#2026#技术架构