Skip to content
Charles Shao
Go back

服务网格 Service Mesh 深挖

views

前两篇把 RPC 框架 的 SDK 治理和 服务发现 的候选集讲透了。团队长到多语言、多团队时会出现新矛盾:每一种语言都重写一遍熔断/重试/mTLS/灰度? Service Mesh 的答案是:把这些横切能力放进与业务容器并肩的 Sidecar 代理,由统一控制面下发策略——业务进程尽量只写业务。

广告体系里常见「Java 竞价核心 + Go/Python 周边数据服务 + 若干遗留 Thrift」:指望每人把 Dubbo Filter 重写一遍不现实。本篇聚焦 Istio + Envoy 这条工业主流路径:架构、流量路径、安全与可观测、以及你必须正视的代价。

本文是微服务与 RPC 系列的第 3 篇。 系列顺序:① RPC 框架(开篇);② 服务注册与发现深挖;③ 服务网格 Service Mesh 深挖(本篇);④ API 网关与分布式追踪

一句话定位:Service Mesh = 数据面 Sidecar(执行)+ 控制面(决策)——把服务间的路由、安全、观测从业务 SDK 下沉为基础设施;收益是一致性,账单是延迟、资源与运维复杂度。

TL;DR

Table of contents

Open Table of contents

1. 为什么需要 Mesh

SDK 模式(Dubbo Cluster、各类 Resilience 库)在同构、小团队里非常高效:零额外 hop,调优直观。痛点出在:

Mesh 把「服务间怎么说话」收归平台,用依赖韧性同一套思想,但是在代理层落地。它不消灭 RPC——契约、序列化、业务超时预算仍在应用层;它消灭的是「每门语言一份私有治理实现」。

另一条诱因是组织:平台团队想统一灰度、统一 mTLS、统一观测标准,而业务团队只想专注特征与策略。Mesh 是这种分工的物理落点。若组织里没有能对 VirtualService/DestinationRule 负责的平台 owner,上网格等于把配置复杂度均摊给每个业务——失败模式从「SDK 不一致」变成「YAML 不一致」,未必更好。

2. Sidecar + 控制面架构

Service Mesh 架构示意图。顶部控制面面板含服务发现同步、VirtualService 流量规则、mTLS/AuthZ 安全策略、遥测采样配置。下方两个数据面 Pod:各含 App 容器与 Envoy Sidecar,控制面以虚线 xDS 下发到两侧 Sidecar,Sidecar 之间以 mTLS 网格流量互通;iptables/eBPF 劫持进出流量。底部说明控制面决策、数据面执行。

控制面不转发用户请求;它只把「怎么转」教会数据面。

2.1 流量劫持

经典做法:用 iptables/nftables(或 CNI)把 Pod 的进出 TCP 重定向到 Sidecar 端口;业务以为自己连对端,其实出站先进 Envoy。新一代 Ambient Mesh / eBPF 试图去掉每 Pod 一个 Sidecar 的重税(ztunnel / waypoint),但概念仍是「数据面代理 + 控制面」。

排查「流量怎么被转走」时,要会看:Pod 的 iptables 规则、Envoy 的 listener/cluster、以及应用实际 dial 的地址。很多人第一次上网格时,会把「连不上」误判成业务 Bug,其实是劫持或 mTLS 握手失败。

2.2 xDS:控制面如何遥控 Envoy

Envoy 通过 xDS API 从控制面拉配置:

于是上一篇的「服务发现」在 Mesh 里变成:控制面看 K8s Endpoints / 注册中心 → EDS 推给 Sidecar。业务进程甚至可以不知道注册中心的存在。

配置下发有延迟与版本:刚改完 VirtualService,不是全集群瞬间一致。做金丝雀时要给传播窗口,别改完 1 秒就宣布成功。

2.3 Istio 里常见对象

对象作用
VirtualService路由、超时、重试、故障注入、镜像
DestinationRule子集、负载均衡、连接池、outlier detection
PeerAuthentication / AuthorizationPolicymTLS 模式与访问控制
Gateway南北向入口(常与下篇网关职责重叠/协作)
Sidecar 资源限制出站范围,减小配置膨胀

配置膨胀是真实问题:服务一多,每条规则交叉,Envoy 推送配置变大、内存上涨。要治理 Sidecar 出站范围、合并规则、避免「每个服务全网互通的巨型 CDS」。

3. 网格内的调用路径与治理挂载点

网格内一次调用的流量路径:Client App → Client Sidecar(路由·重试·mTLS)→ 网络加密链路 → Server Sidecar(鉴权·限流·观测)→ Server App。下方挂载点卡片:出口侧超时重试熔断分流、链路上证书轮换 SPIFFE、入口侧 AuthZ 限流遥测,以及 +1~2 hop 的代价。

