
企业灰度发布 06:Service Mesh 为什么出现,又把复杂度搬到了哪里
微服务治理最初常由语言 SDK 承担:Java 团队使用一套注册发现和熔断库,Go 团队实现另一套,Node.js 服务再少一部分能力。几年后,同一个“超时 500ms”在不同语言中具有不同默认值,升级安全库需要推动所有业务重发版本,遗留服务长期停在旧协议。
Service Mesh 的出发点,是把与业务无关但必须一致的网络能力放到应用进程之外。请求先经过代理,代理执行服务身份、mTLS、路由、超时、重试、负载均衡和遥测;控制面把声明式策略编译并下发给大量代理。业务只使用普通协议,不再为每种语言维护完整治理 SDK。
它解决的是跨语言的一致执行面,不是“网络从此自动可靠”。
数据面与控制面的责任分离
数据面位于真实请求路径上,代理出错、资源不足或配置异常会直接影响业务。控制面通常不转发业务流量,即使短时不可用,已有代理仍可使用最后一次有效配置服务;但新 Pod、证书轮换和新策略会受到影响。因此二者的容量、SLO 和故障演练必须分开。
控制面也不是每个请求都来“问一次路”。它把服务发现、路由和安全规则转换为代理可执行配置,通过增量流式协议分发。代理在本地完成匹配和转发,这让策略执行足够快,却也带来最终一致窗口:提交配置到所有代理收到配置之间存在延迟。
Mesh 真正下沉了哪些能力
第一类是身份与传输安全。工作负载获得短期身份凭证,代理之间建立 mTLS,策略可以按服务身份而不是易变 IP 授权。它提高了集群内零信任的可操作性,但不能替代应用层业务权限;订单服务仍需判断用户能否查看某笔订单。
第二类是流量管理。代理能根据 host、path、header、cookie 或权重选择目标版本,也能执行超时、有限重试、异常端点驱逐、连接池和熔断。这正是后续灰度发布控制器可以操作的执行面。
第三类是统一遥测。代理天然看见请求方向、响应码、持续时间和连接信息,可以生成一致的服务指标和 trace 上下文。但它不知道“HTTP 200 是否真的完成了支付”,业务指标仍必须由应用产生。
第四类是策略执行。入口、出口和服务间通信可以用统一资源声明,安全团队不必进入每个代码库修改网络库。代价是平台团队成为新的关键依赖,策略变更也需要版本、测试、审计和回滚。
复杂度没有消失,只是重新分配
代理会消耗 CPU、内存、连接和文件描述符。Sidecar 模式下,每个 Pod 都多一个代理,规模大时控制面需要向成千上万个实例推送配置;应用建立连接的路径和故障点增加,抓包也不能只看业务容器。
更隐蔽的是配置复杂度。业务方看到一个 YAML,底层可能生成成百上千个 listener、cluster、route 和 endpoint。两条 VirtualService 规则冲突、协议端口识别错误、subset label 选不到端点,都可能表现为 503。平台必须提供静态分析、预览、配置分发状态和代理级调试能力,而不是只给业务团队一个自由编辑框。
治理所有权必须提前划分
如果业务、平台、发布控制器和 GitOps 系统都能修改同一个 VirtualService,最终一定出现字段互相覆盖。更稳妥的模型是:平台拥有基础安全与默认流量策略,业务拥有经过约束的路由意图,发布控制器只拥有 stable/canary 权重和临时路由字段,GitOps 忽略这些运行时字段或使用明确的管理协议。
资源所有权最好细化到字段,而不只到 YAML 文件。变更入口统一经过策略检查,记录操作者、release id、旧值、新值和恢复值。紧急手工修复之后也要反向同步声明状态,否则下一次 reconcile 会把修复覆盖掉。
哪些系统不值得立刻上 Mesh
服务数量少、语言栈统一、调用关系简单的团队,成熟 SDK 与网关可能已经足够。批处理任务、极端低延迟链路、非标准协议或资源极小的边缘环境,也要评估代理开销与协议支持。Mesh 的收益随服务数量、语言异构、安全要求和流量策略复杂度增加而上升。
引入判断不应是“行业都在用”,而应量化:当前有多少治理库、升级一次需要多久、证书与授权是否一致、发布是否需要请求级路由、故障定位成本多高。只有收益能够覆盖平台建设和运行成本,Mesh 才是基础设施,不是新的技术债。
上线 Mesh 的验收顺序
建议先建立可观测的透明代理,只看流量不改行为;再启用宽松 mTLS 并检查非 Mesh 工作负载;随后收紧身份策略;最后才迁移重试、熔断和复杂路由。一次把安全、路由和发布全部打开,会让任何问题都难以归因。
| 阶段 | 验证重点 |
|---|---|
| 透明观测 | 协议识别、延迟与资源基线 |
| 身份建立 | 证书轮换、时钟与信任域 |
| 安全收紧 | 授权例外和非 Mesh 流量 |
| 治理迁移 | 避免 SDK 与代理双重重试 |
| 发布接入 | 权重、指标、回滚和字段所有权 |
下一篇进入 Istio 的具体架构:istiod 如何把 Kubernetes 与 Istio API 编译为数据面配置,代理如何获得服务发现、路由和身份,以及为什么控制面健康不能只看一个 Pod 是否 Running。