写在前面
《每个程序员都该知道的延迟数字》里点过一笔账:Service Mesh 代理会增加延迟和资源消耗,但开销不是一个跨环境固定的“每跳毫秒数”。Istio 官方基准显示,它会随协议、连接数、请求率、负载大小、代理线程数和遥测功能明显变化。《后端架构实战(四):微服务的"分布式税"》讲过这笔税为什么存在。
这篇比较三种数据面路线:sidecar、Istio Ambient,以及以 eBPF 加速网络路径的 Cilium Service Mesh。它们不是严格接替的“三代产品”,而是可以并存的架构选择。
这篇是独立参考稿,不绑某个系列。它和《分布式税》《延迟数字》《Polly》《可观测性》几篇互相印证,串成"微服务通信"的一条线。
一、服务网格到底解决什么
微服务一起来,每一条 service-to-service 链路都背着同一堆非功能性需求:
- 安全:双向加密 + 身份认证(mTLS)——别让内网裸奔;
- 弹性:超时、重试、熔断、限流——别让一个慢下游拖垮整条链路;
- 流量治理:金丝雀发布、按比例分流、按 header 路由、流量镜像;
- 可观测:服务间拓扑、延迟分布、错误率、访问日志。
每个服务自己用框架(.NET 的 Polly、Java 的 Resilience4j、Go 的中间件……)实现一遍 = 语言不一致、版本不一致、改一条策略要动几十个仓库。
服务网格做的事就一句话:把这一整层从应用代码里抽出来,下沉成独立的基础设施层。应用只管业务逻辑,网格管"服务间通信的所有非功能性需求"。
所以网格不是"替你交分布式税",而是让交税的方式标准化、集中化——税还在,但不再每个服务各交各的。
二、第一代:Sidecar(Istio + Envoy)
怎么工作
每个 Pod 被 mutating webhook 注入一个 Envoy sidecar,Pod 内所有进出流量被 iptables 规则重定向到本地 Envoy。应用完全无感——它以为自己直连对端,其实流量先被本地 Envoy 拦了一道。
| |
能力与代价
能力(这一代把网格能做的几乎全做到了):mTLS + SPIFFE 身份、VirtualService 的金丝雀/分流/镜像、DestinationRule 的熔断/outlier detection、全量遥测(指标/链路/访问日志自动埋点)。
代价正是延迟篇那笔账:
- 延迟:请求多经过客户端和服务端代理,过滤器、遥测和排队都会增加平均与尾部延迟;实际值必须按自己的协议、并发和策略压测。
- 资源:每个工作负载都有代理。Istio 1.24 的官方参考测试中,1 KB 请求、1000 RPS、两个 worker 的单个 sidecar 约占 0.20 vCPU 和 60 MB 内存;这只是特定基准,不是容量规划常数。
- 启动:Pod 启动变慢且有序问题——应用先于 Envoy 就绪时,出站连接失败;Envoy 先于应用时,入站没人接。
sidecar 模型的问题不在"能力不够",而在粒度太细:每个 Pod 都扛一个全功能 Envoy,绝大多数流量其实只用到它 mTLS 这一小块。
三、第二代:Ambient(ztunnel + waypoint)
核心思路:L4 和 L7 解耦
Istio Ambient 的洞察是——大多数流量只需要 mTLS(L4),不该每个 Pod 扛一个全功能 Envoy。于是把数据面拆成两层:
- ztunnel:每台 node 跑一个(DaemonSet),用 Rust 写的极轻 L4 代理。只管 mTLS 加解密 + L4 授权。node 上所有 Pod 的流量统一由它过,传输用 HBONE(HTTP/2 CONNECT 隧道协议)封装。
- waypoint:按需部署(per namespace 或 per service),本质还是 Envoy,但只在需要 L7 策略时才起(流量分割、HTTP 级重试、L7 授权)。不需要 L7 的服务,流量只过 ztunnel,不碰 waypoint。
| |
收益与代价
收益:
- 减少重复资源:从“每工作负载一个 Envoy”变成“每节点一个轻量 ztunnel + 按需 waypoint”;能省多少取决于 Pod、节点、waypoint 副本数和策略规模。
- 避免 per-Pod 代理:流量仍会经过源、目的节点上的 ztunnel,HBONE 也仍有代理、加密与排队成本;收益来自更轻的共享 L4 数据面,而不是“近乎零额外跳”。
- 零侵入:业务 Pod 不再被注入 sidecar,迁移成本和故障面都小。
- 可并存:Ambient 能和 sidecar 模式混跑,逐服务渐进迁移。
代价:
- 心智更绕:ztunnel + waypoint + HBONE 三件事,比"一个 sidecar"复杂。
- L7 那一跳省不掉:要流量分割/重试,waypoint 本质还是个 Envoy——只是换了部署位置。
- 能力仍在演进:Ambient 于 2024 年 5 月随 Istio 1.22 进入 Beta,并于 2024 年 11 月随 1.24 达到 GA;核心 ztunnel、waypoint 和 API 已标记 Stable,但与 sidecar 的功能对齐仍是后续路线图的一部分。
四、另一条路线:eBPF(Cilium Service Mesh)
核心思路:既然要离开应用进程,干脆离开用户态
Cilium 使用 eBPF 在内核数据路径中完成服务负载均衡、网络策略和可观测等 L3/L4 工作;需要解析 HTTP、gRPC、Kafka 或 DNS 等应用层协议时,流量仍要重定向到用户态 Envoy。
- L3/L4:eBPF 负责转发、负载均衡、策略执行和观测;可选的 WireGuard/IPsec 提供透明加密,但这不等同于成熟的工作负载级 mTLS 身份认证。
- 身份认证:Cilium 的 SPIFFE/SPIRE mutual authentication 在当前文档中仍为 Beta,若要同时获得加密,还需启用 WireGuard 或 IPsec。
- L7:eBPF 将需要应用层处理的流量透明重定向到 Envoy;具体部署形态取决于安装配置。
一个必须说清的诚实点
Cilium 经常被宣传成"无 sidecar、eBPF 搞定一切",但它的 L7 仍然要靠 Envoy,只不过从"每 Pod 一个"换成了"每 node 一个共享实例"。所以:
Cilium 和 Ambient 都不是“消灭所有代理”。Ambient 用节点级 ztunnel 承担安全 L4 overlay,并按需加入 waypoint;Cilium 用 eBPF 承担大量 L3/L4 工作,但 L7 仍依赖 Envoy。二者的身份模型和策略 API 也不同。
收益与代价
收益:L3/L4 极致性能(内核原生)、无 per-pod 开销、内核级可观测(网络指标天然丰富)。
代价:
- L7 多租户隔离是社区讨论点——共享 node Envoy 处理多服务流量,隔离不如 per-pod sidecar 干净。
- 依赖满足 Cilium 支持矩阵的 Linux 内核与功能配置;不要用一个笼统的
5.10+代替安装前的系统要求检查。 - 控制面是 Cilium 自家体系(
CiliumNetworkPolicy等 CRD),和 Istio 的VirtualService/DestinationRule不通用,迁移有成本。
五、三条路线横评
| 维度 | Sidecar(Istio 经典) | Ambient(Istio) | eBPF(Cilium) |
|---|---|---|---|
| 数据面位置 | 每 Pod 一个 Envoy | 每 node 一个 ztunnel + 按需 waypoint | 内核 eBPF(L3/L4)+ 每 node Envoy(L7) |
| L7 能力 | 全(Envoy 原生) | 全(waypoint = Envoy) | 有,但弱于 Istio 的体系 |
| 每 Pod 开销 | 大(几十~百 MB) | 几乎为零(无 sidecar) | 几乎为零(无 sidecar) |
| 延迟开销 | 多两个代理数据路径,需实测 | L4 路径更轻;L7 增加 waypoint | L3/L4 主要在 eBPF 路径;L7 增加 Envoy |
| 心智复杂度 | 中(最成熟、资料最多) | 中高(ztunnel + waypoint + HBONE) | 中(eBPF + 内核依赖) |
| 成熟度 | 最成熟 | Istio 1.24 起 GA;功能仍持续对齐 | Cilium 网络数据面成熟;mutual authentication 仍为 Beta |
| 适用 | 已有 Istio、重度 L7 治理 | 新部署、求轻量、要 mTLS+可观测 | 新内核、追性能、L7 需求不重 |
六、那笔税到底省了多少
回到延迟问题,更稳妥的比较方式是看数据路径,而不是套一个固定的“每 hop”数字:
| |
(Ambient/Cilium 的精确延迟要看各自的官方基准,随负载和场景漂移;这里给的是相对量级。)
最该记住的洞察:这些路线不是把分布式通信变成零成本,而是在代理隔离、共享资源和内核加速之间取舍。只要需要基于 HTTP 等应用层语义做治理,就需要 L7 解析;在本文讨论的实现里,这仍由 Envoy 承担。
所以省下的是基础 mTLS 这一层的重复税,不是"L7 治理本身的税"。L4 需求为主、L7 需求少的服务,是 Ambient/Cilium 最大的受益者。
七、怎么选(决策清单)
| |
最后一条最容易踩坑。网格自身的运维复杂度(控制面、版本升级、故障排查、CRD 体系)不低。规模没到时,可以按需求组合网络策略、平台提供的工作负载身份或 mTLS 能力、应用侧 Polly 与 OpenTelemetry;其中 Kubernetes NetworkPolicy 只做网络访问控制,本身不提供 mTLS。网格是规模问题的解药,不是小集群的补品。
八、和 .NET / ASP.NET Core 的分工
网格下沉之后,应用层还做什么?关键原则是别重叠——两边都做同一件事,不仅浪费,还会出事:
- mTLS:若网格已覆盖这条链路,应用通常不必再重复建立一层同目的的传输加密;但端到端合规边界、网格外流量和应用层加密需求仍需单独评估。
- 重试 / 超时 / 熔断:二选一。要么网格(Istio 的
DestinationRule/ Ambient waypoint),要么应用(Polly)。两边都开 = 双重重试,一个失败触发两层的重试风暴,放大流量、恶化雪崩——这是最常见的坑。一般原则:跨服务边界的通用策略 → 网格;和业务逻辑绑定的(“这个 API 失败重试 3 次且只对特定错误”)→ 应用层 Polly。详见《Polly 的前世今生》《分布式税》。 - 可观测:互补,不是替代。网格给"服务间拓扑 + 调用延迟 + 错误率"(数据面自动埋点,零侵入);OpenTelemetry 给"业务全链路 + 应用内 span"。两者通过 trace context 串联,画面才完整。详见《后端架构实战(七):可观测性》。
- 流量治理(金丝雀、AB、按 header 分流):网格擅长,别在应用里自己造路由层。
小结
- 服务网格 = 把服务间通信的非功能性需求(mTLS / 弹性 / 治理 / 可观测)从应用下沉成独立基础设施层。
- 三条路线:sidecar(每工作负载 Envoy)、Ambient(节点级 ztunnel + 按需 waypoint)、Cilium(eBPF L3/L4 + 按需 Envoy L7);它们并非严格代际替换。
- 税省了什么:Ambient 和 Cilium 都避免 per-Pod sidecar,但数据路径、身份认证与 L7 处理仍有成本;必须以目标环境的 p50/p99、吞吐和资源占用实测选型。
- 选型:看 L7 需求 / 规模 / 内核版本 / 团队能力;规模没到别硬上,Polly + OTel 可能更划算。
- 和应用层的边界:mTLS 交网格、重试别两边都开(双重重试是最常见的坑)、可观测互补。
一句话:服务网格这十年的故事,就是把"分布式税"从每个应用进程里,一寸一寸挪到 node 和内核——挪得越远,应用越轻,但那笔 L7 的核心税,到现在谁也没真消掉。