基于 eBPF 的云原生网络、安全与可观测性全面解析
—— 当 Linux 内核遇上 Kubernetes,一场数据平面的革命悄然发生
"你不能用建造问题的同一种思维方式去解决它。" — 阿尔伯特·爱因斯坦
在我们深入 Cilium 的世界之前,让我们先退后一步,理解一个核心问题:为什么 Kubernetes 网络需要一场革命?
如果你读过本系列的第一部曲(eBPF 基石篇),你已经掌握了 eBPF 的核心原理——它如何让我们安全地在 Linux 内核中运行自定义程序,如何通过 Verifier 保证安全性,如何通过 Maps 实现高效数据共享。现在,让我们把目光从"底层能力"提升到"真实战场":当数以千计的容器在 Kubernetes 集群中飞速创建和销毁时,传统网络架构正面临前所未有的挑战。
让我们从一个简单的类比开始。
这就是云原生网络面临的核心矛盾:传统网络模型假设实体是静态的、长期存在的、通过 IP 地址唯一标识的——但在 Kubernetes 的世界里,这三个假设全部被颠覆了。
让我们通过一组数据来感受这种规模差异:
Kubernetes 的设计者非常聪明。他们并没有自己实现一套网络栈,而是定义了一套网络模型(Networking Model)——一个"契约",规定了必须满足的四条核心原则:
这个设计理念非常优雅,它给了生态系统巨大的灵活性。但灵活性也意味着,网络实现的质量和性能完全取决于你选择的 CNI 插件。选错了,轻则性能受损,重则安全漏洞百出。
CNI(Container Network Interface)本质上是一个极简的规范——它定义了容器运行时(如 containerd)与网络插件之间的标准接口。整个规范的核心其实就三个操作:
| CNI 操作 | 英文 | 说明 | 类比 |
|---|---|---|---|
| ADD | Add container to network | 将新创建的容器连接到网络,分配 IP、设置路由 | 新住客办理入住,分配房间号,登记前台 |
| DEL | Delete container from network | 容器销毁时,清理网络资源、释放 IP | 住客退房,收回房卡,清理登记 |
| CHECK | Check container's network | 验证容器网络配置是否仍然正确 | 夜间巡检,确认房间设施正常 |
当 kubelet 需要启动一个新 Pod 时,流程是这样的:
CNI 规范的简洁性是一把双刃剑。它使得创建新的网络插件非常容易(任何可执行文件都能成为 CNI 插件),但也意味着不同插件在功能、性能和安全性上差异巨大。这种差异,在集群规模增长到数百、数千节点时,会被无限放大。
在 Kubernetes 的默认架构中,kube-proxy 是实现 Service 负载均衡的核心组件。它运行在每一个节点上,监听 API Server 中 Service 和 Endpoints 资源的变化,然后将这些变化翻译成底层的数据平面规则。
在最常见的 iptables 模式下,kube-proxy 的工作方式是这样的:
这种方式在小规模集群下工作得很好。但问题随着规模增长而指数级恶化。让我们来仔细分析:
问题一:O(n) 线性匹配复杂度
iptables 规则是一条链(chain),数据包必须从第一条规则开始,逐条匹配,直到找到匹配的规则或到达链尾。这意味着匹配时间与规则数成正比——O(n) 复杂度。当你有 10,000 个 Service,每个 Service 有 10 个后端 Pod,那就是 100,000+ 条规则。每一个数据包都要遍历这些规则。这就像在一本 100,000 页的电话簿中,不用索引,一页一页地翻找某个人的号码。
问题二:全量更新的痛苦
每当一个 Service 的后端 Pod 变化(新增、删除、健康检查失败),kube-proxy 需要重新计算全部相关的 iptables 规则,然后通过 iptables-restore 将完整规则集一次性写入内核。在大规模集群中,一次更新可能涉及数万条规则的全量替换,这个过程会锁定 iptables,造成短暂的流量中断。据实际测量,在超过 5,000 个 Service 的集群中,单次 iptables 更新可能需要 5 秒以上。
问题三:负载均衡的粗糙
iptables 使用概率统计模块(-m statistic --mode random --probability)来实现负载均衡。这种方式只支持随机均等分配——它无法感知后端 Pod 的实际负载、响应时间或健康状态。对于现代微服务架构而言,这种原始的负载均衡方式远远不够。
问题四:可观测性的缺失
iptables 规则是一个黑盒。你很难回答这些问题:某个数据包经过了哪些规则?为什么某个连接被拒绝了?流量的延迟瓶颈在哪里?唯一的调试方式是开启 iptables LOG 目标,但这会产生海量日志并严重影响性能。
Kubernetes 社区早就意识到了 iptables 的局限性。于是,kube-proxy 在 v1.11 中将 IPVS(IP Virtual Server) 模式提升为 GA(正式版)。IPVS 是 Linux 内核中专门用于四层负载均衡的模块(基于 Netfilter 框架),它有几个显著优势:
| 维度 | iptables 模式 | IPVS 模式 | 改善 |
|---|---|---|---|
| 查找复杂度 | O(n) 线性遍历 | O(1) 哈希查找 | ✅ 大幅提升 |
| 负载均衡算法 | 仅随机 | RR / WRR / LC / WLC / SH 等 | ✅ 丰富选择 |
| 更新效率 | 全量替换 | 增量更新 | ✅ 显著改善 |
| 连接追踪 | conntrack | conntrack | 🔸 相同 |
| 仍依赖 Netfilter | 是 | 是 | ❌ 未解决 |
| L7 策略支持 | 无 | 无 | ❌ 未解决 |
| 可观测性 | 几乎没有 | 基本统计 | 🔸 略有改善 |
IPVS 确实解决了 iptables 最致命的性能问题(O(n) 查找),但它本质上仍然在 Netfilter 框架内工作。这意味着数据包仍然要经过 Linux 内核网络栈的完整路径——这个路径本身就是一个沉重的历史遗产。
要理解 Cilium(以及 eBPF)的革命性意义,我们必须先理解它要"革命"的对象——Linux 内核传统网络栈。让我们跟随一个数据包的视角,走一遍它在内核中的完整旅程:
从这张图可以清晰看到——传统网络栈的问题不在于某一个环节,而在于整个处理管线太长。一个数据包从网卡到达应用程序,要经过:硬件中断 → 软中断 → DMA 拷贝 → 协议栈解析 → PREROUTING → 路由判定 → INPUT/FORWARD → 各种 Hook → POSTROUTING → Socket。每一步都涉及内存拷贝、锁竞争和上下文切换。
提到 Netfilter,不得不深入讨论一个经常被忽视但至关重要的子系统——conntrack(Connection Tracking,连接追踪)。
conntrack 的作用是跟踪经过 Linux 内核的每一个网络连接的状态。它记录了每个连接的源 IP、源端口、目标 IP、目标端口、协议类型以及连接状态(NEW、ESTABLISHED、RELATED 等)。这些信息被存储在一个内核级的哈希表中。
conntrack 对 iptables 的正常工作至关重要——NAT 规则(如 kube-proxy 的 DNAT)需要 conntrack 来记住"这个连接的返回包应该怎么还原"。但在大规模 Kubernetes 环境中,conntrack 成为了一个严重的性能瓶颈:
| 问题 | 描述 | 实际影响 |
|---|---|---|
| 表溢出 | 默认 conntrack 表大小为 262,144 条。在高并发场景下(如 API 网关节点),连接数可能远超此限制 | 新连接被静默丢弃,表现为间歇性连接超时,极难排查 |
| 锁竞争 | conntrack 表的插入和删除操作需要获取自旋锁(spinlock),在高 PPS(每秒包数)场景下成为瓶颈 | CPU 利用率异常升高,但不表现在用户态进程上,难以定位 |
| 内存开销 | 每条 conntrack 记录占用约 300-400 字节内核内存 | 百万级连接 ≈ 300MB+ 内核不可换出内存 |
| 竞态条件 | 在 Service 后端 Pod 频繁变动时,conntrack 条目可能出现不一致,导致流量发送到已不存在的 Pod | 连接重置(RST)或超时,尤其在滚动更新期间 |
在第一部曲中,我们详细学习了 eBPF 的核心概念。现在让我们快速回顾与 Cilium 最相关的关键能力,为接下来的深入讨论做好准备:
这张映射图展示了一个核心思想:Cilium 的每一个核心功能,都是建立在 eBPF 的某个基础能力之上的。eBPF 提供了"积木",Cilium 用这些积木建造了一座"城堡"。如果说第一部曲教你认识了每一块积木的形状和特性,那么从现在开始,我们将学习如何用这些积木构建令人惊叹的工程。
让我们汇总一下 Kubernetes 网络在"Cilium 之前"面临的全景挑战:
面对这六重挑战,传统的"修补"方案(如从 iptables 升级到 IPVS,或在 Netfilter 上堆砌更多规则)已经不够了。我们需要的不是优化旧路径,而是开辟新路径。
这正是 Cilium 的使命所在。
衔接预告:既然传统方案面临四面楚歌的困境,那就一定有人试图破局。2015 年的冬天,一位名叫 Thomas Graf 的 Linux 内核网络开发者,开始思考一个大胆的想法——"如果我们把整个 Kubernetes 网络栈用 eBPF 重写呢?"这个想法的结晶,就是 Cilium。让我们在第二章一起见证这个项目的诞生和成长。
每一场革命都始于一个简单的问题。2015年,内核开发者 Thomas Graf 问道:「如果我们不再修补网络栈,而是彻底绕过它呢?」这个问题催生了 Cilium——今天超过 60% 的 Kubernetes 集群选择的 CNI。
Cilium 的故事,本质上是两条技术脉络的交汇:Linux 内核网络与云原生基础设施。要理解为什么 Cilium 能颠覆传统 CNI,我们需要回溯它的基因。
Thomas Graf,Cilium 的创始人,并非凭空出世。他在 Linux 内核网络子系统深耕超过 15 年,是内核 TC(Traffic Control)子系统和 iproute2 工具的核心维护者之一。2015 年前后,他在 Red Hat 和 Cisco 的工作中深刻体验到了 iptables 在大规模集群中的痛苦——正是我们在第一章中详细分析的那些问题。
2016 年,Graf 与 Dan Wendlandt(VMware NSX 联合创始人)共同创立了 Isovalent 公司,其核心使命只有一个:
"将 eBPF 的力量带入云原生网络、安全与可观测性,让基础设施变得透明、高效、可编程。"
关键时间线如下:
| 时间 | 里程碑 | 意义 |
|---|---|---|
| 2016 年初 | Cilium 项目在 GitHub 开源 | 首个基于 eBPF 的 CNI 实现 |
| 2017 年 2 月 | Cilium v0.8 发布 | 首次支持 L3/L4 网络策略 |
| 2018 年 4 月 | Cilium v1.0 正式发布 | 生产就绪,完整 CNI 功能 |
| 2019 年 | Google GKE Dataplane V2 选择 Cilium | 首个超大规模验证 |
| 2021 年 10 月 | Cilium 加入 CNCF(孵化阶段) | 社区治理正式化 |
| 2022 年 10 月 | Cilium 升级为 CNCF 毕业项目 | 达到最高成熟度标准 |
| 2023 年 12 月 | Cisco 收购 Isovalent | 企业级支持与集成加速 |
| 2024 年 | Cilium v1.16/v1.17 发布 | netkit 设备、BIG TCP、WireGuard 优化 |
| 2025 年 | Cilium v1.19 发布、社区突破 1,010 名开发者 | 10 年总结:24,000+ GitHub Stars,生态全面成熟 |
截至 2025 年,Cilium 的社区规模令人印象深刻:
许多人第一次接触 Cilium 时,会简单地将它归类为「一个 Kubernetes CNI 插件」。这个描述并不错误,但严重低估了 Cilium 的能力范围。让我们给出一个更精确的定义:
Cilium 是什么?
Cilium 是一个基于 eBPF 的开源项目,为 Kubernetes 及其他云原生环境提供网络(Networking)、安全(Security)和可观测性(Observability)的统一平面。它完全在 Linux 内核空间运行数据路径逻辑,无需 iptables、kube-proxy 或内核模块,实现了从 L2 到 L7 的全栈可编程控制。
为什么强调「不只是 CNI」?因为 Cilium 同时承担了以下角色:
| 传统角色 | 传统工具 | Cilium 替代方案 |
|---|---|---|
| CNI 插件 | Flannel / Calico / Weave | Cilium CNI(VXLAN / Geneve / 直接路由) |
| Service 代理 | kube-proxy(iptables/IPVS) | eBPF KPR(Kube-Proxy Replacement) |
| 网络策略引擎 | Calico Felix / Antrea | CiliumNetworkPolicy(L3-L7 + FQDN) |
| Ingress / Gateway | Nginx / Envoy / Istio | Cilium Gateway API + Envoy 集成 |
| Service Mesh 数据面 | Envoy sidecar / Linkerd | eBPF per-node 代理(无 sidecar) |
| 网络可观测性 | Wireshark / tcpdump / 商业 APM | Hubble(L3-L7 流 + 服务拓扑) |
| 运行时安全 | Falco / Sysdig | Tetragon(内核级强制执行) |
| 数据加密 | 手动 IPsec / mTLS sidecar | 透明加密(WireGuard / IPsec / ztunnel mTLS) |
这意味着 Cilium 正在 统一(Consolidate)过去需要 5-8 个独立工具才能完成的功能。根据 2025 年《State of Kubernetes Networking》报告的数据:
Cilium 源自生物学中的「纤毛」(拉丁文 cilium,复数 cilia)。纤毛是单细胞生物表面数以千计的微小毛发状结构,负责:
这恰好映射了 Cilium 的三大核心能力:
Cilium 的蜜蜂 Logo 🐝 进一步延伸了这一隐喻——蜜蜂是自然界中最高效的协作网络节点,它们通过「舞蹈语言」传递精确的路由信息(可观测性),高效地在蜂巢间转运花蜜(数据路径),同时通过蜂刺保护蜂群安全(安全策略)。
Cilium 的核心设计哲学是将三大支柱统一在同一个 eBPF 数据面上,避免功能孤岛:
这种统一的关键优势在于上下文共享——安全策略的决策可以直接输出为可观测事件,网络转发路径上的元数据可以直接用于策略匹配,无需跨工具关联日志。这在传统架构中几乎不可能实现。
让我们进行一次严肃的技术对比。以下不是营销材料,而是基于架构差异的事实分析:
| 特性维度 | Flannel | Calico | Cilium |
|---|---|---|---|
| 数据面技术 | Linux bridge + VXLAN | iptables / eBPF(可选) | eBPF(原生) |
| Service 代理 | 依赖 kube-proxy | 依赖 kube-proxy / eBPF(beta) | eBPF KPR(完全替代) |
| 网络策略 | 不支持 | L3/L4(iptables 实现) | L3-L7 + FQDN + DNS |
| 可观测性 | 无内置 | 基础流日志 | Hubble(全栈 L3-L7 + 拓扑图) |
| 加密 | 无 | WireGuard(手动) | WireGuard / IPsec / mTLS(透明) |
| 多集群 | 无 | Typha federation | ClusterMesh(去中心化 + KVStoreMesh) |
| Gateway API | 无 | 无(需第三方) | 原生支持(GatewayClass + HTTPRoute) |
| 内核模块依赖 | 需要 vxlan 模块 | 需要 ipset/iptables | 仅需 eBPF(Linux 4.19+) |
| 扩展性上限 | ~500 节点 | ~5,000 节点 | ~10,000+ 节点(OpenAI 验证) |
| 适用场景 | 开发/测试环境 | 中型生产集群 | 大规模生产 / AI / 多集群 |
⚠️ 公平声明:Calico 近年也在积极集成 eBPF(Calico eBPF 数据面),但其核心架构仍然以 iptables 为主要路径,eBPF 功能尚未达到 Cilium 的成熟度和覆盖范围。Flannel 则专注于提供最简单的 L3 网络——如果你的需求仅限于「让 Pod 互通」,Flannel 依然是最轻量的选择。
Cilium 在 2024-2025 年迎来爆发式增长并非偶然,而是多个趋势的汇聚:
① 规模爆炸:随着微服务架构的深入,生产集群从百节点增长到万节点级别(OpenAI 7,500 节点、字节跳动 20,000+ 节点)。iptables 的 O(n) 规则匹配在千级 Service 时已力不从心。
② AI/GPU 工作负载涌现:大语言模型训练中,GPU 间的参数同步(AllReduce)对网络延迟极度敏感——即使 10μs 的抖动也会导致数千个 GPU 空等。传统网络栈的多层复制和中断处理无法满足这一需求。
③ 零信任合规压力:NIST SP 800-207、PCI-DSS v4.0 等法规要求工作负载级别的微分段(Microsegmentation)。基于 IP 的策略在 Pod 生命周期仅数秒的环境中完全失效——必须基于身份。
④ 工具蔓延之苦:2025 年报告显示,73% 的组织认为多工具堆栈增加了运维复杂性。CNI + kube-proxy + NetworkPolicy controller + Service Mesh + 可观测性平台——每增加一层就增加一个故障域。
⑤ Linux 内核 eBPF 的成熟:Linux 5.x/6.x 内核引入了大量关键 eBPF 特性——BPF 链接(Link)、环形缓冲区(Ring Buffer)、kfunc、netkit 设备、BIG TCP 支持。这意味着 Cilium 终于可以在生产环境中安全、稳定地发挥全部潜力。
任何新技术都会面临合理的质疑。让我们逐一回应最常见的顾虑:
| 顾虑 | 回应 |
|---|---|
| 「eBPF 太新了,不够稳定」 | eBPF 在 Linux 内核中已存在 10+ 年(BPF 前身更超 30 年)。Cilium 的 Verifier 机制保证程序安全性——不会导致内核崩溃。Google GKE、AWS EKS、Azure AKS 均在生产中运行 Cilium。 |
| 「学习曲线太陡」 | 对于基础使用(安装 + 网络策略),Cilium 的门槛与 Calico 相当。高级功能(BGP、Gateway API)确实需要投入,但这些功能本身就有固有复杂性——Cilium 只是将它们统一到一个界面下。 |
| 「内核版本要求高」 | Cilium 最低支持 Linux 4.19(2018 年内核),覆盖所有主流发行版。高级功能(BIG TCP、netkit)确实需要 6.x 内核,但这些功能是渐进式启用的——不是必需的。 |
| 「调试 eBPF 很困难」 | Cilium 提供了丰富的调试工具:cilium monitor、cilium bpf 命令、Hubble 流日志、eBPF Map 导出。问题定位通常比 iptables 的数千条规则更容易——因为逻辑是结构化的程序,而非扁平的规则表。 |
| 「单点依赖风险」 | Cilium 是 CNCF 毕业项目,治理独立于任何公司。社区有 1,010+ 开发者来自数百家组织。Cisco 收购 Isovalent 增强了企业支持,但不改变开源治理模型。 |
2023 年 12 月,Cisco 宣布收购 Isovalent,这是 Cilium 发展历程中的重要转折点。这次收购意味着:
对开源社区而言,核心承诺是:Cilium 将保持 100% 开源,企业版在开源基础上添加管理面功能(UI、策略管理器、合规报告等),但数据面始终是相同的开源代码。
🎯 核心要点
知道了 Cilium 是什么和为什么之后,下一个自然的问题是:它到底是怎么做到的?架构层面,Cilium Agent、Operator、eBPF 程序和 Maps 是如何协同工作的?让我们在第三章中拆解 Cilium 的内部机器。
如果说第一章描述了"为什么传统方案不行",第二章回答了"为什么选 Cilium",那么本章将打开 Cilium 的引擎盖,逐层展示它的内部构造。我们将从30,000 英尺的全局视角出发,一路深入到内核空间的 eBPF 字节码,理解每一个组件的职责、交互方式以及设计取舍。
Cilium 的架构遵循一个核心原则:控制平面在用户空间,数据平面在内核空间。这并非 Cilium 独创——SDN 架构早已确立了"控制与转发分离"的理念——但 Cilium 通过 eBPF 将这一理念推向了极致:数据平面不再是独立的用户空间进程(如 OVS、Envoy sidecar),而是直接运行在内核中的可编程字节码。
下图展示了 Cilium 在一个 Kubernetes 节点上的完整组件布局:
从图中可以清晰看到,Cilium 的架构可以分为五大组件群:
| 组件 | 运行位置 | 部署形态 | 核心职责 |
|---|---|---|---|
| Cilium Agent | 用户空间 | DaemonSet | 节点级大脑:监听 K8s API,编译/加载 eBPF 程序,管理 Maps,处理 CNI 调用 |
| Cilium Operator | 用户空间 | Deployment | 集群级协调:IPAM 分配、CiliumNode 同步、GC 清理、Gateway API 管理 |
| eBPF Programs | 内核空间 | 动态加载 | 数据平面执行:转发、策略判决、负载均衡、NAT、加密、采集事件 |
| eBPF Maps | 内核空间 | pinned 文件 | 共享数据存储:策略规则、服务表、连接跟踪表、身份映射、事件 Buffer |
| Hubble | 用户空间 | 内嵌 + Relay | 可观测性:从 Perf Ring Buffer 读取事件,提供 gRPC API、CLI、UI |
| Envoy (可选) | 用户空间 | 嵌入 Agent | L7 策略执行:HTTP/gRPC/Kafka 协议解析与访问控制 |
Cilium Agent 是整个系统中最重要的用户空间组件。它以 DaemonSet 形式在每个节点上运行一个实例,承担着"翻译者"与"编排者"的双重角色——将 Kubernetes 的声明式意图(Pod、Service、NetworkPolicy、CiliumNetworkPolicy)翻译成具体的 eBPF 程序和 Map 条目。
Agent 的内部由多个子系统协作组成:
| 子系统 | 职责 | 关键实现细节 |
|---|---|---|
| K8s Watcher | 监听 API Server 资源变化 (Pod, Service, Endpoint, CNP, CCNP…) | 使用 informer/reflector 模式;支持 CRD 自定义资源 |
| CNI Plugin | 响应 kubelet 的 ADD/DEL 调用,配置 Pod 网络 | 创建 veth pair、分配 IP、挂载 eBPF 到 lxc 接口 |
| Endpoint Manager | 管理节点上所有端点 (≈Pod) 的生命周期 | 每个端点拥有独立的 eBPF 程序和 Policy Map |
| Policy Engine | 计算最终的策略判决矩阵 (Identity A→B: Allow/Deny) | 增量更新;支持 L3/L4/L7/FQDN/CIDR 规则组合 |
| Service Handler | 将 K8s Service / Endpoints 转换为 eBPF LB 规则 | 支持 ClusterIP, NodePort, LoadBalancer, ExternalIP |
| IPAM Manager | 管理 Pod IP 地址分配 | 支持 Cluster-scope, Multi-pool, AWS ENI, Azure IPAM 等多种模式 |
| eBPF Compiler | 编译 C → eBPF 字节码,通过 bpf() 系统调用加载到内核 | 使用 LLVM/Clang 后端;按端点定制编译以消除运行时分支 |
| API Server | 暴露本地 REST API 供 CLI 和调试工具使用 | 默认监听 Unix socket /var/run/cilium/cilium.sock |
#ifdef),而非在运行时做条件判断。这种"编译时特化"策略使得 eBPF 程序更小、分支更少、性能更高——这也是为什么 Cilium 的 eBPF 程序常常被称为"tailored(量身定制的)数据路径"。
与 Agent 的"每节点一个"不同,Operator 通常只有一个或两个副本(高可用部署),负责集群级别不适合在每个节点上重复执行的任务:
Hubble 是 Cilium 的可观测性子系统,其核心设计理念是"零插桩可观测"——不需要修改应用代码或注入 sidecar,就能获得 L3-L7 的全栈网络可见性。Hubble 将在第六章详细展开,这里只介绍其架构位置:
tcpdump 但具有身份感知能力Cilium 的 eBPF 数据路径擅长 L3/L4 处理,但对于需要解析 HTTP 头部、gRPC 方法名或 Kafka Topic 等 L7 协议的场景,Cilium 将流量透明重定向到嵌入式 Envoy 代理进行处理。重要区别是:
Cilium 使用多种 eBPF 程序类型,每种挂载在 Linux 网络栈的不同位置,覆盖数据包从进入到离开的完整生命周期:
下表总结了各挂载点的特性对比:
| 挂载点 | 处理阶段 | 可用操作 | 典型延迟 | Cilium 用途 |
|---|---|---|---|---|
| XDP | 驱动收包后、SKB 分配前 | DROP, PASS, TX, REDIRECT | < 1μs | DDoS 防护、DSR LB、预过滤 |
| TC Ingress | SKB 构建后、路由前 | OK, DROP, REDIRECT, 修改包头 | ~2-5μs | 身份查找、策略判决、DNAT |
| TC Egress | 路由后、发送前 | 同 TC Ingress | ~2-5μs | 出站策略、SNAT、VXLAN 封装 |
| Socket ops | TCP 连接建立/关闭时 | 拦截 connect/accept | ~0 (内联) | 同节点 Pod 绕过 TCP/IP 栈 |
| SK_MSG | 应用 sendmsg() 时 | sockmap redirect | ~0 (内联) | Socket-to-socket 直接转发 |
| cgroup | 系统调用入口 | 拦截 connect/bind/sendmsg | ~0 (内联) | Host-reachable Service、带宽管控 (EDT) |
如果 eBPF 程序是"执行逻辑",那么 eBPF Maps 就是"存储状态"。Maps 是 Cilium 架构中用户空间与内核空间之间唯一的数据交换通道,也是内核中不同 eBPF 程序之间共享状态的机制。
Cilium 使用的关键 Maps 及其技术细节:
| Map 名称 | 类型 | Key | Value | 说明 |
|---|---|---|---|---|
| cilium_ipcache | LPM Trie | IP 前缀 (CIDR) | Identity ID + Tunnel EP | IP 到安全身份的映射;支持最长前缀匹配 |
| cilium_policy_* | Hash | (Src Identity, Dst Port, Proto) | Allow/Deny + Proxy Port | 每个端点独立一份 Policy Map |
| cilium_ct4_global | Hash | 5-tuple | 连接状态 + NAT 信息 | 连接跟踪表;替代 Netfilter conntrack |
| cilium_lb4_services | Hash | VIP + Port | 后端 Slot 数量 | Service → Backend 映射 (一级) |
| cilium_lb4_backends | Hash | Backend ID | Pod IP + Port | 后端列表 (二级) |
| cilium_snat_v4 | Hash | 原始 5-tuple | 翻译后 5-tuple | SNAT 端口映射表 |
| cilium_tunnel_map | Hash | 目标 IP | 隧道远端 IP | VXLAN/Geneve 隧道端点表 |
| cilium_events | Perf Event Array | CPU ID | 事件数据 | 内核 → Hubble 事件通道 |
| cilium_signals | Perf Event Array | CPU ID | 信号类型 | CT 表满等异常信号通知 Agent |
| cilium_ep_to_policy | Hash | lxc ifindex | Endpoint ID | 网络接口 → 端点映射,用于快速定位 |
bpf(BPF_OBJ_PIN, ...) 系统调用"钉"到 BPF 文件系统 /sys/fs/bpf/。这意味着:(1) 即使创建 Map 的进程退出,Map 依然存在;(2) 不同进程(Agent 和 eBPF 程序)可以通过文件路径共享同一个 Map;(3) Agent 重启后可以直接重新打开已有 Map,无需重建。这是 Cilium 实现"数据平面独立于控制平面"的关键技术之一。
理解了各组件的职责后,让我们通过一个具体的端到端场景来串联它们——当一个新 Pod 被调度到节点时,Cilium 内部发生了什么?
整个流程的关键步骤总结如下:
| 步骤 | 触发者 | 动作 | 产物 |
|---|---|---|---|
| ① | kubelet | 调用 CNI ADD,传入 Pod 的 namespace/name、容器 ID | CNI 请求 |
| ② | Agent | 从 IPAM 分配 IP,创建 veth pair (lxcXXX ↔ eth0) | 网络命名空间配置完成 |
| ③ | Agent | 根据 Pod Labels 计算 Identity ID,写入 ipcache Map | cilium_ipcache 条目 |
| ④⑤ | Policy Engine | 遍历所有 CNP/KNP,计算此 Identity 允许的入站/出站规则 | cilium_policy_* 条目 |
| ⑥ | Agent | 根据端点配置生成定制的 C 代码,通过 LLVM 编译为 eBPF ELF | BPF 字节码对象文件 |
| ⑦ | Agent | 调用 bpf() 系统调用加载字节码,Verifier 验证安全性 | 内核中的 eBPF 程序 FD |
| ⑧ | Kernel | JIT 编译器将字节码转为原生机器码 (x86_64/ARM64) | 可执行的本机代码 |
| ⑨ | Agent | 将编译后的程序挂载到 Pod 的 lxc 接口 TC ingress/egress | 数据路径生效 |
| ⑩⑪ | Agent | 标记端点为"ready",返回 CNI 成功响应 | Pod 网络就绪 |
Pod 就绪后,所有进出该 Pod 的数据包都由 eBPF 程序在内核中处理。此时用户空间组件完全不在数据路径上。让我们看看一次典型的 Pod-to-Service 请求中,eBPF 程序和 Maps 是如何协作的:
几个关键设计亮点值得强调:
bpf_redirect_peer() 将数据包从一个 lxc 接口"传送"到另一个,绕过整个内核路由栈。这相比传统的 bridge 转发减少了多次上下文切换bpf_perf_event_output() 异步写入事件到 Perf Ring Buffer,不影响数据包的转发延迟任何架构设计都是取舍的艺术。Cilium 的架构同样有其权衡:
| 设计决策 | 优势 | 代价 |
|---|---|---|
| 按端点定制编译 eBPF | 消除运行时分支,极致性能 | 新 Pod 创建有编译延迟;需要节点上安装 LLVM 工具链(~120MB) |
| eBPF Maps 替代 iptables | O(1) 查找,确定性延迟 | Map 大小有上限(需预估容量),调试工具生态不如 iptables 成熟 |
| 控制平面与数据平面分离 | Agent 崩溃不影响现有连接 | 状态可能不一致(Agent 恢复后需同步);orphaned eBPF 程序需要 GC |
| 嵌入式 Envoy (非 sidecar) | 减少资源开销,简化部署 | 所有 Pod 的 L7 流量共享同一 Envoy,隔离性弱于 sidecar 模式 |
| 依赖较新内核特性 | 能使用最新 eBPF 能力 | 最低内核要求 ≥ 4.19(推荐 ≥ 5.10),老旧发行版可能不兼容 |
Revolutionary Datapath & Performance — 用 eBPF 重写数据平面的每一跳
前三章我们看到了"为什么需要 Cilium"以及它的架构蓝图。本章将进入 最核心的技术领域——数据路径(Datapath)。Cilium 之所以被称为"革命性",根源在于它用 eBPF 程序 彻底重写 了 Linux 内核处理网络数据包的方式:跳过 Netfilter/iptables、以 O(1) 哈希表取代 O(n) 规则链、将 XDP 推到网卡驱动层实现线速过滤。
在第一章中我们简要提到了 kube-proxy + iptables 的问题。这里我们需要更精确地量化这些瓶颈,因为它们正是 Cilium 数据路径设计所针对的 靶心。
iptables 的核心数据结构是 规则链(Chain)——一个线性的、顺序匹配的规则列表。当一个数据包进入 Netfilter 框架时,它必须 从链的第一条规则开始,逐条匹配,直到命中某条规则或到达默认策略。
| Kubernetes Service 数量 | iptables 规则数(约) | Service 更新延迟 | 规则遍历特征 |
|---|---|---|---|
| 1,000 | ~20,000 | ~1 秒 | 可接受,尾延迟偶现 |
| 5,000 | ~100,000 | ~5-10 秒 | CPU 占用明显,conntrack 表压力增大 |
| 10,000 | ~200,000 | ~30 秒+ | 全量刷新造成服务中断风险 |
| 20,000 | ~400,000 | ~2-5 分钟 | 生产不可用,规则安装期间丢包 |
即使在 IPVS 模式下,数据包仍然必须穿越 Netfilter 框架的多个钩子点(PREROUTING → INPUT/FORWARD → POSTROUTING),每个钩子点都有多张表(raw → mangle → nat → filter)需要检查。对于 Pod-to-Pod 同节点通信这样的"短路径"场景,数据包依然要走完完整的内核协议栈——这就像从北京到上海,即使有直飞航班,你却被迫先绕道广州转机。
Cilium 的核心思想可以用一句话概括:在数据包到达 Netfilter 之前就完成所有决策,或者绕过 Netfilter 直接送达目的地。
下图是本章最重要的一张图——它直观展示了 Cilium 如何"剪短"数据路径:
bpf_redirect),完全绕过了大厅里的所有排队流程。
这个性能差距不是抽象的理论——让我们用具体的数字来说话。
| 维度 | iptables 规则链 | eBPF Hash Map |
|---|---|---|
| 数据结构 | 链表(线性遍历) | 哈希表(直接寻址) |
| 查找复杂度 | O(n),n = 规则数 | O(1),与条目数无关 |
| 1,000 Service 查找 | 最坏遍历 ~10,000 条规则 | 1 次哈希计算 + 1 次内存访问 |
| 10,000 Service 查找 | 最坏遍历 ~100,000 条规则 | 仍然是 1 次哈希 + 1 次访问 |
| 更新方式 | 全量替换(atomic swap) | 单条目原子更新 |
| 更新开销 | O(n) — 全部规则重写 | O(1) — 只更新变化的条目 |
| 内存布局 | 链表节点散布,缓存不友好 | 连续内存,CPU 缓存友好 |
| 并发安全 | 需要全局锁 | Per-CPU Maps / RCU 无锁 |
除了查找性能,规则更新的代价同样是关键差距:
| 操作 | kube-proxy / iptables | Cilium / eBPF Maps |
|---|---|---|
| 触发事件 | Pod Ready → Endpoint 更新 | Pod Ready → Endpoint 更新 |
| 更新范围 | 全量重写所有 iptables 规则 | 仅更新该 Service 的 Map 条目 |
| 影响范围 | 所有 Service 的转发短暂受影响 | 仅该 Service,其他 Service 零影响 |
| 10K Service 更新耗时 | ~30 秒(全量 iptables-restore) | <1 毫秒(单条 Map 更新) |
| 对在途连接的影响 | 可能导致已有连接 RST | 无影响(RCU 保护读操作) |
| CPU 开销 | 峰值可达 100% 单核 | 可忽略不计 |
如果说 TC eBPF 是"在进门之后但到达客厅之前就处理",那 XDP 就是 "还没进门、在门口就处理完了"。XDP 是 Linux 内核提供的 最早的可编程数据包处理点,它运行在网卡驱动(NIC Driver)收到数据包之后、分配 skb(socket buffer)之前。
| 模式 | 英文名 | 运行位置 | 性能 | 硬件要求 | 适用场景 |
|---|---|---|---|---|---|
| 原生模式 | Native XDP | 网卡驱动内部 | 最高(线速) | 网卡驱动支持 XDP | 生产环境首选;Intel/Mellanox 等主流网卡均支持 |
| 卸载模式 | Offloaded XDP | 网卡硬件(SmartNIC) | 极高(不消耗 CPU) | SmartNIC(如 Netronome) | 极端性能需求,硬件成本高 |
| 通用模式 | Generic XDP | 内核网络栈(skb 分配后) | 较低(与 TC 相当) | 任何网卡 | 开发测试;不推荐生产使用 |
XDP 程序对每个数据包只能返回以下 5 种动作之一:
Cilium 利用 XDP 实现了 前置过滤(Prefilter)功能:在 NodePort Service 的入口处,XDP 程序可以在数据包进入内核协议栈之前就完成 Service 查找和负载均衡决策。对于 DDoS 攻击流量,XDP_DROP 在网卡驱动层直接丢弃恶意包——这些包 从未触碰到内核的任何内存分配器,因此攻击流量几乎不消耗系统资源。
kube-proxy replacement 是 Cilium 最广为人知的功能之一,也是许多团队采用 Cilium 的 第一个理由。根据 2025 年 Kubernetes 网络报告,49.1% 的用户已经在使用 eBPF-based kube-proxy replacement[1]。
当启用 KPR 后,Cilium Agent 会:
cilium_lb4_services_v2(IPv4)和 cilium_lb6_services_v2(IPv6)Mapcilium_lb4_backends_v3 Map| Service 类型 | eBPF 处理位置 | 处理方式 | 特殊优化 |
|---|---|---|---|
| ClusterIP | TC egress (发送端 Pod) | 在源端 Pod 的 eBPF 程序中即完成 DNAT | sockmap 可进一步跳过整个 TCP/IP 栈 |
| NodePort | XDP / TC ingress (节点物理网卡) | 在节点入口处完成 DNAT + 负载均衡 | XDP 模式下可达线速处理 |
| LoadBalancer | XDP / TC ingress | 与 NodePort 类似,额外处理外部 IP | 支持 DSR(Direct Server Return) |
| ExternalIP | TC ingress | 匹配外部 IP 后进行 DNAT | — |
| HostPort | TC ingress (节点网卡) | 替代 CNI portmap 插件 | 消除对 CNI chaining 的依赖 |
启用 KPR 只需在 Cilium Helm 安装时设置以下关键参数:
# 完全替换 kube-proxy
helm install cilium cilium/cilium \
--set kubeProxyReplacement=true \
--set k8sServiceHost=<API_SERVER_IP> \
--set k8sServicePort=<API_SERVER_PORT>
# 验证 KPR 状态
cilium status | grep KubeProxyReplacement
# 输出: KubeProxyReplacement: True [eth0 (DR, ...)]
# 此后可安全删除 kube-proxy DaemonSet
kubectl -n kube-system delete ds kube-proxy
kubectl -n kube-system delete cm kube-proxy
k8sServiceHost 和 k8sServicePort——因为没有了 kube-proxy,Cilium 需要知道如何直接连接 API Server。kubeProxyReplacement=true),而非在现有集群中迁移,以避免过渡期的规则冲突。externalTrafficPolicy 行为,请仔细阅读 Cilium KPR 文档 中的兼容性说明。
以下数据综合了 2021 年 CNI Benchmark(Thomas Graf 主导发布)以及社区后续的对比测试结果。测试条件:iperf3,TCP,单流,MTU 1500(除特别标注外)。
| CNI / 模式 | 吞吐量 (Gbps) | 相对裸金属性能 | 备注 |
|---|---|---|---|
| 裸金属 (无容器化) | 9.93 | 100% (基线) | 理论上限参考值 |
| Cilium (eBPF Direct Routing) | 9.62 | 96.9% | 🏆 最接近裸金属 |
| Cilium (eBPF VXLAN) | 9.14 | 92.0% | 隧道模式下仍优于其他 CNI |
| Calico (eBPF) | 9.42 | 94.9% | Calico 3.13+ 的 eBPF 模式 |
| Calico (IPIP) | 8.45 | 85.1% | 传统 IPIP 隧道 |
| Canal (Flannel + Calico) | 8.02 | 80.8% | 组合方案 |
| Flannel (VXLAN) | 7.41 | 74.6% | 最基础的 overlay |
| kube-router | 8.15 | 82.1% | BGP 路由模式 |
Cilium 不仅仅是"用 eBPF 替换 iptables"——它还引入了一系列 深度内核级优化技术,每一项都针对特定的性能瓶颈:
传统 Linux 网络栈中,GRO/GSO(Generic Receive/Segmentation Offload)将多个小包合并为一个大包时,受限于 16 位长度字段,单个逻辑段最大只能是 ~64KB。BIG TCP 通过扩展 IPv6 Jumbogram 支持,将 GSO 段大小提升到 最大 512KB,从而大幅减少每个逻辑段的协议栈处理次数。
# 启用 BIG TCP (Cilium Helm values)
helm upgrade cilium cilium/cilium \
--set bpf.enableBIGTCP=true
# 要求: Linux kernel ≥ 5.19, IPv6
在默认的 SNAT 模式下,NodePort/LoadBalancer 流量的 回程路径 必须经过最初接收请求的节点进行反向 NAT。DSR 模式让后端 Pod 直接回复客户端,完全跳过中间节点:
| 维度 | SNAT (默认) | DSR (Direct Server Return) |
|---|---|---|
| 回程路径 | 后端 → 入口节点 → 客户端 | 后端 → 客户端 (直接) |
| 入口节点负载 | 承担所有回程流量 | 仅处理请求,回程不经过 |
| 客户端源 IP | 被 SNAT 覆盖(除非 externalTrafficPolicy=Local) | 保留原始客户端 IP |
| 适用传输层 | TCP + UDP | TCP + UDP(通过 IP Option / IPv6 Extension Header 传递 Service 信息) |
| 延迟 | 回程增加一跳 | 回程减少一跳 |
| 带宽 | 入口节点成为瓶颈 | 回程流量分散 |
# 启用 DSR
helm upgrade cilium cilium/cilium \
--set loadBalancer.mode=dsr
Cilium 默认的负载均衡算法是随机选择后端(Random)。在某些场景(如有状态服务、连接复用)中,Maglev 一致性哈希 可以确保同一客户端(相同五元组)始终被路由到同一后端——即使后端集合发生变化,也只有最小比例的连接被重新映射。
Maglev 算法来自 Google 同名论文,其核心优势是:查找表固定大小(默认 65521,素数),O(1) 查找,且在后端增删时提供最优的 最小中断(Minimal Disruption) 保证。
# 启用 Maglev 一致性哈希
helm upgrade cilium cilium/cilium \
--set loadBalancer.algorithm=maglev \
--set maglev.tableSize=65521
自 Linux 6.7 / Cilium 1.16 起,Cilium 引入了 netkit 作为 veth pair 的替代方案。netkit 是专为 eBPF 优化的虚拟网络设备:
| 维度 | veth pair (传统) | netkit (新一代) |
|---|---|---|
| 设计目标 | 通用虚拟以太网对 | 专为 eBPF 和容器网络优化 |
| eBPF 集成 | 需要额外附加 TC 程序 | 原生 eBPF 支持,TCX 集成 |
| 处理路径 | 经过完整的网络设备子系统 | 精简路径,跳过不必要的钩子 |
| 性能 | 基线 | 延迟更低,吞吐更高 |
| 内核要求 | 任何版本 | Linux ≥ 6.7 |
| Cilium 支持 | 默认 | Cilium ≥ 1.16,通过 routingMode=native + bpf.datapathMode=netkit 启用 |
对于 同节点 Pod-to-Pod 通信(这在微服务架构中占比很高),Cilium 可以利用 BPF_MAP_TYPE_SOCKMAP 实现 Socket 级别的短路加速:
sockmap 的本质是在 Socket 层(L4 以上)直接将数据从一个 Socket 的发送缓冲区重定向到另一个 Socket 的接收缓冲区,完全跳过了 TCP/IP 协议栈的打包/拆包、veth 的帧处理、以及任何 Netfilter 钩子。这对于同节点的高频微服务调用(如 sidecar → application)可以带来 显著的延迟降低和 CPU 节省。
Cilium 的 Bandwidth Manager 使用 eBPF 实现了 基于 EDT(Earliest Departure Time)的速率限制,替代了传统的 tc-tbf 或 tc-htb qdisc。通过在 Pod 的 Kubernetes annotation 中声明带宽限制,Cilium 可以精确控制每个 Pod 的出站带宽:
# Pod 带宽限制示例
apiVersion: v1
kind: Pod
metadata:
annotations:
kubernetes.io/egress-bandwidth: "50M" # 限制出站 50Mbps
kubernetes.io/ingress-bandwidth: "100M" # 限制入站 100Mbps
与传统 tc qdisc 方案不同,EDT-based Bandwidth Manager 不引入额外的排队延迟——它通过为每个数据包打上"最早发送时间戳",让网卡按时序自然地控制发送速率。这与 Google 的 BBR 拥塞控制算法理念一致。
| 技术 | 解决的瓶颈 | 性能收益 | 最低内核版本 | Cilium 版本 | 启用方式 |
|---|---|---|---|---|---|
| KPR | kube-proxy / iptables | 延迟 ↓30-40%, 更新 O(1) | ≥4.19 | ≥1.6 | kubeProxyReplacement=true |
| XDP 加速 | NodePort 入口处理 | 线速处理,DDoS 72× 效率 | ≥4.18 | ≥1.6 | loadBalancer.acceleration=native |
| BIG TCP | 64KB GRO/GSO 限制 | IPv6 吞吐 ↑40-50% | ≥5.19 | ≥1.13 | bpf.enableBIGTCP=true |
| DSR | 回程 SNAT 瓶颈 | 回程延迟 ↓,保留源 IP | ≥4.19 | ≥1.7 | loadBalancer.mode=dsr |
| Maglev | 后端变更时连接重映射 | 最小中断一致性哈希 | ≥4.19 | ≥1.10 | loadBalancer.algorithm=maglev |
| netkit | veth pair 开销 | 更低延迟,精简路径 | ≥6.7 | ≥1.16 | bpf.datapathMode=netkit |
| sockmap | 同节点 TCP/IP 栈遍历 | Socket 层短路,延迟极低 | ≥4.19 | ≥1.4 | socketLB.hostNamespaceOnly=false |
| Bandwidth Mgr | Pod 间带宽公平性 | EDT 精确限速,无排队延迟 | ≥5.1 | ≥1.10 | bandwidthManager.enabled=true |
| bpf_redirect_peer | veth 对端 TC 二次处理 | 跳过对端 TC,减少一跳 | ≥5.10 | ≥1.10 | 自动启用(内核支持时) |
下一章,我们将从"速度"转向"安全"——看 Cilium 如何用 基于身份(Identity-based)的安全模型 彻底替代传统的 IP-based 网络策略,实现真正的云原生零信任。
[1] 数据来源:State of Kubernetes Networking Report 2025,调查对象为全球 Kubernetes 运维和开发人员。
从 "在哪里" 到 "你是谁" —— Cilium 如何用身份重写云原生安全规则
在传统数据中心里,IP 地址相对稳定——一台服务器可能数月乃至数年使用同一个 IP。因此,基于 IP 的防火墙规则(如 iptables、安全组)运行得很好。但在 Kubernetes 环境中,情况发生了根本性变化:
这个场景绝非理论推演。在大规模 Kubernetes 集群中,Pod IP 地址的平均生命周期可以短至几十秒。据 2025 年 Kubernetes 网络报告统计,73.7% 的受访者将网络策略管理列为最大挑战,其中 IP 动态变化是根因之一。
| 问题维度 | 传统数据中心 | Kubernetes 环境 | 影响 |
|---|---|---|---|
| IP 生命周期 | 月级 ~ 年级 | 秒级 ~ 分钟级 | 规则频繁失效 |
| IP 复用 | 罕见 | 极其频繁(IPAM 池小) | 身份张冠李戴 |
| 规模 | 数百规则 | 数万 ~ 数十万规则 | iptables O(n) 性能崩溃 |
| 南北/东西流量比例 | 南北流量为主 | 东西流量远超南北 | 内部横移难以防御 |
| 工作负载标识 | IP ≈ 身份 | IP ≠ 身份 | 无法用 IP 做访问控制 |
| L7 可见性 | 需要额外中间件 | 服务网格或 eBPF 提供 | 传统 L3/L4 规则粒度不够 |
Cilium 的核心安全创新是引入了 Security Identity(安全身份)这一全新抽象层。简单来说:
Security Identity 是一个集群范围唯一的数字 ID(通常是 16-bit 或更大的整数),由 Cilium 根据 Pod 的安全相关标签(security-relevant labels)自动计算生成。关键特征如下:
| 属性 | 说明 | 类比 |
|---|---|---|
| 生成方式 | 对 Pod 的安全相关标签集进行哈希运算 | 就像指纹 — 标签组合唯一决定身份 |
| 作用域 | 集群级别全局唯一 | 全国统一身份证号,各省互认 |
| 存储位置 | kvstore(etcd/CRD)+ 每个节点的 eBPF Map | 中央户籍系统 + 各地派出所副本 |
| 传播方式 | 封装在数据包头中(VXLAN/Geneve: VNI 字段 | 直接路由: 本地 ipcache Map) | 出门必带身份证 |
| 与 IP 的关系 | 通过 ipcache eBPF Map 维护 IP → Identity 映射 | 酒店前台登记本:房间号 → 住客身份 |
| 特殊 Identity | 预留 ID: 1=host, 2=world, 3=unmanaged, 4=health, 5=ingress, 6=kube-apiserver | VIP 通道 — 特殊角色有固定编号 |
app=frontend, env=prod,它们共享同一个 Identity ID。这意味着 Policy Map 中只需要一条规则就能覆盖所有 1,000 个 Pod,而传统 iptables 需要 1,000 条规则。这就是从 O(n) 到 O(1) 跨越的安全层体现。
Identity 生成后,需要在数据包传输过程中 "跟随" 数据包,让接收端知道 "这个包是谁发的"。根据组网模式不同,传播方式也不同:
| 组网模式 | 传播方式 | 技术细节 | 优缺点 |
|---|---|---|---|
| VXLAN / Geneve 隧道 | 嵌入隧道头部 VNI 字段 | 24-bit VNI 中编码 Identity ID,对底层网络完全透明 | ✅ 零额外开销 ⚠️ 受限于 VNI 位宽 |
| 直接路由 (Native Routing) | 本地 ipcache Map 查询 | 目标节点的 Cilium Agent 通过 ipcache Map 将源 IP 反查为 Identity | ✅ 无封装开销 ⚠️ 依赖 ipcache 同步时效 |
| WireGuard 加密 | IP → Identity 反查 | WireGuard 解密后,通过 ipcache 恢复 Identity(与直接路由类似) | ✅ 加密透明 ✅ 身份不泄露到网络 |
| Cluster Mesh(跨集群) | 全局 Identity 同步 | 通过 etcd 或 Cluster Mesh API Server 在集群间同步 Identity 池 | ✅ 统一跨集群策略 ⚠️ 需要 Cluster Mesh 基础设施 |
让我们跟踪一个真实的数据包,看看 Cilium 如何在内核态完成身份验证和策略裁决。场景:frontend Pod 向 api Pod 发送 HTTP 请求。
Kubernetes 自带的 NetworkPolicy 资源虽然是个好的开始,但能力非常有限。Cilium 提供了增强版的 CiliumNetworkPolicy(简称 CNP)和 CiliumClusterwideNetworkPolicy(CCNP),大幅扩展了策略表达能力。让我们逐一对比:
| 能力维度 | K8s NetworkPolicy | CiliumNetworkPolicy |
|---|---|---|
| L3 过滤(IP/CIDR) | ✅ 支持 | ✅ 支持 |
| L4 过滤(Port/Protocol) | ✅ 支持 | ✅ 支持 |
| 基于 Identity 选择器 | ❌ 仅标签选择器 | ✅ Identity-aware,标签 → Identity 自动映射 |
| L7 过滤(HTTP/gRPC/Kafka) | ❌ 不支持 | ✅ HTTP path/method, gRPC service, Kafka topic |
| DNS/FQDN 策略 | ❌ 不支持 | ✅ toFQDNs 基于域名控制出站 |
| Egress 策略 | ✅ 基本支持 | ✅ 增强:FQDN、CIDR 组、Service 选择器 |
| 集群级策略 | ❌ 仅 namespace 级 | ✅ CiliumClusterwideNetworkPolicy |
| 节点级策略 | ❌ 不支持 | ✅ CiliumClusterwideNetworkPolicy with nodeSelector |
| 默认拒绝 | ⚠️ 需手动创建空 policy | ✅ enable-policy: always 全局默认拒绝 |
| 策略审计模式 | ❌ 不支持 | ✅ Audit mode:记录但不阻断 |
| Host 防火墙 | ❌ 不支持 | ✅ 保护节点本身的流量 |
场景:只允许标签为 app=frontend 的 Pod 通过 TCP 80 端口访问标签为 app=api 的 Pod。
方案 A:Kubernetes 原生 NetworkPolicy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-api
namespace: production
spec:
podSelector:
matchLabels:
app: api # 目标 Pod
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend # 来源 Pod
ports:
- protocol: TCP
port: 80
# ⚠️ 局限:无法限制 HTTP 方法/路径
# ⚠️ 局限:无法基于 DNS 域名做出站控制
# ⚠️ 局限:只能在同一 namespace 内选择
方案 B:CiliumNetworkPolicy(增强 L7 策略)
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-frontend-to-api
namespace: production
spec:
endpointSelector:
matchLabels:
app: api # 目标 Pod (Identity-based)
ingress:
- fromEndpoints:
- matchLabels:
app: frontend # 来源 Identity
toPorts:
- ports:
- port: "80"
protocol: TCP
rules:
http: # 🔥 L7 深度控制!
- method: GET
path: "/api/v1/products"
- method: POST
path: "/api/v1/orders"
# ✅ 精细到 HTTP 方法 + 路径
# ✅ 即使 Pod IP 变化也不影响策略
# ✅ 违规请求被 Envoy 代理直接拒绝 (403)
方案 C:基于 DNS 的 Egress 控制
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: restrict-external-access
namespace: production
spec:
endpointSelector:
matchLabels:
app: frontend
egress:
- toFQDNs: # 🔥 基于域名的出站控制
- matchName: "api.stripe.com"
- matchPattern: "*.googleapis.com"
toPorts:
- ports:
- port: "443"
protocol: TCP
- toEndpoints:
- matchLabels:
"k8s:io.kubernetes.pod.namespace": kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
rules:
dns:
- matchPattern: "*"
# ✅ Pod 只能访问 Stripe API 和 Google 服务
# ✅ DNS 请求被 Cilium 拦截,自动学习 FQDN → IP 映射
# ✅ 防止数据外泄到未授权域名
toFQDNs: api.stripe.com,而不需要维护不断变化的 IP 列表。
在零信任(Zero Trust)模型中,一个核心原则是"永远不信任网络本身"——即使是集群内部的 Pod 间通信,也可能被中间人(MITM)攻击截获。Cilium 提供了开箱即用的透明加密功能,让所有 Pod 间流量自动加密,无需修改任何应用代码。
| 对比维度 | IPsec | WireGuard |
|---|---|---|
| 加密算法 | AES-CBC / AES-GCM(可配置) | ChaCha20-Poly1305(固定、现代) |
| 密钥管理 | Cilium Agent 自动轮换 Kubernetes Secret | 自动生成/交换 Curve25519 密钥对 |
| 代码复杂度 | Linux 内核 ~40 万行代码 | ~4,000 行代码(100× 更简洁) |
| 性能开销 | ~15-25% 吞吐量下降 | ~5-10% 吞吐量下降 |
| 配置复杂度 | 需管理 SA/SP/密钥轮换 | 单行 Helm 参数启用 |
| 节点间握手 | IKE/IKEv2 协商(多个 RTT) | 1-RTT 握手 |
| Identity 兼容 | ✅ 通过标记加密隧道保持 Identity | ✅ 解密后通过 ipcache 恢复 Identity |
| 适用场景 | 合规性要求特定算法(如 FIPS 140-2) | 通用场景、追求性能的环境 |
| Cilium 推荐 | 需要特定合规时使用 | ⭐ 默认推荐方案 |
启用透明加密就是这么简单:
# 使用 Helm 安装/升级 Cilium 时启用 WireGuard
helm upgrade cilium cilium/cilium \
--namespace kube-system \
--set encryption.enabled=true \
--set encryption.type=wireguard
# 验证加密状态
cilium encrypt status
# 输出示例:
# Encryption: Wireguard
# Keys in use: 1
# Max Seq. Number: 0/0xffffffff
# Errors: 0
# 验证节点间 WireGuard 隧道
cilium encrypt status --verbose
# Node Endpoint Public Key ...
# node-1 10.0.1.2:51871 aBcDeFgH1234567890...
# node-2 10.0.2.2:51871 xYzAbCdE0987654321...
零信任(Zero Trust)不是一个产品,而是一种安全哲学——"永不信任,持续验证(Never Trust, Always Verify)"。Cilium 天然支持零信任的三大支柱:
零信任的第一步,就是全局默认拒绝——没有明确允许的流量一律阻断。在 Cilium 中,有两种方式实现:
# 方式一:全局策略模式(推荐)
# 在 Cilium Helm values 中设置:
# policyEnforcementMode: "always"
# 效果:任何 endpoint 如果没有匹配的 allow 策略,所有流量默认拒绝
# 方式二:显式 Default Deny CiliumClusterwideNetworkPolicy
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: default-deny-all
spec:
endpointSelector: {} # 匹配所有 endpoint
ingress:
- {} # 空规则 = 拒绝所有入站
egress:
- {} # 空规则 = 拒绝所有出站
# ⚠️ 注意:启用后必须为每个需要通信的服务创建显式 allow 策略
# 💡 建议:先用 Audit Mode 观察,再切换到 Enforce Mode
# cilium config set policy-audit-mode enabled
作为负责任的技术白皮书,我们也需要客观审视 Cilium 的安全边界。没有任何安全方案是完美的——了解局限性,才能做出更好的防御决策。
| 攻击面/局限性 | 风险描述 | 缓解措施 |
|---|---|---|
| eBPF 程序篡改 | 具有 CAP_BPF/CAP_SYS_ADMIN 权限的攻击者可加载恶意 eBPF 程序 | 最小化特权容器;启用 BPF LSM;限制 bpf() syscall 访问;使用 Tetragon 监控 bpf 操作 |
| Cilium Agent 沦陷 | Agent 以 DaemonSet 运行,通常具有较高权限 | Agent Pod 运行 RBAC 最小化;etcd mTLS 认证;审计 Agent API 访问 |
| Identity 碰撞 | 理论上标签哈希可能碰撞(极低概率),导致错误授权 | Identity ID 空间足够大(最大 2^24);碰撞时 kvstore 检测并重新分配 |
| ipcache 同步延迟 | Pod 创建/删除时,ipcache 更新存在短暂窗口(毫秒级) | 默认拒绝策略兜底;Policy Map 在 Identity 未知时默认拒绝(Identity=world) |
| L7 代理旁路 | 若攻击者直接构造 L3/L4 合法但 L7 恶意的流量 | Envoy 代理对匹配流量做深度检查;非 HTTP 合规流量直接丢弃 |
| 供应链攻击 | 恶意 Cilium 镜像或 Helm chart | 使用官方签名镜像;SBOM 验证;Sigstore cosign 签名校验 |
| etcd/CRD 数据泄露 | Identity 和策略数据存储在 etcd 中,泄露可暴露网络拓扑 | etcd 加密存储;RBAC 限制 CiliumIdentity CR 访问;审计日志 |
| 概念 | 一句话解释 | 传统方案对比 |
|---|---|---|
| Security Identity | 基于 Pod 标签计算的全局唯一数字 ID,取代 IP 作为身份标识 | 传统: IP = 身份(K8s 中失效) |
| CiliumNetworkPolicy | 增强版网络策略,支持 L7/FQDN/集群级/审计模式 | 传统: K8s NetworkPolicy 仅 L3/L4 |
| 透明加密 | WireGuard/IPsec 自动加密所有 Pod 间流量,应用无感知 | 传统: 需要 Sidecar mTLS(如 Istio) |
| Default Deny | 未明确允许的流量一律拒绝,零信任的第一步 | 传统: K8s 默认全部允许 |
| FQDN 策略 | 基于域名的出站控制,DNS 代理自动学习 IP 映射 | 传统: 手动维护外部 IP 白名单 |
| Policy Map | eBPF 哈希表,Key = {SrcID, DstPort, Proto},O(1) 查询 | 传统: iptables 线性遍历 O(n) |
在 Kubernetes 集群中进行网络故障排查,运维工程师面临三大经典困境:
Pod 生命周期极短,tcpdump 还没抓到包,Pod 已被调度走
需要同时使用 tcpdump、conntrack、iptables-save、ss 等 6+ 工具
传统抓包只能看到 IP:Port,无法直接关联 Service/Pod 身份
根据 2025 State of Kubernetes Networking Report 的调研数据,可见性(Visibility)被评为第一大挑战,超过了安全性和性能。Hubble 的出现,正是为了终结这种"盲人摸象"式的网络运维。
Hubble 并非一个独立部署的 Agent —— 它直接内嵌在 Cilium Agent 中,利用 eBPF 数据路径已有的事件流,实现零额外探针、零代码修改、零 sidecar 的可观测性。
上图揭示了 Hubble 的三层架构设计,每层都有独立的职责:
| 组件 | 部署方式 | 职责 | 关键配置 |
|---|---|---|---|
| Hubble Server | 内嵌于 Cilium Agent(DaemonSet) | 从 eBPF 事件流中收集网络事件,存入本地环形缓冲区 | hubble.enabled=true |
| Hubble Relay | 独立 Deployment(2+ 副本) | 发现所有节点的 Hubble Server,聚合为统一 gRPC 流 | hubble.relay.enabled=true |
| Hubble UI | 独立 Deployment + Service | 基于 React 的 Web 界面,实时展示 Service Map | hubble.ui.enabled=true |
| Hubble CLI | 二进制 / kubectl plugin | 命令行实时查询流、过滤事件 | 直接连接 Relay 4245 端口 |
| Metrics Exporter | 内嵌于 Agent(Prometheus 端点) | 将流事件聚合为 Prometheus 指标 | hubble.metrics.enabled |
Hubble 的核心优势在于其数据采集完全依赖 eBPF 数据路径已有的 hook 点,无需注入 sidecar、无需修改应用代码、无需额外的网络 tap。其工作流程如下:
hubble.eventBufferCapacity 调整)。环形缓冲区是固定大小的 FIFO 队列,旧事件自动被覆盖,因此内存开销是有界的。Hubble 提供从 L3 到 L7 的全栈可观测性,每层都能回答不同的运维问题:
| 层级 | 可见信息 | 典型用途 | 示例命令 |
|---|---|---|---|
| L3/L4 | 源/目 IP、Port、协议、字节数、包计数、TCP Flags、ICMP Type | 网络连通性诊断、防火墙策略验证 | hubble observe --protocol tcp --port 80 |
| 身份层 | Security Identity、Namespace、Pod 标签、Service 名称 | 确认流量来源身份、策略关联分析 | hubble observe --from-label app=frontend |
| 策略层 | 策略判定(FORWARDED / DROPPED / REDIRECTED)、匹配的规则 ID | 安全策略审计、排查误拦截 | hubble observe --verdict DROPPED |
| DNS (L7) | DNS 查询/响应、解析的 FQDN、TTL、RCODE | DNS 故障排查、FQDN 策略验证 | hubble observe --protocol dns |
| HTTP (L7) | Method、URL、Status Code、Headers(可选) | API 延迟分析、错误率监控 | hubble observe --protocol http --http-status 500 |
| gRPC / Kafka (L7) | gRPC Method、Status;Kafka Topic、API Key | 微服务调用链分析、消息队列监控 | hubble observe --protocol kafka |
hubble.redact 配置来启用。这是因为 L7 解析需要将流量重定向到 Envoy 代理,会带来额外的性能开销。请根据实际需求有选择地开启。
当开发团队报告"Service A 无法访问 Service B"时,运维工程师可以在 30 秒内定位问题:
# 1. 查看被丢弃的流量
$ hubble observe --from-label app=service-a \
--to-label app=service-b \
--verdict DROPPED --last 20
Apr 20 09:15:32.456: default/service-a-7d8f → default/service-b-3k9x
TCP SYN (80) ── DROPPED (Policy denied)
Identity: 28451 → 39102
Policy: ingress, rule: <none matched>
# 2. 原因一目了然:service-b 没有允许 service-a 的入站策略
# 3. 修复:创建对应的 CiliumNetworkPolicy
$ kubectl apply -f - <<EOF
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-a-to-b
spec:
endpointSelector:
matchLabels:
app: service-b
ingress:
- fromEndpoints:
- matchLabels:
app: service-a
toPorts:
- ports:
- port: "80"
protocol: TCP
EOF
# 4. 验证流量恢复
$ hubble observe --from-label app=service-a \
--to-label app=service-b --last 5
Apr 20 09:16:45.789: default/service-a-7d8f → default/service-b-3k9x
TCP SYN (80) ── FORWARDED
Hubble UI 提供实时的服务依赖关系拓扑图。它能自动发现集群中所有的通信关系,以有向图的方式呈现,每条边标注协议类型、请求频率和错误率。这对于以下场景尤为强大:
Hubble 内置的 Metrics Exporter 可以将流事件聚合为 Prometheus 指标,常见指标包括:
| 指标名称 | 类型 | 描述 |
|---|---|---|
hubble_flows_processed_total | Counter | 处理的流事件总数 |
hubble_drop_total | Counter | 被丢弃的数据包总数(按原因分类) |
hubble_tcp_flags_total | Counter | TCP 标志位统计(SYN/FIN/RST) |
hubble_dns_queries_total | Counter | DNS 查询数量(按 RCODE 分类) |
hubble_http_requests_total | Counter | HTTP 请求数(按 method/status 分类) |
hubble_port_distribution_total | Counter | 端口使用分布 |
配合 Grafana,团队可以构建强大的网络监控看板:DNS 解析延迟趋势、HTTP 5xx 错误率报警、被拒绝连接的 Top-10 源等。
开源版 Hubble 使用本地环形缓冲区存储事件,这意味着事件是短暂的(通常只保留几分钟)。对于需要历史回溯、合规审计、趋势分析的企业场景,Isovalent Enterprise 提供了 Timescape 组件:
可观测性的价值只有在开销可控时才有意义。以下是 Hubble 各功能的性能影响评估:
| 功能 | CPU 开销 | 内存开销 | 延迟影响 | 推荐策略 |
|---|---|---|---|---|
| Hubble 基础(L3/L4 事件) | < 1% | ~50 MB/节点 | 不可测 | ✅ 始终开启 |
| DNS 事件 | ~1% | +10 MB | 不可测 | ✅ 始终开启 |
| Prometheus Metrics | 1-3% | +30 MB | 不可测 | ✅ 推荐开启 |
| HTTP L7 解析 | 3-8% | +100 MB(Envoy) | +0.1-0.5ms | ⚠️ 按需开启 |
| Kafka L7 解析 | 3-8% | +100 MB(Envoy) | +0.1-0.5ms | ⚠️ 按需开启 |
| Hubble Relay (集群级) | 独立 Pod | 200-500 MB | N/A | ✅ 推荐部署 |
到这里,我们已经掌握了 Cilium 的网络加速(第四章)、安全(第五章)和可观测性(第六章)三大核心能力。是时候动手实践了!下一章将提供一个完整的动手实验室,让你在真实集群中体验 Cilium 的强大功能。
本章采用交互式终端模拟方式,让你在浏览器中"亲手"完成一个完整的 Cilium 部署与安全策略实验。点击每个阶段的 Execute 按钮,终端将逐字符模拟命令执行与输出。
我们使用自定义 Kind 配置创建 4 节点集群,禁用默认 CNI 以便 Cilium 接管网络平面。
通过 Helm chart 安装 Cilium,启用 Hubble、WireGuard 加密和带宽管理器。
部署三个微服务:Death Star(帝国空间站)、TIE Fighter(帝国战机)、X-Wing(反叛军战机)。验证无策略状态下的全通连接。
创建 CiliumNetworkPolicy:仅允许带有 org=empire 标签的 Pod 访问 Death Star。反叛军 X-Wing 将被拒绝。
进一步限制:即使 TIE Fighter 可到达 Death Star,也只允许 GET /v1/request-landing,禁止 PUT /v1/exhaust-port(防止叛军渗透)。
使用 Hubble CLI 和 UI 查看策略执行结果,确认 DROPPED 和 FORWARDED 判定。
运行 cilium status 与 cilium connectivity test 进行最终验证,然后清理实验环境。
| 阶段 | 操作 | 验证结果 | 核心概念 |
|---|---|---|---|
| Phase 1 | Kind 集群创建 | 4 nodes Ready (no CNI) | CNI-less bootstrap |
| Phase 2 | Helm install Cilium | cilium status = OK | eBPF datapath 接管 |
| Phase 3 | 部署 Star Wars | 所有 Pod 可互通 | 默认 allow-all |
| Phase 4 | L3/L4 策略 | X-Wing → Death Star 被拒 | Identity-based filtering |
| Phase 5 | L7 HTTP 策略 | PUT exhaust-port 403 | Envoy proxy 注入 |
| Phase 6 | Hubble 观测 | DROPPED / FORWARDED 可视化 | eBPF-powered observability |
| Phase 7 | 验证 & 清理 | connectivity test PASS | 生产就绪性验证 |
OpenAI 运行着全球最大的 Kubernetes 集群之一,支撑 ChatGPT、GPT-4 等 AI 模型的训练与推理。他们选择 Cilium 作为唯一的 CNI 和网络基础设施,规模数据令人震撼:
OpenAI 选择 Cilium 的关键原因包括:
| 组织 | 规模 | 使用的核心功能 | 关键收益 |
|---|---|---|---|
| G-Research | 10,000+ 裸金属节点 | BIG TCP、XDP、Bandwidth Manager | 金融量化计算的高吞吐低延迟网络 |
| Datadog | 数千节点、数十集群 | Cluster Mesh、Network Policy | 跨集群服务发现、统一安全策略 |
| Adobe | 数百集群 | Hubble、WireGuard 加密 | PCI-DSS 合规、全栈可观测性 |
| Capital One | 多云、多区域 | Cluster Mesh、FQDN Policy | 金融级零信任网络隔离 |
| GitLab | GKE 上大规模 SaaS | KPR、Hubble Metrics | 30% 网络延迟改善 |
在千级以上节点的集群中,以下优化至关重要:
| 优化项 | 配置方式 | 效果 | 适用场景 |
|---|---|---|---|
| IPAM 模式选择 | ipam.mode=cluster-pool | 避免单点分配瓶颈,支持预分配 Pod CIDR | 节点数 > 500 |
| Identity GC 调优 | identity-gc-interval=30m | 减少 kvstore 写入压力 | 频繁 Pod 创建/销毁 |
| 使用 CRD-backed Identity | identityAllocationMode=crd | 消除对外部 etcd/kvstore 的依赖 | 简化运维架构 |
| 启用 Local Redirect Policy | localRedirectPolicy=true | 节点内流量不出 NIC,减少跨节点流量 | Node-local DNS cache |
| Envoy 资源限制 | envoy.resources.limits | 防止 L7 代理在突发流量下过度消耗资源 | 启用 L7 策略时 |
| Hubble 缓冲区调优 | hubble.eventBufferCapacity=16384 | 保留更长时间窗口的事件 | 高吞吐集群 |
| Maglev 负载均衡 | loadBalancer.algorithm=maglev | 一致性哈希,后端变化最小化连接重分配 | 有状态 Service |
AI/ML 训练和推理工作负载对网络有独特的需求,与传统微服务截然不同:
| AI 网络需求 | Cilium 解决方案 | 技术细节 |
|---|---|---|
| 超高吞吐(100G+) | BIG TCP | GRO/GSO 段大小从 64KB 提升到 185KB,减少中断次数,提升 CPU 效率 |
| 超低延迟 | netkit + eBPF | netkit 设备替代 veth,减少网络栈穿越层次;XDP Native 在驱动层直接处理 |
| GPU 间高效通信 | RDMA / GPUDirect 兼容 | Cilium 可与 RDMA CNI 插件链式部署(通过 CNI chaining 或 Multus) |
| 训练任务带宽保障 | Bandwidth Manager (EDT) | 基于 eBPF 的精确带宽限速,避免尽力而为的公平队列竞争 |
| 多租户 GPU 集群隔离 | CiliumNetworkPolicy | 基于身份的网络隔离,确保不同训练任务之间的流量隔离 |
| 模型推理的安全访问 | L7 策略 + FQDN 策略 | 精确控制推理服务的 API 访问权限和外部调用范围 |
| 跨集群联邦训练 | Cluster Mesh | 多集群间的 Pod-to-Pod 直连、全局 Service 发现 |
2022 年,Isovalent 开源了 Tetragon —— 一个基于 eBPF 的运行时安全可观测性与执行平台。如果说 Cilium 守护的是网络层安全,那么 Tetragon 将防护扩展到了系统调用层:
谁可以和谁通信?允许哪些 L7 请求?
进程执行了什么?访问了哪些文件?调用了哪些 syscall?
Tetragon 的核心能力包括:
Cilium + Tetragon 的组合,为云原生工作负载提供了从网络到运行时的全栈安全防护。
| 时间 | 事件 | 意义 |
|---|---|---|
| 2024.10 | Cilium 1.16 发布 | netkit 设备支持、增强的 BIG TCP、改进的 WireGuard 性能 |
| 2024.11 | Cilium 1.17 发布 | 增强 Cluster Mesh、改进 Ingress Controller、Gateway API 完善 |
| 2025.04 | IETF RFC 9669 发布 | BPF 指令集架构正式成为 IETF 标准,为 eBPF 的长期发展奠定基础 |
| 2025.H2 | Cilium 1.18 发布 | 进一步的 AI 网络优化、改进的 L7 策略性能 |
| 2026.01 | Cisco Isovalent 深度集成 | Cilium 企业版与 Cisco 网络安全产品线深度整合 |
| 2026.03 | Cilium 10 周年 | 社区回顾 10 年发展历程,从实验性项目到云原生网络标准 |
对于大型组织,单一 Kubernetes 集群往往无法满足所有需求。Cilium 的 Cluster Mesh 功能提供了优雅的多集群网络解决方案:
这对于多云(AWS + GCP + 本地)、多区域(中国 + 海外)、或灾备(Active-Active)场景尤为重要。
至此,我们已经从理论到实践、从单集群到多集群、从传统微服务到 AI 工作负载,全面了解了 Cilium 的能力。最后一章,让我们总结所学、规划行动。
| 阶段 | 时间 | 目标 | 关键行动 | 成功指标 |
|---|---|---|---|---|
| Phase 1 探索验证 |
第 1-4 周 | 技术评估与 PoC |
• Kind/Minikube 安装 Cilium • 运行 connectivity test • 部署示例应用验证 NetworkPolicy • Hubble 基础可观测性体验 |
✅ 团队完成动手实验 ✅ 技术评估报告完成 |
| Phase 2 预生产 |
第 5-12 周 | 非生产环境部署 |
• 在 staging 环境部署(含 KPR) • 迁移现有 NetworkPolicy • 开启 Hubble + Grafana 监控 • 性能基准测试 • 启用 WireGuard 加密 |
✅ 全部连通性测试通过 ✅ 性能对比数据 ≥ 预期 ✅ 运维团队完成培训 |
| Phase 3 生产上线 |
第 13-24 周 | 渐进式生产部署 |
• 灰度集群先行(canary cluster) • 逐步迁移工作负载 • 实施 CiliumNetworkPolicy 安全基线 • 建立 SRE 告警与 Runbook • 评估 Cluster Mesh / L7 策略 |
✅ 生产集群零宕机迁移 ✅ 网络延迟改善 ≥ 15% ✅ 安全策略覆盖率 100% |
| # | 陷阱 | 后果 | 规避策略 |
|---|---|---|---|
| 1 | 内核版本过低(< 5.4) | 关键 eBPF 功能不可用,降级为 iptables 模式 | 确保所有节点内核 ≥ 5.10,推荐 5.15+ 或 6.1+ |
| 2 | 未清理旧 CNI 残留 | IP 分配冲突、路由异常 | 迁移前彻底卸载旧 CNI,清理 /etc/cni/net.d 和 iptables 规则 |
| 3 | 直接在生产开启 default deny | 所有未显式允许的流量被拦截,服务大面积中断 | 先用 Hubble 观测现有流量模式,再逐步收紧策略 |
| 4 | L7 策略全局开启 | Envoy 代理增加延迟和资源消耗 | 仅对关键服务按需开启 L7 解析 |
| 5 | 忽略 Cilium Agent 资源限制 | 大规模集群中 Agent 内存不足导致重启 | 根据节点 Pod 密度设置合适的 resource limits |
| 6 | 未配置 Hubble 缓冲区大小 | 高吞吐场景下事件快速被覆盖,回溯能力不足 | 根据节点流量调整 eventBufferCapacity |
| 7 | Cluster Mesh 网段重叠 | 跨集群路由冲突 | 规划时确保每个集群的 PodCIDR 和 ClusterID 唯一 |
本文是 eBPF 技术三部曲的第二部。让我们回顾整个系列的全景:
eBPF 的历史、架构、Verifier、Map 类型、Helper 函数、开发工具链。从内核的角度理解 eBPF 是什么。
eBPF 在云原生网络中的最佳实践 —— Cilium 的架构、数据路径、安全、可观测性、生产部署。
Tetragon 运行时安全、eBPF 在安全领域的深度应用、Windows eBPF、以及 eBPF 生态的未来展望。
从 2014 年 Thomas Graf 在 Linux Plumbers Conference 上提出将 BPF 用于容器网络的构想,到 2026 年 Cilium 成为被 60.8% Kubernetes 用户选择的网络方案 —— 这 12 年的旅程,是一个技术理想从内核社区走向云原生世界的故事。
Cilium 的成功不仅仅是技术层面的胜利。它证明了一个更深刻的道理:解决问题的最佳层次,往往是最底层的那一层。当网络安全的问题在用户空间被层层代理、sidecar、iptables 规则复杂化时,eBPF 选择直接在内核中解决它们 —— 更快、更简洁、更优雅。
helm install cilium,开始你的第一次部署。
| 术语 | 英文 | 解释 | 类比 |
|---|---|---|---|
| eBPF | extended Berkeley Packet Filter | Linux 内核中的可编程虚拟机,允许在内核空间安全运行用户定义的程序 | 内核中的 "JavaScript 引擎" |
| CNI | Container Network Interface | Kubernetes 容器网络接口规范,定义了容器运行时如何配置网络 | 网络世界的 "USB 接口标准" |
| XDP | eXpress Data Path | Linux 内核中最早的数据包处理 hook 点,在驱动层直接处理,绕过整个网络栈 | 快递在大门口就被处理,不进入大楼 |
| KPR | Kube-Proxy Replacement | Cilium 使用 eBPF 完全替代 kube-proxy 的 iptables 规则实现 Service 负载均衡 | 用智能导航替代纸质路牌 |
| Security Identity | 安全身份 | Cilium 为每组具有相同标签的 Pod 分配的数字身份,用于策略执行 | 员工工牌号,而非座位号 |
| Hubble | — | Cilium 内建的网络可观测性平台,利用 eBPF 实时收集流事件 | 网络中的哈勃望远镜 |
| Cluster Mesh | 集群网格 | Cilium 的多集群网络功能,实现跨集群的 Pod 通信和 Service 发现 | 多个园区通过高速通道互联 |
| BIG TCP | — | 允许 GRO/GSO 段大小超过 64KB(最大 185KB),减少 CPU 中断次数 | 用集装箱卡车替代小面包车运货 |
| WireGuard | — | 现代加密隧道协议,Cilium 用它实现节点间透明加密 | 自动加密的专用隧道 |
| Tetragon | — | 基于 eBPF 的运行时安全可观测性与执行平台 | 内核中的安保摄像头 + 保安 |
| CiliumNetworkPolicy | — | Cilium 的自定义网络策略 CRD,支持 L3-L7 的精细访问控制 | 智能门禁系统(可识别人脸、工牌、携带物品) |
| Endpoint | 端点 | Cilium 中受管理的网络实体(通常对应一个 Pod 的网络命名空间) | 公寓楼里的每一户住户 |
| BPF Map | BPF 映射 | 内核中 eBPF 程序使用的键值存储数据结构 | 程序之间共享的公告板 |
| DSR | Direct Server Return | 负载均衡模式:响应流量直接从后端返回客户端,不经过均衡器 | 快递送达后回件不经分拣中心 |
| Maglev | — | Google 提出的一致性哈希负载均衡算法,后端变化时最小化连接重分配 | 座位安排表,新增座位不影响已有安排 |
| EDT | Earliest Departure Time | eBPF 实现的带宽管理机制,为每个包设置最早发送时间 | 高速公路匝道信号灯,控制车辆进入速率 |
Cilium 1.15+ 完整实现了 Kubernetes Gateway API(v1.0 GA),提供比传统 Ingress 更强的表达力、可移植性与安全性。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app-routes
spec:
parentRefs:
- name: cilium-gateway
namespace: infrastructure
hostnames:
- "app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /api/v2
backendRefs:
- name: api-v2-svc
port: 8080
weight: 90
- name: api-v3-canary
port: 8080
weight: 10 # 金丝雀流量切分
- matches:
- headers:
- name: x-canary
value: "true"
backendRefs:
- name: api-v3-canary
port: 8080Cilium Cluster Mesh 实现跨 Kubernetes 集群的透明 Pod-to-Pod 通信、全局服务发现和统一策略管控,无需额外 VPN 或 Gateway。
🏦 Sicredi(巴西最大合作银行之一)通过 Cilium Cluster Mesh 实现:
"Cilium Cluster Mesh 让我们的多集群管理从噩梦变成了标准操作。" — Sicredi Platform Team
# 在两个集群上分别启用 cilium clustermesh enable --service-type LoadBalancer # 建立连接 cilium clustermesh connect --destination-context ctx-cluster-b # 验证 cilium clustermesh status # ✅ Cluster A ⟷ Cluster B: connected (latency: 12ms) # 共享 identities: 247, 共享 services: 18 # 创建全局服务 kubectl annotate service api-svc \ service.cilium.io/global="true" \ service.cilium.io/affinity="local" # 优先本地,故障时跨集群
基于公开用户报告(OpenAI、G-Research、Adobe、Datadog 等),以下是 Cilium 的典型投资回报数据:
| 成本项 | 传统方案 (Calico + Istio + Prometheus) | Cilium 统一方案 | 节省 |
|---|---|---|---|
| CNI 许可/支持 | $0 (OSS) | $0 (OSS) | — |
| Sidecar CPU 开销 | ~2000 vCPU (0.5/pod × 4000 pods) | 0 vCPU | $876K/yr |
| Sidecar 内存开销 | ~400 GB (100MB/pod) | 0 GB | $192K/yr |
| 可观测性堆栈 | Prometheus + Grafana + Jaeger | Hubble (内建) | $85K/yr |
| 运维团队 FTE | 3 FTE (网络+安全+观测) | 1.5 FTE | $225K/yr |
| 3 年 TCO | ~$4.13M | ~$2.01M | $2.12M (51%) |
Cilium 提供内核级服务网格能力,在不注入 Sidecar 代理的情况下实现 mTLS、流量管理、重试、超时和可观测性。
| 能力 | Istio (Sidecar) | Cilium Service Mesh (eBPF) |
|---|---|---|
| mTLS | Envoy sidecar 双向 TLS | WireGuard (L3) 或 SPIFFE mTLS (L7) |
| L7 流量管理 | VirtualService + DestinationRule | CiliumEnvoyConfig + Gateway API |
| 重试/超时 | Envoy 配置 | 内嵌 Envoy per-node (非 per-pod) |
| 可观测性 | Kiali + Jaeger | Hubble (L3-L7, 无采样) |
| 资源开销 | ~100MB/pod + 0.5 vCPU/pod | ~40MB/node (DaemonSet) |
| 启动延迟 | +2-5s per pod (sidecar inject) | 0 (无注入) |
| 网络跳数 | +2 (ingress/egress sidecar) | 0 额外跳数 (eBPF shortcut) |
| SPIFFE 身份 | ✅ (Citadel) | ✅ (Cilium SPIRE 集成) |
apiVersion: cilium.io/v2
kind: CiliumEnvoyConfig
metadata:
name: l7-lb-example
spec:
services:
- name: my-service
namespace: production
backendServices:
- name: my-service
namespace: production
resources:
- "@type": type.googleapis.com/envoy.config.listener.v3.Listener
name: l7-lb-listener
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: l7-lb
route_config:
virtual_hosts:
- name: my-service
domains: ["*"]
routes:
- match: { prefix: "/" }
route:
weighted_clusters:
clusters:
- name: "production/my-service"
weight: 95
- name: "production/my-service-canary"
weight: 5
retry_policy:
retry_on: "5xx"
num_retries: 3Cilium 1.13+ 内建 BGP 控制平面,允许节点直接与 ToR 交换机建立 BGP 对等,通告 Pod CIDR 和 Service VIP — 无需 MetalLB 或外部 BGP speaker。
apiVersion: cilium.io/v2alpha1
kind: CiliumBGPPeeringPolicy
metadata:
name: rack01-peering
spec:
nodeSelector:
matchLabels:
rack: "01"
virtualRouters:
- localASN: 65001
exportPodCIDR: true
serviceSelector:
matchExpressions:
- { key: bgp-announce, operator: In, values: ["true"] }
neighbors:
- peerAddress: "10.0.0.1/32" # ToR switch A
peerASN: 65000
eBGPMultihopTTL: 2
gracefulRestart:
enabled: true
restartTimeSeconds: 120
- peerAddress: "10.0.0.2/32" # ToR switch B (redundancy)
peerASN: 650002025–2026 年,内存价格持续飙升,给企业带来不小的成本压力。 当硬件成本成为不可控变量时,唯一的杠杆就是软件效能—— Cilium 通过 eBPF 内核级优化,在 不增加任何硬件 的前提下, 释放 30-70% 的闲置资源,将"摩尔定律放缓"的压力转化为运维成本下降的红利。
本章从四个维度量化 Cilium 如何帮助企业在硬件涨价周期中守住利润线: Sidecar 消除、kube-proxy 替换、 数据路径加速、以及 ClusterMesh 资源共享。 每一项都附带可落地的配置、真实基准数据和 ROI 计算公式。
传统 Sidecar 模式好比给公寓楼里每一户都安装独立的净水系统—— 1,000 户就要 1,000 套设备、1,000 份维保合同。 Cilium 的 per-node 模型则是在每层楼装一台集中净水器, 10 层楼只需 10 台——效果相同,成本降低两个数量级。
| 指标 | Istio Sidecar | Cilium Per-Node | 节省幅度 |
|---|---|---|---|
| 代理实例数 | 1,000(每 Pod 1个) | 10(每 Node 1个) | ↓ 99% |
| 总内存占用 | 50 GB | 1.2 GB | ↓ 97.6% |
| 总 CPU 占用 | 100 vCPU | 2 vCPU | ↓ 98% |
| Pod 启动延迟 | +300~800 ms | 0 ms | ↓ 100% |
| 配置复杂度 | 每 Pod 注入 + mTLS bootstrap | Node 级别统一管理 | 大幅简化 |
| L7 策略能力 | 完整(Envoy 全功能) | 完整(可选 Envoy per-node) | 功能对等 |
| 年化成本(AWS m5.xlarge) | ~$180,000 | ~$5,400 | ↓ 97% |
# 安装 Cilium 并启用 Ingress + Gateway API(无 Sidecar) $ helm upgrade --install cilium isovalent/cilium \ --namespace kube-system \ --set ingressController.enabled=true \ --set gatewayAPI.enabled=true \ --set envoyConfig.enabled=true \ --set socketLB.enabled=true \ --set l7Proxy=true # 验证:Pod 中不再有 Sidecar 容器 $ kubectl get pods -n demo -o jsonpath='{range .items[*]}{.metadata.name}: {range .spec.containers[*]}{.name} {end}{"\n"}{end}' frontend-7b9d5c8f4-xk2pq: frontend backend-6c8b7d9e3-m4npv: backend database-5a7c9e2f1-r8stw: database # 对比:Istio 注入后同样的 Pod frontend-7b9d5c8f4-xk2pq: frontend istio-proxy backend-6c8b7d9e3-m4npv: backend istio-proxy database-5a7c9e2f1-r8stw: database istio-proxy
在拥有 10,000 个 Service 的集群中,kube-proxy 需要维护约
40,000+ 条 iptables 规则。每条规则按顺序匹配(O(n)),
每次 Service 变更触发全量重写。Cilium 的 eBPF 实现使用 哈希表
直接跳转(O(1)),且增量更新——这就是 72× CPU 降幅的根源。
算法复杂度决定硬件需求——当规则数 n 从 100 增长到 10,000 时: iptables 的 CPU 消耗线性增长 100×,而 eBPF HashMap 保持恒定。 这意味着集群越大,Cilium 的成本优势越显著——这是一个超线性回报。
| 指标 | kube-proxy (iptables) | kube-proxy (ipvs) | Cilium KPR (eBPF) |
|---|---|---|---|
| 查找复杂度 | O(n) 线性 | O(log n) 哈希 | O(1) 常数 |
| 规则更新 | 全量重写 | 增量更新 | 增量更新 |
| 10K Service CPU | 7.2 vCPU | 1.8 vCPU | 0.1 vCPU |
| conntrack 开销 | 高(内核 ct) | 高(内核 ct) | 低(eBPF ct) |
| DSR(直接服务返回) | ❌ | ❌ | ✅ |
| Maglev 哈希 | ❌ | ❌ | ✅ |
| Session Affinity | ✅(iptables 模块) | ✅ | ✅(eBPF Map) |
| Socket-level LB | ❌ | ❌ | ✅(绕过整个 netfilter) |
# 安装 Cilium 并完全替换 kube-proxy $ helm upgrade --install cilium isovalent/cilium \ --namespace kube-system \ --set kubeProxyReplacement=true \ --set k8sServiceHost="${API_SERVER_IP}" \ --set k8sServicePort=6443 \ --set socketLB.enabled=true \ --set bpf.masquerade=true \ --set bpf.tproxy=true # 删除 kube-proxy DaemonSet $ kubectl -n kube-system delete ds kube-proxy $ kubectl -n kube-system delete cm kube-proxy # 验证 KPR 状态 $ cilium status | grep KubeProxyReplacement KubeProxyReplacement: True [eth0 (Direct Routing), XDP] # 验证 iptables 规则已清空 $ iptables-save | grep -c KUBE 0
传统 veth 对好比用小货车运货——每趟最多装 1.5 吨(MTU 1500), 路上还要经过 3 个收费站(netfilter hooks)。 Netkit + BIG TCP 则是换成集装箱卡车(GRO/GSO 聚合到 192KB) 并开辟高速直通道(跳过收费站)——同样的路,运量提升 50%。
| 技术 | 原理 | 吞吐提升 | 延迟改善 | 内核要求 |
|---|---|---|---|---|
| Netkit | 替代 veth pair,跳过 host namespace 网络栈 | +40% | -30% | 6.8+ |
| BIG TCP (IPv4/v6) | GRO/GSO 聚合到 192KB,减少 per-packet 开销 | +50% | -20% | 6.3+ |
| XDP | NIC 驱动层处理,绕过整个内核网络栈 | +10× (pps) | -80% | 4.18+ |
| sockmap/sockLB | socket 层直接转发,跳过 TCP/IP 栈 | +60% (localhost) | -50% | 5.4+ |
| DSR (Direct Server Return) | 回包不经过 LB 节点,减少一跳 | +25% (回程) | -40% | 4.18+ |
| Bandwidth Manager | EDT (Earliest Departure Time) + FQ 调度 | 改善尾部延迟 | P99 -40% | 5.1+ |
在 10-node 集群中,假设当前使用 m5.2xlarge(8 vCPU, 32 GB):
启用 Netkit + BIG TCP 后,同等吞吐可降级到 m5.xlarge(4 vCPU, 16 GB),
每 Node 年省 $1,752,10 Node 共省 $17,520/年,
相当于硬件升级周期延长 2-3 年。
在多集群架构中,传统做法是在每个集群独立部署全套中间件 (Kafka、Redis、Monitoring Stack),造成大量资源重复。 Cilium ClusterMesh 通过跨集群 Service 发现和负载均衡, 允许多个集群共享同一套基础服务——直接削减 30-50% 的冗余部署。
# 在所有集群上启用 ClusterMesh $ cilium clustermesh enable --service-type LoadBalancer # 连接集群 $ cilium clustermesh connect --destination-context ctx-cluster-b ✅ Connected cluster "cluster-b" (id: 2) # 将共享服务标记为全局 $ kubectl annotate svc kafka-shared \ service.cilium.io/global="true" \ service.cilium.io/shared="true" # 验证跨集群 Service 发现 $ cilium clustermesh status ✅ ClusterMesh: 3/3 clusters connected Global services: kafka-shared, redis-shared, prometheus Synced identities: 2,847
将以上四大优化手段叠加,我们可以计算出一个 中等规模生产集群 (10 Node, 1,000 Pod, 10,000 Service)的综合年化成本节省:
| 优化项 | 传统方案年化成本 | Cilium 年化成本 | 年化节省 | 节省比例 |
|---|---|---|---|---|
| Sidecar 消除 | $180,000 | $5,400 | $174,600 | 97% |
| kube-proxy 替换 | $48,000(CPU 浪费) | $600 | $42,000 | 87.5% |
| Netkit + BIG TCP | $35,000(需更大实例) | $17,500 | $17,520 | 50% |
| ClusterMesh 共享 | $72,000(3 集群独立) | $48,000 | $24,000 | 33% |
| 🎯 总计 | $335,000 | $71,500 | $258,120 | 77% |
硬件涨价是外部约束,软件效能是内部杠杆。
Cilium 通过四个层面的系统优化——消除 Sidecar 代理、替换 kube-proxy、
加速内核数据路径、共享跨集群基础设施——实现了不增加任何硬件
条件下 77% 的综合成本降幅。
当 HBM3e 内存价格飙升 5 倍、DDR5 现货价持续走高时,
这种"用算法对抗通胀"的策略不仅是技术选择,更是商业生存策略。
正如 Isovalent CTO Thomas Graf 所说:
"The best infrastructure upgrade is the one you never have to buy."
—— 最好的基础设施升级,是你永远不需要购买的那一次。