Skip to content

필사 모드: Cilium eBPFデータパス深層分析:パケット処理パイプライン

日本語
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

Cilium eBPFデータパス深層分析:パケット処理パイプライン

概要

CiliumのeBPFデータパスはLinuxカーネル内でパケットを処理する高性能ネットワークパイプラインです。この記事ではパケットがPodで送受信される際に通る全プロセスを詳細に分析します。

1. パケット処理フロー概要

1.1 イングレスパケットフロー(外部 -> Pod)

外部ネットワーク

|

v

[物理NIC] eth0

|

v

[XDPプログラム](オプション)

- NodePortアクセラレーション

- DDoS防御

- プリフィルタリング

|

v

[tc ingress: from-netdev]

- ソースIdentityルックアップ(ipcache)

- トンネルデカプセル化(VXLAN/Geneve)

- NodePort DNAT

|

v

[ルーティング決定]

- ローカルPod? -> cilium_host

- リモートノード? -> トンネルまたはダイレクトルーティング

|

v

[cilium_host: to-host]

- ホストファイアウォールポリシー確認

|

v

[tc egress: to-container](lxc*)

- 宛先Identity確認

- イングレスポリシー確認

- L3/L4フィルタリング

- conntrackエントリ作成/更新

- L7リダイレクション(必要に応じてEnvoyへ)

|

v

[Podネットワーク名前空間]

1.2 イグレスパケットフロー(Pod -> 外部)

[Podネットワーク名前空間]

|

v

[tc ingress: from-container](lxc*)

- ソースエンドポイント識別

- イグレスポリシー確認

- サービスDNAT(kube-proxy代替)

- conntrackルックアップ/作成

- L7リダイレクション(必要に応じて)

|

v

[ルーティング決定]

- 同一ノードPod? -> 直接配送

- リモートPod? -> トンネルまたはダイレクトルーティング

- 外部? -> SNAT(マスカレード)

|

v

[tc egress: to-netdev](eth0)

- SNAT適用

- トンネルカプセル化(VXLAN/Geneve)

|

v

[物理NIC] eth0

|

v

外部ネットワーク

2. BPFプログラム詳細

2.1 from-container(Podイグレス)

Podから出ていくパケットを処理する最初のBPFプログラムです。

// 概念的なfrom-container処理フロー(簡略化)

// 実際のコード:bpf/bpf_lxc.c - handle_xgress()

int from_container(struct __sk_buff *skb) {

// 1. パケットパース(L2/L3/L4ヘッダー)

// 2. ソースエンドポイント識別

// 3. イグレスポリシー確認

// - IdentityベースL3/L4ポリシー

// - CIDRポリシー

// - L7ポリシー -> Envoyリダイレクション

// 4. サービスロードバランシング

// - ClusterIP DNAT

// - NodePort DNAT

// 5. conntrack処理

// 6. ルーティング決定

// - 同一ノード:tail call to-container

// - リモートノード:トンネルカプセル化またはダイレクトルーティング

// - 外部:SNAT

return TC_ACT_OK; // or TC_ACT_SHOT(drop)

}

主要な処理ステージ:

| ステージ | 説明 | 使用BPFマップ |

| ------------------ | -------------------------- | --------------------------------- |

| パケットパース | L2/L3/L4ヘッダー抽出 | - |

| エンドポイント識別 | ソースPod確認 | cilium_lxc |

| ポリシー確認 | イグレスポリシーマッチング | cilium_policy |

| サービスLB | ClusterIP/NodePort DNAT | cilium_lb4_services |

| conntrack | 接続状態追跡 | cilium_ct4_global |

| ルーティング | 宛先ノード決定 | cilium_ipcache、cilium_tunnel_map |

2.2 to-container(Podイングレス)

Podに入ってくるパケットを処理するBPFプログラムです。

// 概念的なto-container処理フロー

// 実際のコード:bpf/bpf_lxc.c - handle_ingress()

