..

Cilium:从 Kubernetes YAML 到 eBPF Map 与端到端通信链路

本文从两个方向解释 Cilium:

  1. 控制面:Node、Pod、CiliumEndpoint、Service、EndpointSlice、CiliumNetworkPolicy 和 CiliumEgressGatewayPolicy 等资源如何转化为 Linux 路由、eBPF 程序和 BPF Map;
  2. 数据面:同节点 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 会:

  1. 创建 veth pair并配置 Pod IP和路由;
  2. 创建本地 Endpoint;
  3. 根据 namespace、service account和Pod labels分配 security identity;
  4. 生成并挂载 endpoint BPF;
  5. 写本机 endpoint map cilium_lxc
  6. 创建每 endpoint policy map;
  7. 同步 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.gopkg/service/service.gopkg/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:

  1. 用 Pod selector找到匹配endpoint;
  2. 用 Node selector选择Gateway Node;
  3. 得到Gateway Node IP;
  4. 根据interface或配置推导Egress IP;
  5. 将策略展开为每个Pod IP与destination CIDR的组合;
  6. 写入 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.gopkg/maps/egressmap/policy.gobpf/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。

  1. Pod A发包进入A的host-side veth ingress bpf_lxc
  2. 查询CT;
  3. 用Pod B IP查询IPCache得到identity 1002;
  4. 查询A的policy map执行egress policy;
  5. 查询cilium_lxc发现B是本机endpoint;
  6. 重定向到B veth;
  7. 查询B的policy map执行ingress policy;
  8. 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

下载/回包方向:

  1. 公网回包进入物理网卡;
  2. nodeport_lb4()查询Service未命中;
  3. tail call到NAT ingress;
  4. snat_v4_rev_nat()用完整反向tuple查询SNAT map;
  5. 得到原始Pod IP/port并执行reverse-SNAT;
  6. recircle后查询cilium_lxc并投递Pod;
  7. 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

请求链路:

  1. Pod先经过普通CNP egress policy;
  2. egress_gw_handle_packet()结合CT状态查询Egress policy map;
  3. Gateway为远端时通过Cilium tunnel发送到Gateway;Gateway为本机则直接继续;
  4. Gateway再次查policy取得Egress IP;
  5. 选择正确出口接口并创建SNAT mapping;
  6. 将源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

  1. 物理网卡/XDP进入nodeport_lb4()
  2. 查询cilium_lb4_services_v2命中frontend;
  3. 新连接通过Random/Maglev选择backend,已有连接从Service CT恢复backend ID;
  4. 查询cilium_lb4_backends_v3得到Pod IP/port;
  5. CT保存backend ID和rev-NAT ID;
  6. lb4_xlate()执行DNAT;
  7. backend本地则查cilium_lxc并本地投递,backend远端则tunnel/native route转发;
  8. 目标endpoint执行ingress CNP;
  9. 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.gopkg/policy/l4.go
Service watcher/manager pkg/k8s/watchers/service.gopkg/service/service.go
LB Map写入 pkg/maps/lbmap/lbmap.go
Egress Gateway pkg/egressgateway/manager.gopkg/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. 总结

  1. Node/CiliumNode形成节点地址、PodCIDR、tunnel map和native routes;
  2. Pod/Endpoint/CEP/CES形成本机cilium_lxc、集群cilium_ipcache、security identity和endpoint BPF;
  3. CNP进入policy repository,按identity/L3/L4编译为每endpoint的cilium_policy_<id>
  4. Service/EndpointSlice形成Service、backend、reverse-NAT和Maglev maps;
  5. Egress Gateway Policy形成(PodIP, DestCIDR) → (EgressIP, GatewayIP)
  6. 同节点Pod通过endpoint map直接重定向;
  7. 跨节点Pod通过IPCache/tunnel map或native route定位远端节点;
  8. 普通公网请求在出口节点SNAT,下载回包查reverse entry恢复Pod IP;
  9. 统一Gateway在源节点选Gateway,在Gateway用指定Egress IP做SNAT,并将回包送回Pod节点;
  10. 公网访问内部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