- Authors

- Name
- Youngju Kim
- @fjvbn20031
Ciliumネットワークポリシーエンジン:L3/L4/L7フィルタリング実装
概要
CiliumのネットワークポリシーエンジンはKubernetes NetworkPolicyを拡張してL3/L4/L7レベルの細やかなトラフィック制御を提供します。eBPFとEnvoyプロキシを組み合わせたハイブリッドアーキテクチャで高性能と柔軟性を同時に達成します。
1. ポリシーリポジトリとルールコンパイル
1.1 ポリシーソース
Ciliumは複数のソースからネットワークポリシーを収集します。
ポリシーソース:
1. Kubernetes NetworkPolicy
- 標準L3/L4ポリシー
- Ciliumが自動的に変換して適用
2. CiliumNetworkPolicy(CNP)
- 名前空間範囲のCilium拡張ポリシー
- L7、FQDN、Identityベースなどの高度な機能
3. CiliumClusterwideNetworkPolicy(CCNP)
- クラスタ全体に適用されるポリシー
- デフォルト拒否ポリシー、共通セキュリティルール
4. CiliumEnvoyConfig(CEC)
- EnvoyプロキシのL7トラフィック管理ルール
1.2 ポリシーリポジトリ
Agent内部のポリシーリポジトリがすべてのポリシーを統合管理します。
ポリシー収集フロー:
K8s API Server
|
v
[Watcher: NetworkPolicy] -> ポリシーリポジトリ
[Watcher: CNP] -> ポリシーリポジトリ
[Watcher: CCNP] -> ポリシーリポジトリ
|
v
[ポリシー計算エンジン]
|
v
[エンドポイントごとのポリシーセット]
|
v
[BPFプログラムコンパイル]
1.3 ポリシーからBPFマップへの変換
CiliumNetworkPolicy YAML
|
v
ポリシーパースと正規化
|
v
セレクタマッチング:影響を受けるエンドポイントを決定
|
v
Identityベースの許可リスト生成
|
v
BPFポリシーマップ更新:
cilium_policy_<endpoint_id>マップにエントリを追加
キー:(Identity、ポート、プロトコル)
値:(許可/拒否、プロキシポート)
|
v
エンドポイントBPFプログラム再生成(必要に応じて)
2. Identityベース適用 vs IPベース適用
2.1 Identityベース適用
Ciliumのデフォルトのポリシー適用方式です。IPアドレスの代わりに数値Identityを使用します。
従来のIPベースファイアウォール:
許可:10.244.1.5 -> 10.244.2.10:8080
問題:Podが再起動するとIPが変わる
Cilium Identityベース:
許可:Identity 48291(app=frontend)-> Identity 52103(app=backend):8080
利点:IP変更に関係なくポリシーを維持
# ポリシーマップの内容確認(エンドポイントID基準)
cilium bpf policy get 1234
# 出力例:
# POLICY DIRECTION IDENTITY PORT/PROTO PROXY PORT ENTRY TYPE
# Allow Ingress 48291 8080/TCP 0 allow
# Allow Ingress 52103 443/TCP 0 allow
# Allow Egress 0 53/UDP 0 allow (DNS)
2.2 ポリシーマップ構造
// ポリシーマップキー(概念的)
struct policy_key {
__u32 identity; // ソース/宛先Identity
__u16 dport; // 宛先ポート(0 = すべてのポート)
__u8 protocol; // TCP、UDP、ICMP
__u8 direction; // ingress(1)、egress(2)
};
// ポリシーマップ値
struct policy_entry {
__u8 action; // allow(1)、deny(2)、audit(3)
__u16 proxy_port; // L7プロキシポート(0 = プロキシなし)
__u8 auth_type; // 認証タイプ(mTLSなど)
__u64 packets; // マッチパケットカウンタ
__u64 bytes; // マッチバイトカウンタ
};
2.3 ポリシールックアップアルゴリズム
パケット受信時のポリシールックアップ:
1. ソースIPからIdentityを照会(ipcache)
2. ポリシーマップで(Identity、Port、Protocol)の組み合わせをルックアップ
3. 正確なマッチ試行:
- (src_identity、dst_port、protocol)を確認
4. ワイルドカードマッチ:
- (src_identity、ANY_PORT、protocol)を確認
- (ANY_IDENTITY、dst_port、protocol)を確認
5. Denyルールを優先確認:
- Denyがあれば無条件で拒否
6. 結果:Allow / Deny / Audit
3. L3/L4適用:eBPFでの高速フィルタリング
3.1 L3ポリシー(ネットワークレイヤー)
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: l3-policy-example
spec:
endpointSelector:
matchLabels:
app: backend
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
- fromCIDR:
- 10.0.0.0/8
- fromEntities:
- world
egress:
- toEndpoints:
- matchLabels:
app: database
- toCIDR:
- 0.0.0.0/0
toCIDRSet:
- cidr: 0.0.0.0/0
except:
- 169.254.169.254/32
3.2 L4ポリシー(トランスポートレイヤー)
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: l4-policy-example
spec:
endpointSelector:
matchLabels:
app: backend
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
toPorts:
- ports:
- port: '8080'
protocol: TCP
- port: '8443'
protocol: TCP
egress:
- toEndpoints:
- matchLabels:
app: database
toPorts:
- ports:
- port: '5432'
protocol: TCP
3.3 eBPFでのL3/L4適用フロー
パケット:src=10.244.1.5:34567 dst=10.244.2.10:8080 TCP
1. [from-containerまたはto-container BPFプログラム]
2. ソースIdentityルックアップ:
ipcache[10.244.1.5] -> Identity: 48291
3. ポリシーマップルックアップ:
policy_map[endpoint_id]で検索:
key = (identity=48291, port=8080, proto=TCP, dir=ingress)
4. 結果:
- Allow:パケット転送を継続
- Deny:パケットドロップ + モニターイベント
- L7 Redirect:Envoyプロキシポートへリダイレクション
4. L7適用:Envoyプロキシ統合
4.1 L7ポリシー概要
L7ポリシーはアプリケーションプロトコルレベルのフィルタリングを提供します。
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: l7-http-policy
spec:
endpointSelector:
matchLabels:
app: api-server
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
toPorts:
- ports:
- port: '8080'
protocol: TCP
rules:
http:
- method: GET
path: '/api/v1/users'
- method: GET
path: '/api/v1/products'
- method: POST
path: '/api/v1/orders'
headers:
- 'Content-Type: application/json'
4.2 L7リダイレクションメカニズム
L7ポリシーが適用されたトラフィックフロー:
Pod A -> [from-container BPF]
|
v(ポリシーマップ:L7プロキシリダイレクション必要)
|
v
[tc redirectでEnvoyプロキシポートへ]
|
v
[Envoy Proxy(ノードあたり1つ)]
- HTTP/gRPC/Kafkaパース
- L7ルールマッチング
- 許可/拒否判定
|
v(許可された場合)
|
v
[BPFを通じて宛先へ転送]
|
v
Pod B
4.3 サポートプロトコル
| プロトコル | フィルタリング可能なフィールド |
|---|---|
| HTTP | method、path、headers、host |
| gRPC | service、method |
| Kafka | topic、clientID、apiKey、apiVersion |
| DNS | クエリ名パターン(matchName、matchPattern) |
4.4 Kafka L7ポリシー例
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: kafka-policy
spec:
endpointSelector:
matchLabels:
app: kafka-consumer
egress:
- toEndpoints:
- matchLabels:
app: kafka-broker
toPorts:
- ports:
- port: '9092'
protocol: TCP
rules:
kafka:
- role: consume
topic: 'orders'
- role: consume
topic: 'events'
5. FQDNポリシー:DNSプロキシ連携
5.1 FQDNポリシーの動作原理
FQDNポリシーフロー:
1. ポリシー定義:
toFQDNs:
- matchName: "api.example.com"
2. Cilium DNSプロキシ有効化:
- PodのDNSトラフィックを透過的にインターセプト
- DNS応答からIPアドレスを学習
3. IPキャッシュ更新:
DNS応答:api.example.com -> 203.0.113.10、203.0.113.11
|
v
ipcacheにIP -> FQDNマッピングを追加
BPFポリシーマップに該当IPの許可ルールを追加
4. トラフィック許可/ブロック:
- 学習されたIPへのトラフィックのみ許可
- DNS TTLに基づきマッピングが期限切れおよび更新
5.2 FQDNポリシー例
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: fqdn-policy
spec:
endpointSelector:
matchLabels:
app: backend
egress:
- toFQDNs:
- matchName: 'api.external-service.com'
toPorts:
- ports:
- port: '443'
protocol: TCP
- toFQDNs:
- matchPattern: '*.storage.googleapis.com'
toPorts:
- ports:
- port: '443'
protocol: TCP
- toEndpoints:
- matchLabels:
io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: '53'
protocol: UDP
rules:
dns:
- matchPattern: '*'
6. CiliumNetworkPolicy vs CiliumClusterwideNetworkPolicy
6.1 スコープの違い
CiliumNetworkPolicy(CNP):
- 名前空間スコープ
- endpointSelectorで同じ名前空間のPodを選択
- fromEndpoints/toEndpointsのnamespaceSelectorでクロス名前空間参照
CiliumClusterwideNetworkPolicy(CCNP):
- クラスタスコープ
- nodeSelectorで特定ノードを選択可能
- すべての名前空間に適用
- クラスタレベルのデフォルトポリシーに適合
6.2 CCNP活用例
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: default-deny-ingress
spec:
endpointSelector: {}
ingress:
- fromEntities:
- cluster
6.3 ホストポリシー
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: host-firewall
spec:
nodeSelector:
matchLabels:
node-role.kubernetes.io/worker: ''
ingress:
- fromEntities:
- remote-node
- health
toPorts:
- ports:
- port: '10250'
protocol: TCP
- fromCIDR:
- 10.0.0.0/8
toPorts:
- ports:
- port: '22'
protocol: TCP
7. ポリシー監査モード(Policy Audit Mode)
7.1 監査モードの動作
監査モードではポリシー違反トラフィックをブロックせずログのみ記録します。
# エンドポイントを監査モードに設定
cilium endpoint config 1234 PolicyAuditMode=Enabled
# グローバル監査モード設定
cilium config PolicyAuditMode=true
# 監査ログ確認
cilium monitor --type policy-verdict
# 出力例:
# Policy verdict log: flow ... action audit
# -> Would be DROPPED by policy (ingress)
# Identity: 48291 -> 52103, port 8080/TCP
7.2 監査から適用への移行
監査モード活用ワークフロー:
ステップ1:監査モード有効化
-> すべてのトラフィックを許可、違反を記録
ステップ2:Hubbleでトラフィックパターンを分析
-> 実際に必要な通信パスを把握
ステップ3:ポリシーを作成し監査結果と比較
-> 意図しないブロックがないか確認
ステップ4:監査モード無効化
-> 実際のポリシー適用開始
8. エンドポイント再生成とポリシー変更
8.1 ポリシー変更時の再生成プロセス
ポリシー変更検知:
|
v
影響を受けるエンドポイントの決定:
- セレクタがマッチするすべてのエンドポイント
- Identity参照による間接的な影響も含む
|
v
ポリシーマップ再計算:
- 新しい許可/拒否ルールセットを生成
- 既存ポリシーマップと比較(差分のみ適用)
|
v
BPFマップ更新:
- cilium_policyマップにエントリを追加/削除
- アトミック更新でパケット損失を最小化
|
v
BPFプログラム再コンパイル(必要に応じて):
- L7リダイレクションの追加/削除時
- プログラムロジックの変更が必要な場合
|
v
エンドポイント状態更新:Ready
9. Denyポリシー
9.1 Denyルールの動作
Ciliumは明示的なDenyルールをサポートし、DenyはAlwaysよりも常に優先されます。
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: deny-specific-cidr
spec:
endpointSelector:
matchLabels:
app: backend
egressDeny:
- toCIDR:
- 169.254.169.254/32
toPorts:
- ports:
- port: '80'
protocol: TCP
egress:
- toCIDR:
- 0.0.0.0/0
toPorts:
- ports:
- port: '443'
protocol: TCP
9.2 ポリシー優先順位
ポリシー評価順序:
1. Denyルール確認
- マッチするDenyルールがあれば即座に拒否
- Allowルールを無視
2. Allowルール確認
- マッチするAllowルールがあれば許可
3. デフォルト動作
- その方向(ingress/egress)にポリシーがある場合:デフォルト拒否
- ポリシーがまったくない場合:デフォルト許可
10. ポリシートラブルシューティング
10.1 デバッグコマンド
# 適用されたポリシーの確認
cilium policy get
# エンドポイントごとのポリシー状態
cilium endpoint get 1234
# ポリシーマップの内容確認
cilium bpf policy get 1234
# IdentityからラベルL確認
cilium identity get 48291
# ポリシーverdictモニタリング
cilium monitor --type policy-verdict
# ドロップされたパケットの確認
cilium monitor --type drop
10.2 一般的な問題と解決策
問題:Pod間通信がブロックされる
原因の可能性:
1. Identityが正しく割り当てられていない
-> cilium identity listで確認
2. ポリシーセレクタが正しくない
-> cilium policy getで適用ポリシーを確認
3. DNSイグレスポリシーが欠落
-> FQDNポリシー使用時にDNS許可は必須
問題:L7ポリシーが適用されない
原因の可能性:
1. Envoyプロキシが正常に動作していない
-> cilium statusでProxy状態を確認
2. toPorts配下のrules構文エラー
-> cilium policy getでパース結果を確認
まとめ
Ciliumのネットワークポリシーエンジンは多層的セキュリティモデルを通じて強力なトラフィック制御を提供します。
- Identityベース適用:IPアドレスではなくラベルベースでポリシーを適用し動的環境でも安定
- eBPF高速フィルタリング:L3/L4ポリシーをカーネルで直接適用し最小レイテンシー
- Envoy L7統合:HTTP、gRPC、Kafkaなどアプリケーションレベルのフィルタリング
- FQDNポリシー:DNSプロキシを通じたドメインベースのイグレス制御
- Deny優先:明示的拒否ルールが常に優先されセキュリティを強化
- 監査モード:ポリシー適用前に影響度を事前把握可能
- 増分更新:最小限の再生成でポリシー変更を適用