治理挂在代理两侧与链路上;App 只看见「成功或失败」。

3.1 流量治理清单

能力典型挂载配置入口(Istio)
超时 / 重试出口 SidecarVirtualService
熔断 / 连接池出口DestinationRule
金丝雀 / A-B出口路由权重VirtualService
故障注入出口/入口VirtualService
限流入口或外部 ratelimitEnvoyFilter / 扩展
镜像(shadow)出口VirtualService

这对广告灰度极友好:把 5% 流量切到新竞价策略版本,业务二进制不用改匹配规则。镜像流量可把生产请求复制到候选版本做暗流量验证,但要注意写接口禁止盲目镜像(双写预算就炸了)。

Outlier detection(异常值检测)类似「主动踢掉持续 5xx/超时的实例」,和发现层健康检查互补——它更贴近真实请求成败,而不是端口探活。参数要保守:连续失败阈值过低,一次毛刺就会踢光半边容量;过高又等同没开。建议与负载均衡里的慢启动(slow start)一起配:被踢后回池的实例先吃小流量再爬升。

金丝雀还有组织流程:权重从 0→1→5→25→100,每级卡住看错误率与业务 KPI(广告主消耗、填充率)。只看 HTTP 200 不够——竞价可能「技术成功、业务算错」。网格能切流量,但不能替你定义业务成功指标。

3.2 mTLS 与身份

网格为每个工作负载签发身份(SPIFFE URI),Sidecar 之间建立 mTLS。收益:

迁移期常用 PERMISSIVE(明文与 mTLS 并存)再切 STRICT。切 STRICT 前必须确认所有调用路径都进了网格——漏网的脚本、批任务、旁路 NodePort 会突然全挂。

注意:mTLS 管的是东西向;南北向仍多在网关终结公网 TLS(下一篇)。

证书与控制面可用性绑定:控制面长时间不可用、SDS 续不上,会逐渐出现握手失败。网格的 HA 不是「多个 Envoy」就够,Istiod / 证书链路同样要进稳定性预算。对广告这种长连接多的系统,证书轮换窗口还要避开流量高峰。

3.3 可观测下沉

Sidecar 自动产生:RED 指标、访问日志、以及与 Trace 系统对接的 span。对「来不及埋点的老服务」特别有价值;完整的 Trace 传播与采样策略在第 4 篇展开。

网格 metrics 常成为容量与 SLO 的权威来源——但也要防止基数爆炸(别把高基数广告主 ID 打进目标标签)。

3.4 故障注入:把混沌变成配置

VirtualService 的 delay / abort 注入,能在预发验证:

比「等生产偶然抖一下」便宜得多。但注入必须限定在 staging 或带染色 header 的流量——曾经有人把 abort 规则推到生产忘了删,那是另一种 war story。

4. 代价与 SDK 对照

治理下沉对比:左栏 SDK/框架内建——治理嵌进程、每语言重写、升级跟着业务发版,优点是零额外 hop;右栏 Sidecar Mesh——与业务解耦、多语言一致、策略热更新,代价是多一跳与运维资源开销。底部建议可混合:热路径留 SDK,统一安全与多语言走 Mesh。

Mesh 不是银弹,是「复杂度搬家」——从业务仓库搬到平台团队。

4.1 真实账单

超低延迟交易/竞价热路径,往往保留短链路 SDK;Mesh 优先覆盖管理面、多语言外围、强制 mTLS 的区域。也能「网格内通信,但对某几个端口绕过劫持」做精确例外——例外清单要严管,否则安全模型被掏空。

4.2 何时上、何时不上

值得上:多语言、强合规(必须 mTLS)、渴望统一灰度与观测、平台团队能扛运维。

慎上:几十个服务以内的同构栈、极致延迟、还没有成熟的平台 SRE——先把 RPC 超时熔断与发现做对,往往 ROI 更高。

渐进路径:先只开可观测与 mTLS PERMISSIVE → 再开路由灰度 → 最后才碰重试/熔断等「会改变流量形状」的开关。每一步都要有回滚(VirtualService 一键打回)。

4.3 本地调试与「绕过网格」

开发机常常不在网格里。常见手段:

没有「本地故事」的 Mesh 会逼业务绕路,最终生产与开发行为分叉——这比延迟多一毫秒更危险。

4.4 与 负载均衡 的关系

Mesh 的 DestinationRule 负载均衡(round_robin、least_request、ring_hash)与上一篇 RPC 客户端 LB 是同一族算法,只是执行点换了。选型原则不变:干净的 endpoints + 合适的策略 + 慢实例踢出。Outlier detection 是网格版的「主动健康意识」,别关着还怪 LB 不均。

参考


views
Share this post on:

Previous Post
API 网关与分布式追踪
Next Post
服务注册与发现深挖