服务网格:从 sidecar 到 Ambient,那笔"分布式税"怎么省

写在前面

《每个程序员都该知道的延迟数字》里点过一笔账:经 Service Mesh sidecar,每个 hop 要多付 2–5 ms(Istio 官方基准 ~3 ms p50 / ~10 ms p99)。《后端架构实战(四):微服务的"分布式税"》讲过这笔税"为什么非付不可"。

这篇讲的是这笔税怎么逐步省下来——服务网格这三四年的演进,方向出奇一致:把代理从应用进程里搬出去,搬到每台 node、再搬进内核。三代路线:sidecar → Ambient → eBPF。读完你会清楚它们各自省了什么、省不掉什么、你怎么选。

这篇是独立参考稿,不绑某个系列。它和《分布式税》《延迟数字》《Polly》《可观测性》几篇互相印证,串成"微服务通信"的一条线。


一、服务网格到底解决什么

微服务一起来,每一条 service-to-service 链路都背着同一堆非功能性需求

  • 安全:双向加密 + 身份认证(mTLS)——别让内网裸奔;
  • 弹性:超时、重试、熔断、限流——别让一个慢下游拖垮整条链路;
  • 流量治理:金丝雀发布、按比例分流、按 header 路由、流量镜像;
  • 可观测:服务间拓扑、延迟分布、错误率、访问日志。

每个服务自己用框架(.NET 的 Polly、Java 的 Resilience4j、Go 的中间件……)实现一遍 = 语言不一致、版本不一致、改一条策略要动几十个仓库

服务网格做的事就一句话:把这一整层从应用代码里抽出来,下沉成独立的基础设施层。应用只管业务逻辑,网格管"服务间通信的所有非功能性需求"。

所以网格不是"替你交分布式税",而是让交税的方式标准化、集中化——税还在,但不再每个服务各交各的。


二、第一代:Sidecar(Istio + Envoy)

怎么工作

每个 Pod 被 mutating webhook 注入一个 Envoy sidecar,Pod 内所有进出流量被 iptables 规则重定向到本地 Envoy。应用完全无感——它以为自己直连对端,其实流量先被本地 Envoy 拦了一道。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Pod A                            Pod B
┌────────────────┐               ┌────────────────┐
│   App          │               │   App          │
│    │           │               │    ▲           │
│    ▼           │               │    │           │
│   Envoy ───────┼──── mTLS ────→┼── Envoy        │   ← 每 Pod 一个 sidecar
└────────────────┘               └────────────────┘

一次调用: app → 本地 Envoy → 网络 → 对端 Envoy → 对端 app
        多了 2 个本地代理跳 + 2 次 mTLS 加解密

能力与代价

能力(这一代把网格能做的几乎全做到了):mTLS + SPIFFE 身份、VirtualService 的金丝雀/分流/镜像、DestinationRule 的熔断/outlier detection、全量遥测(指标/链路/访问日志自动埋点)。

代价正是延迟篇那笔账:

  • 延迟:每 hop +2 个本地代理跳 + 2 次 mTLS ≈ 2–5 ms。一个请求串 5 个服务,光 sidecar 就叠出十几毫秒。
  • 资源:每个 Pod 几十~上百 MB 内存 + 一份 CPU。1000 个 Pod 就是几十 GB 耗在 sidecar 上。
  • 启动: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。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Node 1                            Node 2
┌─────────────────────┐           ┌─────────────────────┐
│  Pod A    Pod B     │           │  Pod C    Pod D     │
│    │        │       │           │    │        │       │
│    ▼        ▼       │           │    ▲        ▲       │
│    └──→ ztunnel ────┼── HBONE ──┼→ ztunnel ←──┘       │  ← 每 node 一个(L4)
│          (L4)       │   隧道    │      (L4)           │
│            │        │           │       │ (按需)      │
│            ▼        │           │       ▼             │
│        waypoint     │           │   waypoint          │  ← 需要 L7 才起
└─────────────────────┘           └─────────────────────┘

L4 流量只过 ztunnel(轻);要 L7 治理才加 waypoint 那一跳

收益与代价

收益

  • 资源骤降:从"每 Pod 一个 Envoy"变成"每 node 一个轻 ztunnel + 按需 waypoint",大规模下省的是几十 GB 级别的内存。
  • L4 近乎零额外跳:ztunnel 在 node 级,HBONE 隧道高效,mTLS 开销从"每 Pod 每 hop"摊薄到"每 node"。
  • 零侵入:业务 Pod 不再被注入 sidecar,迁移成本和故障面都小。
  • 可并存:Ambient 能和 sidecar 模式混跑,逐服务渐进迁移。

代价

  • 心智更绕:ztunnel + waypoint + HBONE 三件事,比"一个 sidecar"复杂。
  • L7 那一跳省不掉:要流量分割/重试,waypoint 本质还是个 Envoy——只是换了部署位置。
  • 仍在成熟:2024 年 5 月 Istio 1.22 进入 Beta,之后持续 GA 化,2026 已是主流可选方案,但部分高级特性仍在演进。

四、第三代:eBPF(Cilium Service Mesh)

核心思路:既然要离开应用进程,干脆离开用户态

Cilium 把逻辑直接编进内核的 eBPF 程序,在 socket 层、XDP、TC 这些挂载点处理流量——数据包根本不用回到用户态

  • L3/L4(网络、mTLS、网络策略、可观测指标):完全在内核态用 eBPF 完成,没有 sidecar 那种"内核→用户态 Envoy→内核"的反复切换。mTLS 走节点级加密(WireGuard/IPSec)+ Cilium 身份。
  • L7(HTTP/gRPC 策略):eBPF 把需要 L7 处理的流量透明重定向到一个 node 级的共享 Envoy——不是每 Pod sidecar,是每 node 一个。

