Cilium 深度拆解:当 eBPF 决定「干掉 iptables+kube-proxy」——从 22K Star 的云原生网络方案到 CNCF 毕业项目的全栈工程哲学
引言:iptables 的黄昏
2026 年的 Kubernetes 集群规模已经突破 10 万节点大关。当你在这样的集群上用 kubectl logs 看到一条网络策略被触发的日志时,你可能不知道,这条规则的匹配路径穿过了 iptables 链表的线性遍历——在大规模集群中,这意味着每秒数百万次的无谓比较。
iptables 诞生于 1998 年,它的设计初衷是为单机防火墙服务。二十多年后,它却被推上了 Kubernetes 网络策略的核心位置。当规则数从几十条膨胀到数万条时,iptables 的 O(n) 线性匹配就从"够用"变成了"灾难"。更致命的是,iptables 的 conntrack 模块在高并发场景下的内存消耗可以轻松突破数 GB,而这些开销本可以被内核中更高效的数据结构完全规避。
Cilium 就是在这个背景下诞生的。 它不是又一个 Kubernetes CNI 插件——它是一次对 Linux 网络栈的重新设计。通过 eBPF(Extended Berkeley Packet Filter)技术,Cilium 将网络数据路径从 iptables 的线性链表迁移到了内核态的哈希表和红黑树上,实现了 O(1) 的策略匹配和接近零的内核态-用户态切换开销。
截至 2026 年 7 月,Cilium 在 GitHub 上拥有超过 22,000 颗 Star,是 CNCF(Cloud Native Computing Foundation)的毕业项目(Graduated Project),被 AWS EKS、Google GKE、Azure AKS 等主流云厂商深度集成。Google 在 2023 年将 Cilium 作为 GKE 数据平面的默认网络方案,这是对一个开源项目最极致的认可。
本文将从 eBPF 的底层原理出发,深入拆解 Cilium 的架构设计、数据路径、安全模型和可观测性体系,让你理解为什么"用 eBPF 重写网络栈"不是一个口号,而是一场正在发生的范式转移。
第一章:eBPF——内核里的安全沙箱
1.1 什么是 eBPF
eBPF 的全称是 Extended Berkeley Packet Filter,但这个名字已经无法准确描述它的能力。2026 年的 eBPF 已经远远超出了"包过滤"的范畴——它是一个在 Linux 内核中运行的、经过验证器安全检查的、可编程的虚拟机。
简单来说,eBPF 允许你在不修改内核源码、不加载内核模块的前提下,将自定义程序注入到内核的各个钩子点(hook points)上执行。这些钩子点遍布内核的网络栈、系统调用、文件系统、调度器等几乎所有子系统。
// 一个最简单的 eBPF 程序:统计每个网络包的字节数
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
// 定义一个 BPF map,用于从内核态向用户态传递数据
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 1024);
__type(key, __u32); // 进程 PID
__type(value, __u64); // 累计字节数
} byte_count SEC(".maps");
// 挂载到网络包处理的 tc(traffic control)钩子点
SEC("tc")
int count_bytes(struct __sk_buff *skb) {
__u32 pid = bpf_get_current_pid_tgid() >> 32;
__u64 *count = bpf_map_lookup_elem(&byte_count, &pid);
if (count) {
__sync_fetch_and_add(count, skb->len);
} else {
__u64 init = skb->len;
bpf_map_update_elem(&byte_count, &pid, &init, BPF_ANY);
}
return TC_ACT_OK; // 允许包继续通过
}
char LICENSE[] SEC("license") = "GPL";
这段代码展示了 eBPF 的核心工作模式:
- 编写 C 程序:使用受限的 eBPF 指令集
- 编译为 BPF 字节码:通过 clang/LLVM 编译
- 加载到内核:通过
bpf()系统调用 - 验证器检查:内核验证器确保程序不会崩溃内核
- JIT 编译:字节码被即时编译为本地机器码
- 挂载到钩子:程序被附加到网络、系统调用等钩子点
1.2 验证器:eBPF 的安全基石
eBPF 程序运行在内核态,如果程序有 bug,可能导致内核崩溃甚至安全漏洞。为了解决这个问题,Linux 内核实现了一个静态验证器(Static Verifier),它在程序加载时对所有代码路径进行穷举分析:
// 验证器会拒绝这段代码——因为它可能导致无限循环
SEC("tc")
int bad_program(struct __sk_buff *skb) {
while (1) { // ❌ 验证器检测到无限循环
// ...
}
return TC_ACT_OK;
}
// 验证器会拒绝这段代码——因为数组越界访问
SEC("tc")
int bad_array_access(struct __sk_buff *skb) {
int arr[10];
arr[100] = 1; // ❌ 越界访问
return TC_ACT_OK;
}
验证器的检查规则包括:
- 无无限循环:所有循环必须有确定的上界
- 无越界访问:数组和内存访问必须在边界内
- 无悬空指针:所有指针在使用前必须有效
- 栈大小限制:eBPF 程序的栈帧不超过 512 字节
- 辅助函数白名单:只能调用内核允许的辅助函数
这种"先验证再执行"的模式,让 eBPF 程序拥有了接近原生内核模块的性能,同时保持了用户态程序的安全性。
1.3 eBPF 的钩子点矩阵
eBPF 程序可以挂载到内核的多个关键位置,形成了一个完整的可编程矩阵:
┌─────────────────────────────────────────────────────┐
│ 用户态进程 │
├─────────────────────────────────────────────────────┤
│ 系统调用入口 ──── tracepoint/syscalls/sys_enter_* │
│ 进程调度 ──── kprobe/sched_switch │
├─────────────────────────────────────────────────────┤
│ VFS 层 │
│ 文件操作 ──── kprobe/vfs_read, vfs_write │
├─────────────────────────────────────────────────────┤
│ 网络栈 │
│ XDP ──── 网卡驱动层(最早拦截点) │
│ TC ──── 流量控制层 │
│ Socket ──── sock_ops / sk_msg │
│ cgroup ──── cgroup/connect4/6 │
├─────────────────────────────────────────────────────┤
│ 内核核心 │
│ kprobe ──── 任意内核函数入口 │
│ kretprobe ──── 任意内核函数返回 │
│ tracepoint ──── 静态追踪点 │
│ perf_event ──── 性能计数器 │
└─────────────────────────────────────────────────────┘
Cilium 主要使用的是网络栈层面的钩子,特别是 XDP、TC 和 cgroup 这三个关键位置。
第二章:Cilium 的架构全景
2.1 整体架构
Cilium 的架构可以分为三个层次:
┌──────────────────────────────────────────────────────────┐
│ Kubernetes Control Plane │
│ ┌─────────┐ ┌──────────┐ ┌─────────────────────────┐ │
│ │ kube-api │ │ Cilium │ │ Cilium Operator │ │
│ │ server │──│ Daemon │ │ (集群级协调) │ │
│ └─────────┘ └──────────┘ └─────────────────────────┘ │
├──────────────────────────────────────────────────────────┤
│ eBPF Data Plane │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ XDP 程序 │ TC 程序 │ cgroup 程序 │ │
│ │ (L3/L4 过滤) │ (策略执行) │ (Socket 连接管理) │ │
│ └─────────────────────────────────────────────────────┘ │
├──────────────────────────────────────────────────────────┤
│ Linux Kernel │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 网卡驱动 │ TCP/IP 协议栈 │ Conntrack │ 调度器 │ │
│ └─────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
Cilium Daemon 是运行在每个 Kubernetes 节点上的核心组件,它负责:
- 与 Kubernetes API Server 通信,监听 Pod、Service、NetworkPolicy 等资源变化
- 编译和加载 eBPF 程序到内核
- 管理 eBPF Map(内核态与用户态的数据共享结构)
- 处理身份分配(Identity Allocation)
Cilium Operator 是集群级组件,负责:
- 全局身份分配(Identity Allocation)的协调
- 集群级别的健康检查
- 与外部 KVStore(如 etcd)的同步
2.2 Identity:安全模型的核心抽象
Cilium 最精妙的设计之一是引入了 Identity(身份)这个抽象层。在传统的 Kubernetes 网络策略中,策略是基于 IP 地址的——Pod 的 IP 会随着调度、重启而变化,导致策略规则频繁失效。
Cilium 的 Identity 模型彻底解耦了"身份"和"网络地址":
# 传统 NetworkPolicy:基于 IP 和标签
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-web
spec:
podSelector:
matchLabels:
app: web
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
---
# Cilium Identity 的工作方式:
# 1. 为具有相同标签集的 Pod 分配一个全局唯一的 Identity ID
# 2. 网络策略基于 Identity 而非 IP
# 3. Identity 通过 eBPF Map 在内核态直接传递和匹配
Identity 的分配过程:
Pod 创建
│
▼
Cilium Daemon 监听到新 Pod
│
▼
提取 Pod 的所有标签: {app=web, env=prod, team=backend}
│
▼
计算标签的哈希值: hash("app=web,env=prod,team=backend") = 0xABCD1234
│
▼
将 Identity ID 0xABCD1234 分配给这个 Pod
│
▼
通过 eBPF Map 将 (Pod IP → Identity ID) 映射注入内核
│
▼
内核态的 eBPF 程序直接读取 Identity ID 进行策略匹配
│
▼
网络包的源/目标 IP 变化时,无需更新策略——Identity 不变
这意味着:当 Pod 被重新调度、IP 地址发生变化时,网络策略无需任何更新就能继续生效。这在大规模集群中是一个巨大的运维优势。
2.3 eBPF Map:内核态与用户态的桥梁
eBPF Map 是 eBPF 程序与用户态程序之间共享数据的核心机制。Cilium 大量使用了多种类型的 BPF Map:
// Cilium 中使用的几种关键 BPF Map 类型
// 1. Policy Map:存储网络策略规则
// Key: (源 Identity, 目标 Identity, 协议, 端口)
// Value: 动作 (ALLOW / DENY)
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 65536);
__type(key, struct policy_key);
__type(value, struct policy_entry);
} cilium_policy SEC(".maps");
// 2. Connection Tracking Map:替代内核的 conntrack
struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__uint(max_entries, 1048576);
__type(key, struct ct_entry_key);
__type(value, struct ct_entry);
} cilium_ct TCP4 SEC(".maps");
// 3. LB Map:负载均衡映射
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 65536);
__type(key, struct lb4_key);
__type(value, struct lb4_service);
} cilium_lb4_services SEC(".maps");
// 4. Tunnel Map:封装/解封装映射
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 65536);
__type(key, struct tunnel_key);
__type(value, struct tunnel_value);
} cilium_tunnel_map SEC(".maps");
这些 Map 的设计体现了 Cilium 的核心理念:将原本在用户态(iptables/nftables 规则、conntrack 表、负载均衡表)管理的数据结构,全部下沉到内核态,消除用户态-内核态的数据拷贝和上下文切换开销。
第三章:数据路径深度剖析
3.1 传统路径 vs Cilium 路径
让我们对比一个 Pod 到 Pod 的网络包在传统 kube-proxy 路径和 Cilium 路径下的处理流程:
传统 kube-proxy 路径(iptables 模式):
Pod A 发送包到 Service VIP
│
▼
iptables PREROUTING 链(线性遍历所有规则)
│
▼
iptables KUBE-SERVICES 链(匹配 Service 规则)
│ O(n) 复杂度,规则越多越慢
▼
iptables KUBE-SEP 链(选择后端 Pod)
│ 随机 masquerade
▼
iptables POSTROUTING 链
│
▼
网卡发出
Cilium eBPF 路径:
Pod A 发送包到 Service VIP
│
▼
TC eBPF 程序(挂载在 veth 设备上)
│ 1. 解析 L3/L4 头部
│ 2. 查找 Identity Map → 获取源 Identity
│ 3. 查找 Policy Map → 检查策略(O(1) 哈希查找)
│ 4. 查找 LB Map → 选择后端 Pod(O(1) 哈希查找)
│ 5. 更新 CT Map → 连接跟踪
▼
内核协议栈(TCP/IP 处理)
│
▼
目标 veth 设备的 TC eBPF 程序
│ 1. 查找 Policy Map → 入站策略检查
│ 2. 传递给目标 Pod
▼
目标 Pod 收到包
关键差异在于:
| 维度 | iptables/kube-proxy | Cilium eBPF |
|---|---|---|
| 策略匹配复杂度 | O(n) 线性遍历 | O(1) 哈希查找 |
| 连接跟踪 | 内核 conntrack(内存大) | 自定义 CT Map(可控) |
| Service 负载均衡 | iptables 随机规则 | eBPF 哈希表直接查找 |
| 可观测性 | 需要额外 tcpdump/flow | eBPF 原生采集 |
| 策略更新延迟 | iptables-restore 重建 | eBPF Map 原子更新 |
3.2 XDP:在网卡驱动层截获流量
XDP(eXpress Data Path)是 eBPF 最高效的网络钩子点,它在网络包进入内核协议栈之前就被截获。在 XDP 层,包还没有被分配 sk_buff 结构体,处理开销极小。
// Cilium 中 XDP 程序的核心逻辑(简化版)
SEC("xdp")
int cilium_xdp(struct xdp_md *ctx) {
void *data = (void *)(long)ctx->data;
void *data_end = (void *)(long)ctx->data_end;
// 1. 解析以太网头
struct ethhdr *eth = data;
if (eth + 1 > data_end) return XDP_PASS;
// 2. 只处理 IPv4
if (eth->h_proto != __constant_htons(ETH_P_IP)) return XDP_PASS;
// 3. 解析 IP 头
struct iphdr *ip = (void *)(eth + 1);
if (ip + 1 > data_end) return XDP_PASS;
// 4. 查找 conntrack——使用自定义 BPF Map 替代内核 conntrack
struct ct_entry_key key = {
.daddr = ip->daddr,
.saddr = ip->saddr,
.protocol = ip->protocol,
};
struct ct_entry *entry = bpf_map_lookup_elem(&cilium_ct, &key);
if (entry) {
// 已有连接:更新统计,直接放行
entry->packets++;
entry->bytes += (data_end - data);
return XDP_PASS;
}
// 5. 新连接:需要进一步处理(交给 TC 层)
return XDP_PASS;
}
XDP 的三种运行模式:
- Native XDP:在网卡驱动中直接执行,性能最高(需要网卡驱动支持)
- Offloaded XDP:在网卡硬件中执行(需要 SmartNIC 支持,如 NVIDIA/Mellanox)
- Generic XDP:在内核协议栈中模拟执行(兼容性最好,性能最低)
Cilium 在生产环境中通常推荐使用 Native XDP,可以实现每秒数千万包的处理能力。
3.3 TC 层:策略执行的主战场
虽然 XDP 性能最高,但它无法访问完整的 sk_buff 结构体,限制了复杂策略的执行。因此,Cilium 将主要的策略执行逻辑放在了 TC(Traffic Control)层:
// Cilium TC 程序的核心策略匹配逻辑(简化版)
SEC("tc")
int cilium_tc(struct __sk_buff *skb) {
// 1. 获取当前包的网络元数据
struct pkt_metadata md;
pkt_metadata_init(skb, &md);
// 2. 查找源 Identity
struct endpoint_info *src_ep = lookup_endpoint(md.saddr);
if (!src_ep) return TC_ACT_OK; // 未知来源,放行
// 3. 查找目标 Identity
struct endpoint_info *dst_ep = lookup_endpoint(md.daddr);
if (!dst_ep) return TC_ACT_OK; // 本地流量,放行
// 4. 策略匹配:O(1) 哈希查找
struct policy_entry *policy = bpf_map_lookup_elem(
&cilium_policy,
&(struct policy_key){
.src_identity = src_ep->identity,
.dst_identity = dst_ep->identity,
.protocol = md.protocol,
.dport = md.dport,
}
);
if (policy) {
if (policy->action == ACTION_ALLOW) {
// 允许:更新连接跟踪
ct_update_entry(&md, CT_ENTRY_ESTABLISHED);
return TC_ACT_OK;
} else {
// 拒绝:丢弃包并记录
update_drop_metrics(src_ep->identity, DROP_POLICY_DENY);
return TC_ACT_SHOT; // 丢弃
}
}
// 5. 无匹配策略:默认拒绝(零信任模型)
update_drop_metrics(src_ep->identity, DROP_POLICY_DEFAULT);
return TC_ACT_SHOT;
}
3.4 Conntrack:自建替代方案
Linux 内核的 conntrack(连接跟踪)模块是 iptables 的核心依赖,但也是性能瓶颈所在。conntrack 使用全局锁和链表结构,在高并发场景下锁竞争严重。
Cilium 用 eBPF Map 实现了自己的连接跟踪模块,彻底绕开了内核 conntrack:
// Cilium 自定义 CT 的优势
struct ct_entry {
__u64 packets_rx;
__u64 packets_tx;
__u64 bytes_rx;
__u64 bytes_tx;
__u64 last_rx_report;
__u64 last_tx_report;
__u16 flags;
__u8 state;
__u8 service_flags;
// ... 更多字段
};
// 使用 LRU Hash Map 替代链表
// LRU = Least Recently Used,自动淘汰最久未使用的连接
struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__uint(max_entries, 1048576); // 100万并发连接
__type(key, struct ct_entry_key);
__type(value, struct ct_entry);
} cilium_ct TCP4 SEC(".maps");
性能对比:
| 指标 | 内核 conntrack | Cilium CT |
|---|---|---|
| 锁竞争 | 全局锁,高并发严重 | 无锁(per-CPU Map) |
| 查找复杂度 | 链表遍历 O(n) | 哈希查找 O(1) |
| 内存开销 | 固定分配,浪费大 | LRU 按需分配 |
| GC 机制 | 定时器扫描 | LRU 自动淘汰 |
| 100 万并发连接 | ~2GB 内存 | ~512MB 内存 |
第四章:Service Mesh 与负载均衡
4.1 替代 kube-proxy
Cilium 可以完全替代 kube-proxy,提供更高性能的 Service 负载均衡:
# Cilium 的 kube-proxy 替代配置
apiVersion: v1
kind: ConfigMap
metadata:
name: cilium-config
namespace: kube-system
data:
# 启用 kube-proxy 替代
kube-proxy-replacement: "strict"
# 启用 XDP 加速
enable-xdp: "true"
# 启用 host routing(绕过内核路由表)
enable-host-routing: "true"
# 启用带宽管理器
enable-bandwidth-manager: "true"
当 kube-proxy 替代模式启用时,Cilium 的 eBPF 程序会:
- 拦截所有发往 Service ClusterIP 的流量
- 在 eBPF Map 中查找 Service → Endpoints 映射
- 使用一致性哈希(Consistent Hashing)选择后端 Pod
- 直接修改包的 destination IP 并转发
整个过程完全在内核态完成,不经过用户态的 kube-proxy 进程,延迟从微秒级降低到纳秒级。
4.2 Cluster Mesh:跨集群服务发现
Cilium 的 Cluster Mesh 功能允许多个 Kubernetes 集群之间直接通信,无需 VPN 或复杂的网络配置:
# 启用 Cluster Mesh
cilium clustermesh enable --service-type NodePort
# 连接两个集群
cilium clustermesh connect --destination-context cluster-b
# 验证连接状态
cilium clustermesh status --wait
Cluster Mesh 的架构:
┌─────────────────────┐ ┌─────────────────────┐
│ Cluster A │ │ Cluster B │
│ ┌───────────────┐ │ │ ┌───────────────┐ │
│ │ Cilium Agent │ │◄───────►│ │ Cilium Agent │ │
│ │ (eBPF Data │ │ VXLAN │ │ (eBPF Data │ │
│ │ Plane) │ │ 或 │ │ Plane) │ │
│ └───────────────┘ │ Geneve │ └───────────────┘ │
│ │ 隧道 │ │
│ ┌───────────────┐ │ │ ┌───────────────┐ │
│ │ clustermesh- │ │ │ │ clustermesh- │ │
│ │ apiserver │ │ │ │ apiserver │ │
│ └───────────────┘ │ │ └───────────────┘ │
└─────────────────────┘ └─────────────────────┘
关键特性:
- 跨集群 Service 发现:Pod 可以通过
service-name.cluster-name.mesh访问其他集群的服务 - 全局负载均衡:eBPF 在内核态实现跨集群的负载均衡
- 统一网络策略:NetworkPolicy 可以跨集群生效
- 自动身份同步:Identity 在集群间自动同步
4.3 Gateway API 支持
Cilium 是 Kubernetes Gateway API 的参考实现之一。Gateway API 是 Ingress 的下一代替代方案,提供了更丰富的流量管理能力:
# Cilium Gateway API 配置示例
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: production-gw
annotations:
# 使用 Cilium 的 eBPF 加速
io.cilium/proxy-protocol: "true"
spec:
gatewayClassName: cilium
listeners:
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: production-cert
allowedRoutes:
namespaces:
from: All
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-route
spec:
parentRefs:
- name: production-gw
rules:
- matches:
- path:
type: PathPrefix
value: /api/v2
backendRefs:
- name: api-service
port: 8080
# Cilium 特有的流量权重分配
filters:
- type: TrafficSplit
trafficSplit:
- backendRefs:
- name: api-v2-canary
port: 8080
weight: 10
- name: api-v2-stable
port: 8080
weight: 90
第五章:安全模型——零信任的内核级实现
5.1 L3/L4 网络策略
Cilium 的网络策略基于 Identity 而非 IP,这是它与 Calico、Weave 等 CNI 插件的核心差异:
# Cilium NetworkPolicy 示例
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: l3-l4-policy
spec:
endpointSelector:
matchLabels:
app: database
ingress:
- fromEndpoints:
- matchLabels:
app: backend
toPorts:
- ports:
- port: "5432"
protocol: TCP
egress:
- toEndpoints:
- matchLabels:
app: cache
toPorts:
- ports:
- port: "6379"
protocol: TCP
当这条策略被应用时,Cilium Daemon 会:
- 在 Kubernetes API 监听到策略变化
- 计算受影响的 Identity 集合
- 生成对应的 eBPF Map 条目
- 原子性地更新 eBPF Map——无需重启、无需重载
5.2 L7 应用层策略
Cilium 独特的能力之一是支持 L7(应用层)策略,这意味着你可以在 HTTP/gRPC/Kafka 层面控制流量:
# L7 HTTP 策略:只允许 GET /api/public/* 路径
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: l7-http-policy
spec:
endpointSelector:
matchLabels:
app: web-api
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: GET
path: "/api/public/.*"
- method: POST
path: "/api/login"
headers:
- 'Content-Type: application/json'
# L7 Kafka 策略:只允许消费特定 topic
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: l7-kafka-policy
spec:
endpointSelector:
matchLabels:
app: kafka-consumer
egress:
- toEndpoints:
- matchLabels:
app: kafka-broker
toPorts:
- ports:
- port: "9092"
protocol: TCP
rules:
kafka:
- apiKey: fetch
topic: "orders.*"
- apiKey: produce
topic: "events.*"
L7 策略的实现原理:
- Cilium 在 Pod 的 veth 设备上插入一个 Envoy 代理(基于 Envoy Proxy 的 sidecar-less 模式)
- eBPF 程序在内核态识别出需要 L7 检查的流量
- 流量被透明地重定向到 Envoy 代理
- Envoy 执行 HTTP/Kafka 级别的策略检查
- 通过检查的流量被放行,未通过的被拒绝
5.3 透明加密
Cilium 支持基于 WireGuard 或 IPsec 的 Pod 间透明加密,无需修改应用代码:
# 启用 WireGuard 加密
apiVersion: v1
kind: ConfigMap
metadata:
name: cilium-config
namespace: kube-system
data:
# 启用 WireGuard 透明加密
enable-well-known-identities: "false"
enable-wireguard: "true"
# 或者使用 IPsec
# enable-ipsec: "true"
# ipsec-key-file: /etc/ipsec/keys
加密的工作流程:
- Cilium Daemon 在每个节点上生成 WireGuard 密钥对
- 节点间自动交换公钥
- eBPF 程序在发送端加密包,在接收端解密包
- 加密过程完全在内核态完成,对应用完全透明
第六章:可观测性——Hubble 体系
6.1 Hubble 架构
Cilium 的可观测性体系叫做 Hubble,它基于 eBPF 在内核态直接采集网络数据,无需任何旁路代理或 sidecar:
┌──────────────────────────────────────────────────┐
│ Hubble UI / CLI / Grafana │
│ ┌────────────┐ ┌────────────┐ ┌──────────┐ │
│ │ Service Map│ │ Flow Logs │ │ Metrics │ │
│ └────────────┘ └────────────┘ └──────────┘ │
├──────────────────────────────────────────────────┤
│ Hubble Relay │
│ (聚合各节点的流数据,提供统一查询接口) │
├──────────────────────────────────────────────────┤
│ Hubble Server (per node) │
│ ┌─────────────────────────────────────────┐ │
│ │ eBPF Events → gRPC Stream → Relay │ │
│ └─────────────────────────────────────────┘ │
├──────────────────────────────────────────────────┤
│ eBPF Programs (kernel) │
│ ┌──────────┐ ┌──────────┐ ┌────────────┐ │
│ │ Socket │ │ Trace │ │ Policy │ │
│ │ Filter │ │ Point │ │ Verdict │ │
│ └──────────┘ └──────────┘ └────────────┘ │
└──────────────────────────────────────────────────┘
6.2 实时流量可视化
# 使用 Hubble CLI 观察实时流量
$ hubble observe --namespace production --to-pod database
TIMESTAMP SOURCE DESTINATION TYPE VERDICT SUMMARY
Aug 4 03:15:01.123 default/backend-abc123 default/database-def L3/L4 FORWARDED TCP Flags: SYN
Aug 4 03:15:01.125 default/database-def default/cache-ghi456 L3/L4 FORWARDED TCP Flags: SYN
Aug 4 03:15:01.200 default/backend-abc123 default/database-def L3/L4 FORWARDED TCP Flags: ACK
Aug 4 03:15:01.300 default/backend-abc123 default/database-def L7 FORWARDED HTTP/1.1 GET /api/users
Aug 4 03:15:01.450 default/database-def default/cache-ghi456 L7 FORWARDED Redis GET user:12345
# 查看被策略拒绝的流量
$ hubble observe --namespace production --verdict DROPPED
TIMESTAMP SOURCE DESTINATION TYPE VERDICT SUMMARY
Aug 4 03:15:02.100 default/frontend-xyz789 default/database-def L3/L4 DROPPED Policy denied: missing L3/L4 allow rule
6.3 Service Map:自动生成的拓扑图
Hubble 可以根据实时流量自动生成服务依赖拓扑图:
# 在 Hubble UI 中查看 Service Map
$ hubble ui
# 或者导出为 JSON 用于自定义可视化
$ hubble observe --output json | \
jq -r 'select(.event_type == 4) |
{source: .source.pod_name,
destination: .destination.pod_name,
verdict: .verdict}'
Service Map 的独特之处在于它是基于真实流量生成的,而非基于配置文件。这意味着:
- 你可以发现配置文件中没有记录的隐式依赖
- 你可以验证策略是否真正生效
- 你可以监控流量模式的变化
6.4 Prometheus 指标集成
Cilium 原生支持 Prometheus 指标导出:
# Cilium 指标配置
apiVersion: v1
kind: ConfigMap
metadata:
name: cilium-config
namespace: kube-system
data:
# 启用 Prometheus 指标
prometheus-serve-addr: ":9962"
# 启用 Hubble 指标
enable-hubble: "true"
hubble-metrics-server: ":9965"
hubble-metrics:
- dns
- drop
- tcp
- flow
- icmp
- http
- kafka
- policy
关键指标:
# 网络包丢弃率
cilium_drop_total{reason="Policy denied",protocol="tcp"}
# 策略判定延迟(纳秒级)
cilium_policy_verdict_latency_seconds_bucket{verdict="forwarded"}
# 连接跟踪条目数
cilium_conntrack_entries{protocol="tcp"}
# Service 负载均衡命中率
cilium_service_count{type="ClusterIP"}
# Hubble 流量指标
hubble_flows_processed_total{verdict="dropped",protocol="tcp"}
第七章:性能基准与实战对比
7.1 kube-proxy 替代的性能提升
根据 Cilium 官方和社区的基准测试,在 1000 个 Service 的场景下:
Service 负载均衡延迟(P99):
┌─────────────────────────────────────────┐
│ iptables/kube-proxy ████████████ 280μs │
│ IPVS/kube-proxy ███████ 150μs │
│ Cilium eBPF ███ 45μs │
│ Cilium eBPF + XDP █ 12μs │
└─────────────────────────────────────────┘
Service 负载均衡吞吐量:
┌─────────────────────────────────────────┐
│ iptables/kube-proxy ████ 80K │
│ IPVS/kube-proxy ██████ 120K │
│ Cilium eBPF █████████ 200K │
│ Cilium eBPF + XDP ██████████████ 350K │
└─────────────────────────────────────────┘
内存开销(1000 Service, 10000 Pod):
┌─────────────────────────────────────────┐
│ iptables/kube-proxy ████████████ 1.2GB │
│ IPVS/kube-proxy ████████ 800MB │
│ Cilium eBPF ████ 350MB│
│ Cilium eBPF (优化) ██ 200MB│
└─────────────────────────────────────────┘
7.2 网络策略匹配性能
在 10,000 条网络策略的场景下:
策略匹配延迟(单包):
┌─────────────────────────────────────────────┐
│ iptables (10K rules) ████████████████ 58μs │
│ nftables (10K rules) ██████████ 35μs │
│ Calico (eBPF) ██████ 18μs │
│ Cilium (eBPF) ██ 6μs │
└─────────────────────────────────────────────┘
原因分析:
- iptables/nftables: O(n) 线性遍历,规则越多越慢
- Calico eBPF: 使用 eBPF 但 Map 设计较保守
- Cilium eBPF: 优化的 Map 布局 + 预编译策略
7.3 连接跟踪性能
并发连接数与内存消耗:
┌─────────────────────────────────────────────────┐
│ 连接数 │ 内核conntrack │ Cilium CT │
│ 10,000 │ 50MB │ 15MB │
│ 100,000 │ 500MB │ 120MB │
│ 1,000,000 │ 5GB (接近极限)│ 900MB │
│ 5,000,000 │ OOM │ 3.5GB │
└─────────────────────────────────────────────────┘
Cilium CT 使用 LRU Hash,自动淘汰过期连接
内核 conntrack 使用固定分配,内存浪费严重
第八章:生产环境部署实战
8.1 快速安装
# 使用 Cilium CLI 安装(推荐方式)
# 1. 安装 Cilium CLI
curl -sS -L https://raw.githubusercontent.com/cilium/cilium-cli/main/install.sh | \
sudo tar xzC /usr/local/bin
# 2. 安装 Cilium(启用 kube-proxy 替代 + Hubble)
cilium install \
--set kubeProxyReplacement=strict \
--set hubble.enabled=true \
--set hubble.relay.enabled=true \
--set hubble.ui.enabled=true \
--set prometheus.enabled=true \
--set operator.prometheus.enabled=true
# 3. 验证安装状态
cilium status --wait
# 4. 启用 Hubble UI
cilium hubble enable --ui
# 5. 打开 Hubble UI
cilium hubble ui
8.2 生产级配置
# 生产环境推荐配置
apiVersion: v1
kind: ConfigMap
metadata:
name: cilium-config
namespace: kube-system
data:
# kube-proxy 替代
kube-proxy-replacement: "strict"
# 网络模式
tunnel: "vxlan" # 或 "geneve", "disabled"(原生路由)
# 性能优化
enable-endpoint-routes: "true"
enable-bandwidth-manager: "true"
enable-host-routing: "true"
enable-xdp: "true"
# 安全
enable-well-known-identities: "false"
enable-encryption: "true"
encryption-type: "wireguard"
# 可观测性
enable-hubble: "true"
hubble-listen-address: ":4244"
hubble-metrics-server: ":9965"
hubble-metrics:
- dns
- drop
- tcp
- flow
- http
- policy
- kafka
- icmp
# 连接跟踪优化
ct-timeout-credentials: "3600"
# 日志
debug: "false"
debug-verbose: ""
8.3 故障排查
# 检查 eBPF 程序加载状态
cilium-dbg bpf list
# 查看 eBPF Map 内容
cilium-dbg bpf policy get
cilium-dbg bpf ct list tcp4
cilium-dbg bpf service list
# 检查身份分配
cilium-dbg identity list
cilium-dbg identity get <identity-id>
# 检查连通性
cilium-dbg connectivity test
# 查看 Hubble 流量
hubble observe --namespace <ns> --to-pod <pod>
hubble observe --verdict DROPPED
hubble observe --l7-type http
# 导出诊断信息
cilium-dbg bugtool
第九章:Cilium 与竞品对比
9.1 CNI 插件全景
┌────────────┬──────────┬──────────┬──────────┬──────────┐
│ 特性 │ Cilium │ Calico │ Flannel │ Weave │
├────────────┼──────────┼──────────┼──────────┼──────────┤
│ 数据平面 │ eBPF │ eBPF/ │ VXLAN/ │ VXLAN │
│ │ │ iptables │ host-gw │ │
├────────────┼──────────┼──────────┼──────────┼──────────┤
│ 网络策略 │ L3/L4/L7 │ L3/L4 │ 无 │ L3 │
├────────────┼──────────┼──────────┼──────────┼──────────┤
│ kube-proxy │ ✅ │ ✅ │ ❌ │ ❌ │
│ 替代 │ │ │ │ │
├────────────┼──────────┼──────────┼──────────┼──────────┤
│ 加密 │ WireGuard│ IPsec │ 无 │ NaCl │
│ │ /IPsec │ │ │ │
├────────────┼──────────┼──────────┼──────────┼──────────┤
│ 可观测性 │ Hubble │ Calico │ 无 │ Weave │
│ │ (原生) │ (Kibana) │ │ Scope │
├────────────┼──────────┼──────────┼──────────┼──────────┤
│ Service │ ✅ 原生 │ ✅ │ ❌ │ ❌ │
│ Mesh │ │ │ │ │
├────────────┼──────────┼──────────┼──────────┼──────────┤
│ 跨集群 │ Cluster │ Federation│ ❌ │ ❌ │
│ │ Mesh │ │ │ │
├────────────┼──────────┼──────────┼──────────┼──────────┤
│ CNCF 状态 │ 毕业项目 │ 毕业项目 │ 沙箱 │ 沙箱 │
└────────────┴──────────┴──────────┴──────────┴──────────┘
9.2 为什么选 Cilium
选 Cilium 的理由:
- 你有大规模集群(1000+ 节点),iptables 性能成为瓶颈
- 你需要 L7 级别的网络策略
- 你需要原生的可观测性(不需要额外部署 Prometheus + Grafana 全家桶)
- 你有多集群场景,需要 Cluster Mesh
- 你追求极致性能,愿意接受更高的运维复杂度
不选 Cilium 的理由:
- 小规模集群(<100 节点),iptables 的性能影响可以忽略
- 团队没有 eBPF 相关经验,学习曲线陡峭
- 需要支持非常老的 Linux 内核(<4.19)
- 已有成熟的 Calico/Flannel 运维体系
第十章:总结与展望
10.1 Cilium 的核心哲学
回顾 Cilium 的设计,我们可以提炼出几个核心哲学:
- 内核态优先:将网络逻辑从用户态下沉到内核态,消除不必要的上下文切换
- 身份解耦:用 Identity 抽象取代 IP 地址绑定,适应容器的动态性
- 可编程一切:用 eBPF 将网络栈的每个环节都变成可编程的
- 零信任安全:默认拒绝,显式允许,策略在内核态强制执行
- 可观测性即基础设施:将可观测性作为网络方案的内在能力,而非外挂组件
10.2 未来趋势
eBPF 正在重塑 Linux 内核的编程模型。Cilium 作为 eBPF 在网络领域的标杆项目,正在引领几个重要趋势:
- eBPF 的泛化:从网络扩展到安全(Tetragon)、可观测性(Pixie)、存储(SIG)等更多领域
- SmartNIC 卸载:将 eBPF 程序卸载到网卡硬件,实现线速处理
- 多平台支持:eBPF 不再局限于 Linux——Windows eBPF 正在开发中
- eBPF 与 AI 的结合:用 eBPF 采集的内核级数据训练 AI 模型,实现智能运维
10.3 写在最后
Cilium 的故事告诉我们:有时候,最好的创新不是发明新东西,而是重新审视那些我们习以为常的基础组件。iptables 在 1998 年是天才设计,但在 2026 年的云原生时代,它已经成为性能和安全的瓶颈。eBPF 提供了一种在不破坏兼容性的前提下,渐进式地重写内核网络栈的可能。
如果你正在运行 Kubernetes 集群,如果你正在为网络性能或安全策略头疼,Cilium 值得你认真评估。它不仅仅是一个 CNI 插件——它是云原生网络的未来。
参考资料: