Cilium:从 Kubernetes YAML 到 eBPF Map 与端到端通信链路
本文从两个方向解释 Cilium:
- 控制面:Node、Pod、CiliumEndpoint、Service、EndpointSlice、CiliumNetworkPolicy 和 CiliumEgressGatewayPolicy 等资源如何转化为 Linux 路由、eBPF 程序和 BPF Map;
- 数据面:同节点 Pod、跨节点 Pod、普通 Pod 访问公网、命中统一 Egress Gateway、公网访问内部 Pod时,数据包如何流动。
本文以 IPv4、TC BPF 和 kube-proxy replacement 为主。不同配置可能使用 XDP、native routing、VXLAN、Geneve、WireGuard、IPsec、socket LB 或 L7 proxy,但核心状态模型一致。
1. 总体模型
Cilium agent 预先监听 Kubernetes 资源、分配 identity、计算策略和路由,并把结果写入 BPF Map。数据包到达后,eBPF 程序在内核中查表、执行策略、NAT 和重定向,不会为每个包访问 Kubernetes API。
flowchart LR
API[Kubernetes API] --> W[Cilium Watchers]
W --> NM[Node Manager]
W --> EM[Endpoint Manager]
W --> PR[Policy Repository]
W --> SM[Service Manager]
W --> EGM[Egress Gateway Manager]
NM --> TM[cilium_tunnel_map / Linux routes]
NM --> IPC[cilium_ipcache]
EM --> LXC[cilium_lxc]
EM --> PM[cilium_policy_endpointID]
PR --> PM
PR --> IPC
SM --> SVC[cilium_lb4_services_v2]
SM --> BE[cilium_lb4_backends_v3]
SM --> REV[LB reverse NAT / Maglev maps]
EGM --> EGP[cilium_egress_gw_policy_v4]
TM --> DP[TC/XDP eBPF datapath]
IPC --> DP
LXC --> DP
PM --> DP
SVC --> DP
BE --> DP
REV --> DP
EGP --> DP
1.1 主要挂载点
| 挂载位置 | 常见程序 | 主要职责 |
|---|---|---|
Pod host-side veth,如 lxcXXXXX |
bpf_lxc |
Pod egress/ingress policy、CT、Service LB、本地交付 |
| 节点物理网卡 | bpf_host |
NodePort、外部 ingress、SNAT/reverse-SNAT、host firewall |
cilium_host |
bpf_host |
host namespace 与 Pod 数据面的衔接 |
| VXLAN/Geneve 设备 | bpf_overlay |
跨节点封装、解封装、identity 传递 |
| 物理网卡 XDP | bpf_xdp |
更早执行的 NodePort/LB 快速路径 |
| cgroup/socket | bpf_sock |
socket LB、connect/sendmsg 地址转换 |
ingress/egress 是相对于挂载设备而言。Pod 发包在业务语义上是 egress,但到达 host-side veth 时是该 veth 的 ingress。
2. 控制面:YAML 如何变成 BPF 状态
2.1 Node 与 CiliumNode
Node/CiliumNode 提供节点 labels、InternalIP、PodCIDR/allocation CIDR、加密 key 和 Egress Gateway 选节点所需信息。
apiVersion: v1
kind: Node
metadata:
name: node-b
labels:
role: egress-gateway
spec:
podCIDR: 10.244.2.0/24
status:
addresses:
- type: InternalIP
address: 192.168.1.20
处理链路:
Node/CiliumNode event
→ pkg/node/manager.NodeUpdated()
→ linuxNodeHandler.NodeAdd()/nodeUpdate()
→ overlay: PodCIDR → NodeIP 写 cilium_tunnel_map
→ native routing: 安装到远端 PodCIDR 的 Linux route
→ 节点/Pod prefix identity 和 tunnel metadata 写 cilium_ipcache
关键实现:
pkg/node/manager/manager.go: NodeUpdated();pkg/datapath/linux/node.go: nodeUpdate();pkg/datapath/linux/node.go: updateTunnelMapping();pkg/maps/tunnel/tunnel.go。
sequenceDiagram
autonumber
participant API as Kubernetes API
participant W as Node Watcher
participant M as Node Manager
participant L as Linux Node Handler
participant T as cilium_tunnel_map
participant R as Linux Route Table
participant I as cilium_ipcache
API->>W: Node/CiliumNode add/update
W->>M: NodeUpdated
M->>L: NodeAdd/NodeUpdate
alt Overlay
L->>T: PodCIDR → Node InternalIP
L->>R: route PodCIDR 到 tunnel device
else Native routing
L->>R: PodCIDR → remote node/direct route
end
M->>I: prefix → identity/tunnel metadata
2.2 Pod、Local Endpoint、CEP/CES
Pod YAML 不直接对应一个 BPF entry。Pod sandbox 创建时,Cilium CNI/agent 会:
- 创建 veth pair并配置 Pod IP和路由;
- 创建本地 Endpoint;
- 根据 namespace、service account和Pod labels分配 security identity;
- 生成并挂载 endpoint BPF;
- 写本机 endpoint map
cilium_lxc; - 创建每 endpoint policy map;
- 同步 CiliumEndpoint/CiliumEndpointSlice,供其他节点学习 Pod IP、identity和所在节点。
cilium_lxc 的逻辑映射:
Pod IP → ifindex、endpoint ID、MAC、node MAC、security identity
远端 agent 根据 CEP/CES 等信息更新:
cilium_ipcache: Pod IP/prefix → identity + tunnel endpoint + encryption key
关键实现:
pkg/maps/lxcmap/lxcmap.go: WriteEndpoint();pkg/endpoint/bpf.go;pkg/endpointmanager/endpointsynchronizer.go;pkg/datapath/ipcache/listener.go: OnIPIdentityCacheChange()。
sequenceDiagram
autonumber
participant API as Kubernetes API
participant K as Kubelet/CNI
participant A as Local Cilium Agent
participant ID as Identity Allocator
participant V as Pod veth
participant L as cilium_lxc
participant P as cilium_policy_endpointID
participant C as CiliumEndpoint/CES
participant RA as Remote Agents
participant I as cilium_ipcache
API->>K: 创建 Pod
K->>A: CNI ADD
A->>V: 创建veth、配置IP/route
A->>ID: labels → security identity
ID-->>A: numeric identity
A->>A: 创建/regenerate Endpoint BPF
A->>L: PodIP → ifindex/MAC/identity
A->>P: 生成endpoint policy entries
A->>C: 同步PodIP/identity/node
C->>RA: CEP/CES watch event
RA->>I: PodIP → identity/tunnel endpoint
2.3 CiliumNetworkPolicy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-client-to-server
namespace: business
spec:
endpointSelector:
matchLabels:
app: server
ingress:
- fromEndpoints:
- matchLabels:
app: client
toPorts:
- ports:
- port: "8080"
protocol: TCP
解析和下发链路:
CNP YAML
→ pkg/policy/k8s watcher
→ resolve CiliumCIDRGroup / ToServices 等引用
→ cnp.Parse()
→ policyManager.PolicyAdd()
→ Policy Repository
→ 找出被规则选中的 endpoints
→ endpoint regeneration
→ EndpointPolicy.toMapState()
→ syncPolicyMap()
→ cilium_policy_<endpoint-id>
关键源码:
pkg/policy/k8s/cilium_network_policy.go;daemon/cmd/policy.go: PolicyAdd();pkg/policy/repository.go: AddListLocked();pkg/policy/resolve.go: EndpointPolicy.toMapState();pkg/endpoint/bpf.go: syncPolicyMap()。
CNP 通常不会落入一个全局规则表,而是被编译成每 endpoint 独立 map:
cilium_policy_<endpoint-id>
逻辑 key 包含:
remote security identity + traffic direction + protocol + port/prefix
value 包含 allow/deny、proxy port、authentication 等动作。CIDR规则还可能分配CIDR identity并写入 cilium_ipcache,policy map再引用这个identity。
sequenceDiagram
autonumber
participant API as Kubernetes API
participant W as CNP Watcher
participant Parser as CNP Parser/Translator
participant Repo as Policy Repository
participant Sel as Selector/Identity Cache
participant EP as Selected Endpoint
participant State as EndpointPolicy MapState
participant PM as cilium_policy_endpointID
participant IPC as cilium_ipcache
API->>W: CNP add/update
W->>Parser: resolve refs并Parse
Parser->>Repo: PolicyAdd(rules)
Repo->>Sel: selectors → identities
Repo->>EP: 触发受影响endpoint regeneration
EP->>State: ingress/egress L3/L4 → MapState
opt CIDR/FQDN派生CIDR
Sel->>IPC: prefix → CIDR identity
end
State->>PM: add/delete policy keys
数据面执行位置:
- 源 Pod 发包时执行源 endpoint egress policy;
- 目标 Pod 收包时执行目标 endpoint ingress policy;
- 回包结合 conntrack状态按有状态连接处理;
- L7规则可通过policy value将流量重定向到Envoy。
2.4 Service 与 EndpointSlice
Service YAML + EndpointSlice
→ Service/EndpointSlice Watcher
→ 构造 loadbalancer.SVC
→ Service.UpsertService()
→ 分配 service ID/backend ID
→ LBBPFMap.UpsertService()
| Map | 内容 |
|---|---|
cilium_lb4_services_v2 |
frontend、backend slot、backend ID和Service flags |
cilium_lb4_backends_v3 |
backend ID → Pod IP/port |
| LB reverse NAT map | rev-NAT ID → Service frontend IP/port |
| Maglev maps | Service ID → 一致性hash lookup table |
关键源码:pkg/k8s/watchers/service.go、pkg/service/service.go、pkg/maps/lbmap/lbmap.go。
sequenceDiagram
autonumber
participant API as Kubernetes API
participant W as Service/EndpointSlice Watcher
participant S as Service Manager
participant ID as ID Allocator
participant B as cilium_lb4_backends_v3
participant M as cilium_lb4_services_v2
participant R as Reverse NAT Map
participant G as Maglev Map
API->>W: Service + EndpointSlice events
W->>S: UpsertService(frontend,backends,trafficPolicy)
S->>ID: 分配service/backend IDs
S->>B: backend ID → PodIP:PodPort
S->>M: frontend slot 0 + backend slots
S->>R: rev-NAT ID → frontend
opt Maglev
S->>G: service ID → backend table
end
2.5 CiliumEgressGatewayPolicy
apiVersion: cilium.io/v2
kind: CiliumEgressGatewayPolicy
metadata:
name: business-egress
spec:
selectors:
- podSelector:
matchLabels:
app: client
destinationCIDRs:
- 0.0.0.0/0
excludedCIDRs:
- 10.0.0.0/8
- 172.16.0.0/12
egressGateway:
nodeSelector:
matchLabels:
role: egress-gateway
interface: eth1
Egress Gateway Manager:
- 用 Pod selector找到匹配endpoint;
- 用 Node selector选择Gateway Node;
- 得到Gateway Node IP;
- 根据interface或配置推导Egress IP;
- 将策略展开为每个Pod IP与destination CIDR的组合;
- 写入
cilium_egress_gw_policy_v4。
该map是LPM Trie:
Key: Pod source IP + destination CIDR
Value: Egress IP + Gateway Node IP
即:
(PodIP, Destination CIDR) → (EgressIP, GatewayIP)
excluded CIDR使用特殊gateway value写入同一LPM Trie,最长前缀匹配会优先命中更具体的排除项。
关键源码:pkg/egressgateway/manager.go、pkg/maps/egressmap/policy.go、bpf/lib/egress_gateway.h。
3. 数据面中的几类 Map
| Map | 解决的问题 |
|---|---|
cilium_lxc |
目标是否为本机Pod,应该重定向到哪个ifindex |
cilium_ipcache |
某个IP/prefix的identity、远端节点和加密信息 |
cilium_policy_<id> |
对端identity、方向、协议和端口是否允许 |
| Service/Backend maps | 虚拟Service frontend应该选择哪个Pod |
| Conntrack maps | 连接是NEW/ESTABLISHED/REPLY,保存backend/rev-NAT等状态 |
| SNAT map | 地址和端口如何正向/反向转换 |
| Egress policy map | Pod访问某目的CIDR应走哪个Gateway并用哪个Egress IP |
4. 场景一:同节点 Pod 通信
假设Pod A 10.244.1.10/identity 1001和Pod B 10.244.1.20/identity 1002都在node-a。
- Pod A发包进入A的host-side veth ingress
bpf_lxc; - 查询CT;
- 用Pod B IP查询IPCache得到identity 1002;
- 查询A的policy map执行egress policy;
- 查询
cilium_lxc发现B是本机endpoint; - 重定向到B veth;
- 查询B的policy map执行ingress policy;
- CT使回包按有状态连接处理。
如果A访问ClusterIP,则在上述流程前部增加Service lookup、backend选择和DNAT。
sequenceDiagram
autonumber
participant A as Pod A
participant AB as bpf_lxc A
participant CT as Conntrack
participant IPC as cilium_ipcache
participant AP as cilium_policy_A
participant L as cilium_lxc
participant BP as cilium_policy_B
participant BB as bpf_lxc B
participant B as Pod B
A->>AB: A IP → B IP
AB->>CT: CT egress lookup/create
AB->>IPC: B IP → identity 1002
AB->>AP: egress lookup(identity 1002,L4)
alt Egress deny
AP-->>A: Drop
else Egress allow
AB->>L: lookup B IP
L-->>AB: 本机ifindex/MAC
AB->>BB: redirect到B veth
BB->>BP: ingress lookup(identity 1001,L4)
alt Ingress deny
BP-->>A: Drop
else Ingress allow
BB->>B: 交付请求
B-->>CT: 响应命中reply/established
CT-->>A: 有状态返回
end
end
5. 场景二:不同节点 Pod 通信
假设Pod A在node-a,Pod B在node-b。
源节点:查询IPCache得到B identity和node-b tunnel endpoint,执行A egress CNP;overlay模式查询tunnel信息并封装,native routing模式走FIB/Linux route。
目标节点:overlay模式由bpf_overlay解封装并恢复source identity;随后查询本机cilium_lxc,执行B ingress CNP并投递B。
sequenceDiagram
autonumber
participant A as Pod A@node-a
participant AB as bpf_lxc@node-a
participant AP as cilium_policy_A
participant IPC as cilium_ipcache
participant TF as tunnel map/FIB
participant Net as Underlay
participant DB as bpf_overlay/host@node-b
participant L as cilium_lxc@node-b
participant BP as cilium_policy_B
participant B as Pod B@node-b
A->>AB: A IP → B IP
AB->>IPC: lookup B
IPC-->>AB: identity B + node-b endpoint
AB->>AP: egress policy
AP-->>AB: Allow
alt Overlay VXLAN/Geneve
AB->>TF: B prefix → node-b IP
AB->>Net: 封装node-a→node-b
Net->>DB: tunnel ingress/解封装
else Native routing
AB->>TF: FIB/route lookup B
AB->>Net: 原生IP转发
Net->>DB: physical ingress
end
DB->>L: lookup B IP
L-->>DB: B ifindex/identity
DB->>BP: ingress policy(identity A,L4)
BP-->>DB: Allow
DB->>B: redirect到B
B-->>A: 回包沿CT/反向路由
6. 场景三:普通 Pod 访问公网及下载/回包
假设:
Pod 10.244.1.10:34567
Node IP 192.168.1.10
Server 8.8.8.8:443
请求方向:Pod egress CNP检查后创建CT;出口NAT路径判断需要masquerade,在cilium_snat_v4_external创建正反向entry,执行:
10.244.1.10:34567 → 8.8.8.8:443
SNAT
192.168.1.10:40001 → 8.8.8.8:443
下载/回包方向:
- 公网回包进入物理网卡;
nodeport_lb4()查询Service未命中;- tail call到NAT ingress;
snat_v4_rev_nat()用完整反向tuple查询SNAT map;- 得到原始Pod IP/port并执行reverse-SNAT;
- recircle后查询
cilium_lxc并投递Pod; - CT识别为已建立连接回复。
sequenceDiagram
autonumber
participant P as Pod
participant L as bpf_lxc
participant Pol as Egress Policy
participant CT as Conntrack
participant NAT as cilium_snat_v4_external
participant H as bpf_host/to-netdev
participant S as Internet Server
participant IN as bpf_host/from-netdev
participant EP as cilium_lxc
P->>L: PodIP:34567 → Server:443
L->>Pol: egress lookup(world,TCP/443)
Pol-->>L: Allow
L->>CT: create CT entry
L->>H: route到物理出口
H->>NAT: create forward/reverse entries
H->>H: PodIP:34567 → NodeIP:40001
H->>S: NodeIP:40001 → Server:443
S-->>IN: Server:443 → NodeIP:40001
IN->>IN: nodeport_lb4,Service miss
IN->>NAT: reverse tuple lookup
NAT-->>IN: PodIP:34567
IN->>IN: reverse-SNAT + checksum
IN->>CT: CT reply/established
IN->>EP: lookup PodIP
EP-->>IN: Pod veth ifindex
IN-->>P: 下载数据/响应
7. 场景四:命中统一 Egress Gateway
假设Pod在node-a,Gateway在node-gw,Gateway InternalIP为192.168.1.20,指定Egress IP为203.0.113.10。
控制面预置:
Key: PodIP + 0.0.0.0/0
Value: EgressIP=203.0.113.10, GatewayIP=192.168.1.20
请求链路:
- Pod先经过普通CNP egress policy;
egress_gw_handle_packet()结合CT状态查询Egress policy map;- Gateway为远端时通过Cilium tunnel发送到Gateway;Gateway为本机则直接继续;
- Gateway再次查policy取得Egress IP;
- 选择正确出口接口并创建SNAT mapping;
- 将源Pod IP改成Egress IP后访问公网。
PodIP:34567 → Internet:443
Egress Gateway SNAT
203.0.113.10:40001 → Internet:443
回包链路:Gateway执行reverse-SNAT恢复Pod IP,反向查询Egress policy,通过IPCache得到Pod所在节点并封装回源节点,源节点解封装后投递Pod。
sequenceDiagram
autonumber
participant P as Pod@node-a
participant SB as Source Node BPF
participant CNP as Endpoint Egress Policy
participant EGP as cilium_egress_gw_policy_v4
participant T as Cilium Tunnel
participant GW as Gateway Node
participant NAT as SNAT Map@Gateway
participant S as Internet Server
participant IPC as cilium_ipcache
participant EP as cilium_lxc@node-a
P->>SB: PodIP:34567 → Internet:443
SB->>CNP: 普通CNP egress检查
CNP-->>SB: Allow
SB->>EGP: lookup(PodIP,InternetIP)
EGP-->>SB: GatewayIP + EgressIP
alt Gateway远端
SB->>T: 封装到GatewayIP
T->>GW: tunnel ingress/解封装
else Gateway本机
SB->>GW: 本机继续
end
GW->>EGP: 再查PodIP+InternetIP
EGP-->>GW: EgressIP
GW->>NAT: create SNAT/reverse entry
GW->>GW: src PodIP → EgressIP
GW->>S: EgressIP:40001 → Internet:443
S-->>GW: Internet:443 → EgressIP:40001
GW->>NAT: reverse-SNAT lookup
NAT-->>GW: PodIP:34567
GW->>EGP: reverse policy lookup
GW->>IPC: PodIP → node-a endpoint
IPC-->>GW: node-a IP/identity
GW->>T: 封装回node-a
T->>SB: 解封装
SB->>EP: lookup PodIP
EP-->>SB: Pod veth ifindex
SB-->>P: 返回数据
8. 场景五:公网访问内部 Pod
常见入口是LoadBalancer IP、NodePort、ExternalIP或Ingress/Gateway API对应的Service。假设公网客户端访问NodeIP:30080,backend为PodIP:8080。
- 物理网卡/XDP进入
nodeport_lb4(); - 查询
cilium_lb4_services_v2命中frontend; - 新连接通过Random/Maglev选择backend,已有连接从Service CT恢复backend ID;
- 查询
cilium_lb4_backends_v3得到Pod IP/port; - CT保存backend ID和rev-NAT ID;
lb4_xlate()执行DNAT;- backend本地则查
cilium_lxc并本地投递,backend远端则tunnel/native route转发; - 目标endpoint执行ingress CNP;
- NAT模式回复根据CT和reverse NAT map恢复Service frontend;DSR模式可由backend节点直接回复。
sequenceDiagram
autonumber
participant C as Public Client
participant N as LB Node NIC
participant NP as nodeport_lb4
participant SVC as cilium_lb4_services_v2
participant CT as Service/NodePort CT
participant BE as cilium_lb4_backends_v3
participant F as Tunnel/Native Routing
participant DB as Backend Node BPF
participant Pol as Backend Ingress Policy
participant P as Backend Pod
participant REV as Reverse NAT Map
C->>N: Client → NodeIP:NodePort
N->>NP: physical ingress
NP->>SVC: frontend lookup
SVC-->>NP: count/rev-NAT ID
NP->>CT: service CT lookup
alt 新连接
NP->>SVC: Random/Maglev backend slot
SVC-->>NP: backend ID
NP->>CT: 保存backend/rev-NAT
else 已有连接
CT-->>NP: 原backend ID
end
NP->>BE: backend ID lookup
BE-->>NP: PodIP:PodPort
NP->>NP: DNAT frontend → PodIP:PodPort
alt Backend本地
NP->>DB: local endpoint redirect
else Backend远端
NP->>F: tunnel/native route
F->>DB: remote ingress/decap
end
DB->>Pol: ingress CNP(client/world identity,L4)
Pol-->>DB: Allow
DB->>P: 投递请求
P-->>DB: 响应
alt NAT模式
DB->>CT: reply CT
DB->>REV: rev-NAT ID → frontend
REV-->>DB: Service IP:Port
DB-->>C: reverse NAT后返回
else DSR模式
DB-->>C: backend节点直接返回
end
如果公网可以直接路由Pod IP,则Service map不命中、SNAT reverse map通常不命中,数据包recircle到普通from-netdev,查询cilium_lxc并执行Pod ingress CNP后投递;这种情况没有Service DNAT。
9. 物理网卡 ingress 的统一分类
flowchart TD
A[Physical IPv4 ingress] --> B[nodeport_lb4]
B --> C{Service frontend命中?}
C -- Yes --> D[选择backend并DNAT]
D --> E{backend本地?}
E -- Yes --> F[Endpoint policy + local delivery]
E -- No --> G[Tunnel/native route/DSR/NAT]
C -- No --> H{DSR/NAT64特殊流量?}
H -- Yes --> I[特殊路径]
H -- No --> J[查询SNAT reverse mapping]
J --> K{命中?}
K -- Yes --> L[reverse-SNAT恢复原地址]
L --> M[recircle + endpoint/route lookup]
K -- No --> N[设置skip_nodeport并recircle]
N --> O{最终目的}
O --> P[本机Pod]
O --> Q[Host/Linux stack]
O --> R[普通路由]
关键结论:目的IP是Node IP不代表一定是节点自身流量,也可能是Pod出站回包;Cilium通过完整tuple是否命中SNAT reverse entry进行区分。DROP_NAT_NO_MAPPING在该调用点通常表示“不是NAT回包”,随后recircle,并非最终drop。skip_nodeport用于防止recircle死循环。
10. 地址转换基础实现
Service DNAT
lb4_local()选择backend后设置tuple并调用lb4_xlate();后者通过ctx_store_bytes()修改IPv4 daddr,再修改L4目标端口并更新校验和。
SNAT/reverse-SNAT
snat_v4_rewrite_headers()统一完成地址和端口改写:SNAT修改source,reverse-SNAT修改destination,然后更新IPv4和L4 checksum。
ctx_store_bytes()
- TC skb路径对应
bpf_skb_store_bytes(); - XDP路径对应
xdp_store_bytes或边界检查后的memcpy(); - skb helper可能改变底层buffer,此后通常需要
revalidate_data()。
11. 核心 BPF Map 总表
| Map | Key | Value | 写入者 | 用途 |
|---|---|---|---|---|
cilium_lxc |
本机Pod/host IP | ifindex、MAC、endpoint ID、identity | Endpoint regeneration | 本机endpoint定位 |
cilium_ipcache |
IP/prefix | identity、tunnel endpoint、encrypt key | IPCache listener | 对端身份和远端节点 |
cilium_tunnel_map |
PodCIDR/prefix | Node underlay IP、encrypt key | Node handler | overlay封装目的节点 |
cilium_policy_<id> |
identity、方向、协议、端口 | allow/deny、proxy/auth | Policy regeneration | 每endpoint CNP |
cilium_lb4_services_v2 |
frontend、slot、scope | Service元数据/backend ID | Service Manager | Service/backend选择 |
cilium_lb4_backends_v3 |
backend ID | Pod IP/port | Service Manager | DNAT目标 |
| LB reverse NAT map | rev-NAT ID | Service IP/port | Service Manager | 回复恢复frontend |
| CT maps | connection tuple | 状态、identity、backend/rev-NAT | BPF datapath | 有状态处理 |
cilium_snat_v4_external |
NAT tuple | 转换地址/端口 | BPF NAT | SNAT/reverse-SNAT |
cilium_egress_gw_policy_v4 |
PodIP + destination prefix | EgressIP + GatewayIP | Egress GW Manager | 统一出口 |
12. 关键源码索引
控制面
| 功能 | 源码 |
|---|---|
| Node事件 | pkg/node/manager/manager.go |
| Node路由/tunnel | pkg/datapath/linux/node.go |
| Tunnel Map | pkg/maps/tunnel/tunnel.go |
| BPF IPCache同步 | pkg/datapath/ipcache/listener.go |
| Endpoint Map | pkg/maps/lxcmap/lxcmap.go |
| Endpoint regeneration/policy map | pkg/endpoint/bpf.go |
| CNP watcher/parse | pkg/policy/k8s/cilium_network_policy.go |
| Policy repository | pkg/policy/repository.go |
| Policy MapState | pkg/policy/resolve.go、pkg/policy/l4.go |
| Service watcher/manager | pkg/k8s/watchers/service.go、pkg/service/service.go |
| LB Map写入 | pkg/maps/lbmap/lbmap.go |
| Egress Gateway | pkg/egressgateway/manager.go、pkg/maps/egressmap/policy.go |
数据面
| 功能 | 源码 |
|---|---|
| Pod endpoint路径 | bpf/bpf_lxc.c |
| 物理网卡/host路径 | bpf/bpf_host.c |
| Overlay路径 | bpf/bpf_overlay.c |
| XDP LB入口 | bpf/bpf_xdp.c |
| NodePort分类 | bpf/lib/nodeport.h: nodeport_lb4() |
| Service/backend/DNAT | bpf/lib/lb.h |
| Conntrack | bpf/lib/conntrack.h |
| SNAT/reverse-SNAT | bpf/lib/nat.h |
| Egress Gateway | bpf/lib/egress_gateway.h |
13. 总结
- Node/CiliumNode形成节点地址、PodCIDR、tunnel map和native routes;
- Pod/Endpoint/CEP/CES形成本机
cilium_lxc、集群cilium_ipcache、security identity和endpoint BPF; - CNP进入policy repository,按identity/L3/L4编译为每endpoint的
cilium_policy_<id>; - Service/EndpointSlice形成Service、backend、reverse-NAT和Maglev maps;
- Egress Gateway Policy形成
(PodIP, DestCIDR) → (EgressIP, GatewayIP); - 同节点Pod通过endpoint map直接重定向;
- 跨节点Pod通过IPCache/tunnel map或native route定位远端节点;
- 普通公网请求在出口节点SNAT,下载回包查reverse entry恢复Pod IP;
- 统一Gateway在源节点选Gateway,在Gateway用指定Egress IP做SNAT,并将回包送回Pod节点;
- 公网访问内部Pod通常先命中Service、选择backend并DNAT,再执行目标endpoint ingress CNP,回复通过CT/reverse NAT恢复Service视图。
最终数据包走向由以下状态共同决定:
Endpoint identity
+ CNP policy map
+ Service/backend map
+ Conntrack/NAT state
+ IPCache/tunnel/FIB
+ Egress Gateway policy