一个必须说清的诚实点

Cilium 经常被宣传成"无 sidecar、eBPF 搞定一切",但它的 L7 仍然要靠 Envoy,只不过从"每 Pod 一个"换成了"每 node 一个共享实例"。所以:

Cilium 和 Ambient 都不是"消灭代理",都是"把代理从每 Pod sidecar 挪到 node 级 / 内核"。真正的区别在 L3/L4 谁更高效:Cilium 是内核原生 eBPF(零用户态切换),Ambient 是 ztunnel 用户态但极轻。

收益与代价

收益:L3/L4 极致性能(内核原生)、无 per-pod 开销、内核级可观测(网络指标天然丰富)。

代价

  • L7 多租户隔离是社区讨论点——共享 node Envoy 处理多服务流量,隔离不如 per-pod sidecar 干净。
  • 依赖较新内核(eBPF 能力对内核版本有要求,常见要 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)
延迟开销高(2–5 ms/hopL4 低;要 L7 加 waypoint 跳L3/L4 最低(内核);L7 加 node Envoy 跳
心智复杂度中(最成熟、资料最多)中高(ztunnel + waypoint + HBONE)中(eBPF + 内核依赖)
成熟度最成熟2024 Beta 后持续 GACilium 成熟;L7 mesh 相对新
适用已有 Istio、重度 L7 治理新部署、求轻量、要 mTLS+可观测新内核、追性能、L7 需求不重

六、那笔税到底省了多少

回到延迟篇的数字,看三代怎么把那 2–5 ms/hop 往下压:

1
2
3
sidecar (每 Pod Envoy):       2–5 ms/hop   ← 每 Pod 每跳两个 Envoy + 2 次 mTLS
Ambient L4 (ztunnel + HBONE): 显著降低       ← mTLS 摊到每 node,L4 路径大幅减负
Cilium L3/L4 (内核 eBPF):     理论最低       ← 内核原生,无用户态切换

(Ambient/Cilium 的精确延迟要看各自的官方基准,随负载和场景漂移;这里给的是相对量级。)

最该记住的洞察:三代演进不是"消灭分布式税",而是把税从"每 Pod 每 hop"逐步降到"每 node / 内核级"。但有一条税省不掉——只要你要 L7 流量治理(金丝雀分流、HTTP 重试、L7 授权),那一次 Envoy 处理就躲不掉,无论它叫 sidecar、waypoint 还是 node Envoy。

所以省下的是基础 mTLS 这一层的重复税,不是"L7 治理本身的税"。L4 需求为主、L7 需求少的服务,是 Ambient/Cilium 最大的受益者。


七、怎么选(决策清单)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
□ 已有 Istio + 重度 L7 治理(金丝雀/重试都写在 VirtualService 里)
   → 留 sidecar;想降开销就逐服务迁 Ambient(能并存,渐进)

□ 新部署、主要要 mTLS + 基础可观测、资源敏感
   → Ambient

□ 内核新(5.10+)、追极致网络性能、L7 需求不重、团队熟 eBPF
   → Cilium

□ 规模没到(几十个服务以下)
   → 可能根本不需要网格

最后一条最容易踩坑。网格自身的运维复杂度(控制面、版本升级、故障排查、CRD 体系)不低。规模没到时,mTLS 交给平台层(比如 K8s + 网络策略)、弹性交给应用的 Polly、可观测交给 OpenTelemetry,往往比上整套网格更划算。网格是规模问题的解药,不是小集群的补品。


八、和 .NET / ASP.NET Core 的分工

网格下沉之后,应用层还做什么?关键原则是别重叠——两边都做同一件事,不仅浪费,还会出事:

  • mTLS:交给网格。应用别再自己加密 service-to-service(自加密会和网格的 mTLS 打架或重复)。
  • 重试 / 超时 / 熔断二选一。要么网格(Istio 的 DestinationRule / Ambient waypoint),要么应用(Polly)。两边都开 = 双重重试,一个失败触发两层的重试风暴,放大流量、恶化雪崩——这是最常见的坑。一般原则:跨服务边界的通用策略 → 网格;和业务逻辑绑定的(“这个 API 失败重试 3 次且只对特定错误”)→ 应用层 Polly。详见《Polly 的前世今生》《分布式税》。
  • 可观测互补,不是替代。网格给"服务间拓扑 + 调用延迟 + 错误率"(数据面自动埋点,零侵入);OpenTelemetry 给"业务全链路 + 应用内 span"。两者通过 trace context 串联,画面才完整。详见《后端架构实战(七):可观测性》。
  • 流量治理(金丝雀、AB、按 header 分流):网格擅长,别在应用里自己造路由层。

小结

  • 服务网格 = 把服务间通信的非功能性需求(mTLS / 弹性 / 治理 / 可观测)从应用下沉成独立基础设施层。
  • 三代演进:sidecar(每 Pod Envoy)→ Ambient(node 级 ztunnel + 按需 waypoint)→ eBPF(内核 L3/L4 + node Envoy L7)。方向一致:代理从应用进程挪到 node、再挪进内核
  • 税省了什么:sidecar 的 2–5 ms/hop,被 Ambient/Cilium 在 L4 层大幅降低;但 L7 治理那一次 Envoy 处理省不掉
  • 选型:看 L7 需求 / 规模 / 内核版本 / 团队能力;规模没到别硬上,Polly + OTel 可能更划算。
  • 和应用层的边界:mTLS 交网格、重试别两边都开(双重重试是最常见的坑)、可观测互补。

一句话:服务网格这十年的故事,就是把"分布式税"从每个应用进程里,一寸一寸挪到 node 和内核——挪得越远,应用越轻,但那笔 L7 的核心税,到现在谁也没真消掉。


参考资料