写在前面
《每个程序员都该知道的延迟数字》里点过一笔账:经 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 拦了一道。
| |
能力与代价
能力(这一代把网格能做的几乎全做到了):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。
| |
收益与代价
收益:
- 资源骤降:从"每 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/hop) | L4 低;要 L7 加 waypoint 跳 | L3/L4 最低(内核);L7 加 node Envoy 跳 |
| 心智复杂度 | 中(最成熟、资料最多) | 中高(ztunnel + waypoint + HBONE) | 中(eBPF + 内核依赖) |
| 成熟度 | 最成熟 | 2024 Beta 后持续 GA | Cilium 成熟;L7 mesh 相对新 |
| 适用 | 已有 Istio、重度 L7 治理 | 新部署、求轻量、要 mTLS+可观测 | 新内核、追性能、L7 需求不重 |
六、那笔税到底省了多少
回到延迟篇的数字,看三代怎么把那 2–5 ms/hop 往下压:
| |
(Ambient/Cilium 的精确延迟要看各自的官方基准,随负载和场景漂移;这里给的是相对量级。)
最该记住的洞察:三代演进不是"消灭分布式税",而是把税从"每 Pod 每 hop"逐步降到"每 node / 内核级"。但有一条税省不掉——只要你要 L7 流量治理(金丝雀分流、HTTP 重试、L7 授权),那一次 Envoy 处理就躲不掉,无论它叫 sidecar、waypoint 还是 node Envoy。
所以省下的是基础 mTLS 这一层的重复税,不是"L7 治理本身的税"。L4 需求为主、L7 需求少的服务,是 Ambient/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 的核心税,到现在谁也没真消掉。