int to_container(struct __sk_buff *skb) {

// 1. パケットパース

// 2. ソースIdentityルックアップ

// - ipcacheでソースIP -> Identityマッピング

// 3. イングレスポリシー確認

// - IdentityベースL3/L4ポリシー

// - L7ポリシー -> Envoyリダイレクション

// 4. conntrack更新

// 5. reverse NAT(応答パケットの場合)

// 6. Podへ配送

return TC_ACT_OK;

}

2.3 from-overlay / to-overlay

オーバーレイネットワーク(VXLAN/Geneve)を通じたパケット処理です。

VXLAN受信フロー:

[物理NIC] -> [VXLANデカプセル化] -> [from-overlay BPF]

- 内部Identity抽出(Geneve TLVまたはソースIPベース)

- 宛先エンドポイントルックアップ

- ポリシー確認

- 対象Podへ配送

VXLAN送信フロー:

[from-container BPF] -> [ルーティング:リモートノード] -> [to-overlay BPF]

- Identity情報をトンネルヘッダーに含める

- VXLAN/Geneveカプセル化

- 物理NICへ転送

3. コネクショントラッキング実装

3.1 conntrack構造

Ciliumは独自のeBPFベースコネクショントラッキングを実装しています。

// conntrackキー構造(概念的)

struct ct_key {

__u32 src_ip;

__u32 dst_ip;

__u16 src_port;

__u16 dst_port;

__u8 protocol; // TCP、UDP、ICMP

__u8 direction; // ingress、egress

};

// conntrack値構造

struct ct_entry {

__u64 rx_packets;

__u64 rx_bytes;

__u64 tx_packets;

__u64 tx_bytes;

__u32 lifetime;

__u16 rev_nat_index; // reverse NATインデックス

__u16 src_sec_id; // ソースIdentity

__u32 flags;

};

3.2 conntrackステートマシン

TCP接続状態追跡:

SYN -> [NEW] -> SYN-ACK -> [ESTABLISHED] -> FIN -> [CLOSING] -> [CLOSED]

状態別タイムアウト:

- NEW:60秒

- ESTABLISHED:6時間(TCP)、60秒(UDP)

- CLOSING:10秒

3.3 conntrackの活用

conntrackテーブル照会

cilium bpf ct list global

TCP接続の出力例:

TCP IN 10.244.1.5:34567 -> 10.96.0.1:443

Expires: 21590s Identity: 48291

RxPackets: 142 RxBytes: 15234

TxPackets: 138 TxBytes: 12890

Flags: rx+tx established

conntrackエントリ数の確認

cilium bpf ct list global | wc -l

特定IPのconntrackフィルタリング

cilium bpf ct list global | grep "10.244.1.5"

3.4 conntrack GC(ガベージコレクション)

期限切れのconntrackエントリは定期的にクリーンアップされます。

Agent内部GCループ:

1. BPFマップの全エントリを走査

2. タイムアウト期限切れエントリを識別

3. 期限切れエントリを削除

4. 関連NATエントリも合わせて削除

5. メトリクスの更新

GC周期:設定可能(デフォルト約12秒)

4. NATエンジン

4.1 SNAT(Source NAT / マスカレード)

Podからクラスタ外部へ出るトラフィックのソースIPをノードIPに変換します。

SNAT処理フロー:

Pod(10.244.1.5:34567)-> 外部(8.8.8.8:443)

|

v

[from-container BPF]

- 宛先がクラスタ外部か確認

- SNATの必要性を判断

|

v

[SNATエンジン]

- ソースIPをノードIPに変換(10.244.1.5 -> 192.168.1.100)

- ソースポートをエフェメラルポートに変換

- NATマッピングをBPFマップに保存

|

v

ノードIP(192.168.1.100:50123)-> 外部(8.8.8.8:443)

応答パケット(Reverse SNAT):

外部(8.8.8.8:443)-> ノードIP(192.168.1.100:50123)

|

v

[to-netdev BPF]

- NATマッピングから元のソースを照会

- 宛先を元のPod IP/ポートに復元

|

v

外部(8.8.8.8:443)-> Pod(10.244.1.5:34567)

4.2 DNAT(サービスロードバランシング)

KubernetesサービスIPを実際のバックエンドPod IPに変換します。

サービスDNATフロー:

クライアント(10.244.1.5)-> Service(10.96.0.10:80)

|

v

[from-container BPF:サービスLB]

- cilium_lb4_servicesでサービスをルックアップ

- バックエンド選択(ラウンドロビン、Maglevなど)

- 宛先IP/ポートをバックエンドに変換

|

v

クライアント(10.244.1.5)-> Backend Pod(10.244.2.10:8080)

4.3 Maglev一貫性ハッシュ

MaglevはGoogleが開発した一貫性ハッシュアルゴリズムで、Ciliumのサービスロードバランシングに使用されます。

Maglevハッシュ処理過程:

1. ルックアップテーブル作成(65537エントリ)

- 各バックエンドがテーブルの複数の位置にマッピング

- バックエンド数に関係なく均一な分布

2. パケットハッシュ計算

- 5-tupleハッシュ:src_ip + dst_ip + src_port + dst_port + protocol

- ハッシュ値でテーブルインデックスを決定

3. バックエンド選択

- table[hash % table_size] = backend

バックエンド変更時の影響:

- 1つのバックエンド追加/削除 -> 約1/Nの接続のみ再マッピング

- 既存接続の大部分を維持

4.4 サービスタイプ別処理

ClusterIP:

- from-containerでDNAT

- ソケットレベルLB(bpf_sock)またはtcレベル

NodePort:

- XDPまたはtc ingress(from-netdev)でDNAT

- DSRモード:応答パケットを直接配送

- SNATモード:元のノードを通じて応答

LoadBalancer:

- NodePortと同一の処理 + ExternalIPマッピング

- LB-IPAMによるIP割り当て

ExternalTrafficPolicy: Local

- ローカルバックエンドがある場合のみ処理

- クライアントソースIPを保持

5. DSR(Direct Server Return)モード

5.1 DSRの動作原理

DSRモードでは応答パケットが元のリクエストを受信したノードを経由せず直接クライアントに配送されます。

DSRフロー:

1. クライアント -> ノードA(NodePort)

[ノードA:DNAT + DSRオプション設定]

- 宛先をバックエンドPod(ノードB)に変換

- IPオプションに元のサービスIP/ポートをエンコード

2. ノードA -> ノードB(バックエンドPod)

[ノードB:DSRオプション処理]

- IPオプションから元のサービスIP/ポートを復元

- conntrackにreverse NAT情報を保存

3. ノードB(バックエンドPod)-> クライアント

[ノードB:reverse NAT]

- ソースIPをサービスIPに変換

- ノードAを経由せず直接応答

通常モード(SNAT):

クライアント -> ノードA -> ノードB -> ノードA -> クライアント

(2ホップ追加)

DSRモード:

クライアント -> ノードA -> ノードB -> クライアント

(応答は直接)

6. eBPFテールコール:プログラムチェイニング

6.1 テールコールメカニズム

eBPFプログラムには命令数制限があるため、複雑な処理を複数のプログラムに分離します。

テールコールチェーン例:

[from-container]

|

tail_call -> [IPv4ポリシー確認]

|

tail_call -> [サービスLB]

|

tail_call -> [NAT処理]

|

tail_call -> [転送]

6.2 Ciliumの主要テールコールポイント

CILIUM_CALL_IPV4_FROM_LXC = 0 // IPv4 from-containerエントリ

CILIUM_CALL_IPV4_CT_INGRESS = 4 // IPv4 conntrackイングレス

CILIUM_CALL_IPV4_CT_EGRESS = 5 // IPv4 conntrackイグレス

CILIUM_CALL_IPV4_NODEPORT_NAT = 13 // NodePort NAT

CILIUM_CALL_IPV4_NODEPORT_DSR = 14 // NodePort DSR

CILIUM_CALL_IPV4_ENCAP = 15 // トンネルカプセル化

CILIUM_CALL_SEND_ICMP_UNREACH = 18 // ICMP Unreachable送信

CILIUM_CALL_SRV6_ENCAP = 23 // SRv6カプセル化

7. ソケットレベルロードバランシング

7.1 ソケットLBの概要

ソケットレベルロードバランシングはiptablesやtcレベルのNATをバイパスし、connect()システムコール時点でサービスIPをバックエンドIPに直接変換します。

従来の方式(iptables/tc):

connect(サービスIP) -> [カーネルネットワークスタック] -> [NAT] -> [conntrack] -> バックエンド

ソケットLB方式:

connect(サービスIP) -> [BPF sock_ops] -> connect(バックエンドIP)

- NAT不要

- conntrackエントリ不要

- ネットワークスタックオーバーヘッド除去

7.2 ソケットLBの利点

パフォーマンス比較:

tcレベルLB:

- パケットごとにNAT実行

- conntrackエントリが必要

- 追加CPUサイクル

ソケットレベルLB:

- 接続ごとに1回のみ変換

- conntrack不要

- 最小CPUオーバーヘッド

- 元のサービスIPを保持(getpeername)

8. パケットドロップとモニタリング

8.1 ドロップ理由コード

Ciliumはパケットドロップ時に詳細な理由コードを提供します。

ドロップされたパケットのモニタリング

cilium monitor --type drop

出力例:

xx drop (Policy denied) flow ...

xx drop (Invalid source ip) flow ...

xx drop (CT: Map insertion failed) flow ...

主要なドロップ理由:

| コード | 説明 |

| ------------------------- | ------------------------ |

| Policy denied | ポリシーにより拒否 |

| Invalid source ip | ソースIPが無効 |

| CT: Map insertion failed | conntrackマップ挿入失敗 |

| No mapping for NAT | NATマッピングなし |

| Unknown L3 target | L3宛先が不明 |

| Authentication required | mTLS認証が必要 |

| Service backend not found | サービスバックエンドなし |

8.2 パケットトレーシング

リアルタイムパケットトレース

cilium monitor --type trace

特定エンドポイントのトラフィックのみモニタリング

cilium monitor --type trace --from-endpoint 1234

ポリシーverdictモニタリング

cilium monitor --type policy-verdict

デバッグレベルモニタリング

cilium monitor --type debug

9. パフォーマンス最適化技法

9.1 XDPアクセラレーション

XDPモード別パフォーマンス:

- XDP native(ドライバ内蔵):最高パフォーマンス

- XDP generic(ソフトウェア):互換性優先

- XDP offload(NICハードウェア):特定NICのみサポート

9.2 BIG TCP

BIG TCPの動作:

- GRO(Generic Receive Offload)で受信パケットを64KB+サイズに統合

- 内部的に大容量パケットとして処理しパケットあたりのオーバーヘッドを削減

- GSO(Generic Segmentation Offload)で送信時に分割

9.3 eBPFプログラム最適化

コンパイル時最適化:

- 未使用機能をコンパイルから除外

- ポリシーのないエンドポイント:最小限のBPFコード

- IPv4専用環境:IPv6コードを除去

ランタイム最適化:

- BPFマッププリフェッチ

- インライン関数の活用

- 不要な条件分岐の除去

- JITコンパイルによるネイティブコード実行

まとめ

CiliumのeBPFデータパスは以下の核心設計で高性能を達成しています。

- **カーネル内処理**:すべてのパケット処理がカーネル空間で行われユーザー空間遷移オーバーヘッドを除去

- **テールコールチェイニング**:複雑なロジックを複数のBPFプログラムに分離しモジュール性を確保

- **独自conntrack**:Linux netfilter conntrackの代わりにBPFマップベースの高性能コネクショントラッキング

- **ソケットレベルLB**:NATなしでサービスロードバランシングし最小オーバーヘッド

- **DSRモード**:不要なネットワークホップを除去し応答レイテンシーを削減

- **XDPアクセラレーション**:ネットワークドライバレベルで超高速パケット処理

현재 단락 (1/319)

CiliumのeBPFデータパスはLinuxカーネル内でパケットを処理する高性能ネットワークパイプラインです。この記事ではパケットがPodで送受信される際に通る全プロセスを詳細に分析します。

작성 글자: 0원문 글자: 7,868작성 단락: 0/319