Administrator
发布于 2022-11-23 / 8042 阅读
162

Service Mesh 之 Istio 接入体验与代价评估

为什么想上 Mesh

团队有 30+ 微服务,TLS、重试、熔断这些逻辑散落在每个 Dubbo/Spring Cloud 应用里,升级一次 SDK 全员陪跑。一次熔断规则改版,光是让各服务升级 SDK 就花了两周,还有三个老服务因为没人维护迟迟不动。我们想试试把这部分下沉到基础设施,于是拉了一套 Istio 1.15 做试点,看它到底值不值。

Sidecar 模式怎么工作

每个 Pod 注入一个 Envoy 容器,应用出向流量被 iptables 规则拦截,先过 Envoy 再出去。这样业务代码零改造就获得了 mTLS、限流、灰度能力。应用完全不知道 sidecar 的存在,只管和 localhost 通信。

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata: { name: order-svc }
spec:
  host: order-svc
  trafficPolicy:
    connectionPool:
      http:
        maxRetriesPerConnection: 3
    outlierDetection:
      consecutive5xxErrors: 5
      baseEjectionTime: 30s

上面这段就给 order-svc 配了连接池和熔断(连续 5 个 5xx 就摘流量 30 秒),业务代码一行不用改。

流量管理真香的地方

灰度发布是 Mesh 最实在的收益。以前灰度要改 Nginx 权重或 SDK 路由,现在一份 VirtualService 搞定:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata: { name: order-svc }
spec:
  hosts: [order-svc]
  http:
  - route:
    - destination: { host: order-svc, subset: v1 }
      weight: 90
    - destination: { host: order-svc, subset: v2 }
      weight: 10

按权重切 10% 流量到新版本,观察指标没问题再调满。比改注册中心元数据优雅太多,也更细粒度。

代价评估

试点跑了一个月,我们记了账:

维度引入前引入后
P99 延迟18ms27ms(多一跳 + TLS)
单 Pod 内存512Mi+120Mi(Envoy)
发布复杂度高(需理解 CRD、sidecar 注入)
排障时长平均 20min平均 45min

运维复杂度是隐性成本

  • 排错链条变长:原来抓个包就行,现在要区分是应用还是 Envoy 拒的流,得看 Envoy 的 access log(x-envoy-upstream-service-time 这种头);
  • 控制面 Istiod 挂了,新 Pod 注入会失败,扩容直接卡住;
  • mTLS 全开时,跨集群、与其他非 Mesh 系统的互通要单独处理,我们一个老大数据平台就不支持 mTLS,得给它开 PERMISSIVE 模式过渡;
  • 版本升级牵一发动全身,Istio 1.15→1.16 的 sidecar 注入模板变了,灰度了三天。

我们的结论

Mesh 适合"多语言、SDK 治理成本高、强合规加密"的场景。我们最终只在支付域试点落地,没全公司铺开。对中小团队,先把 SDK 治理做扎实比上 Mesh 更划算。支付域之所以适合,是因为它多语言(有 Go 写的风控)、合规要求 mTLS、且灰度频率高——三样都命中。

给想试的人一句忠告

别被"先进"带节奏。上 Mesh 前先算清楚三笔账:延迟多 9ms 业务接不接得住、内存每 Pod 多 120Mi 集群多大、排障时长翻倍团队扛不扛得住。我们当时就是先算了这三笔,才决定不全量推。

证书与 mTLS 的隐性工作

Mesh 的 mTLS 不是免费午餐。Istio 用 istiod 内置的 CA 发证书,每个 Envoy 拿一张默认一小时有效期的短期证书。我们接入第一周就遇到证书轮转导致的 503:某次 istiod 滚动重启,新证书下发慢了几秒,部分 Envoy 拿着刚过期的证书拒绝握手,503 率从 0.1% 飙到 4%。根因是证书轮换的宽限期没配,老证书过期、新证书还没到。后来把 rotation grace period 设到 30 分钟才稳。

另外,mTLS 默认 STRICT 模式会拦掉所有非 mesh 流量。我们一个老的大数据平台用 IP 直连、没进 mesh,突然全不通。得在它对应的服务上设 PERMISSIVE 过渡,再慢慢迁移。这种"默认严格"的治理哲学,对存量系统不友好,要有迁移窗口,不能一刀切。

和 Spring Cloud 的取舍

我们本来就有 Spring Cloud Alibaba(Nacos 做注册中心、Sentinel 做限流)。上了 Istio 后,两套治理重叠:Nacos 管服务发现、Istio 也管;Sentinel 管限流、Envoy 也管。重叠意味着困惑——开发不知道该配哪边。我们的结论是:新业务直接走 Istio 线,老业务留在 Spring Cloud,不强行统一,避免一次大迁移的事故风险。

性能上,Feign 调用是应用内 SDK,多一次本机方法调用但没 sidecar 那跳网络;Istio 多一跳 localhost 的 Envoy,延迟 +9ms。对小请求占比高的场景,这 9ms 占比不小。所以我们最终只在"治理复杂、多语言、强合规"的支付域用 Istio,其余域不动。

可观测性这块确实值

客观说,Mesh 给可观测性带来的好处是实打实的。Envoy 默认吐 access log 和 metrics,Prometheus 直接抓,不用在每个应用里埋点就能拿到每个服务间的 RT、错误率、流量。我们支付域接入后,第一次有了"服务调用拓扑"的全貌图,之前靠 SkyWalking 的链路追踪拼,覆盖不全。这块收益甚至比流量管理更让团队买账。

成本量化复盘

一个月试点下来,我们算了总账:集群多了 30 个 Envoy,按每 Pod +120Mi 内存、集群 200 节点算,月资源成本增加约 8%;排障工时被拉长,oncall 平均多花一倍时间看 Envoy 日志;换来的是灰度发布从"改注册中心元数据"变成"一份 YAML",发布引发的事故率明显下降。这笔账对支付域划算,对整体不划算——所以局部落地是理性选择,不是跟风。

一次 Envoy 内存泄漏的教训

试点第二个月,支付域某个 Pod 的 Envoy 内存从 120Mi 慢慢涨到 1.2G,触发 OOM 被 kill,Pod 重启又涨。查下来是某个上游服务的连接数暴涨,Envoy 的 upstream 连接缓存没上限,加上 keepalive 配得大。临时把每个上游的 maxConnections 限到 200,内存稳住。这让我们意识到 sidecar 也有自己的容量问题,不是"加了就不管"。我们后来给所有 Envoy 配了资源 limit 和连接上限,并接了内存监控,防止悄悄涨。

和 API Gateway 的分工

有人问:都有了网关(我们用 Spring Cloud Gateway),还要 Mesh 吗?分工是:网关管南北向(外部进来的流量,鉴权、限流、WAF),Mesh 管东西向(服务之间,mTLS、细粒度路由)。两者不冲突,但小团队常把东西向也放网关,结果网关成了中心瓶颈。Mesh 的价值正是把东西向治理去中心化到每个 Pod。我们支付域是"网关收口 + Mesh 内部治理"双层,各管一摊。

给团队的决策清单

总结一份"要不要上 Mesh"的清单:多语言服务?SDK 治理成本高?强 mTLS 合规?灰度发布频繁?四个里至少中三个才建议上。我们只支付域中三个,所以只在那落地。其余域用 Spring Cloud 把治理做扎实,性价比更高。Mesh 是重武器,按需掏,别当标配,否则运维债比它省下的还多。

我们最终的生产拓扑

落地后支付域的拓扑是:外层 Spring Cloud Gateway 收南北向流量、做鉴权和粗限流;进到 mesh 后,支付、风控、账务三个服务之间走 Envoy mTLS,灰度用 VirtualService 按权重切。这套跑了一季度,发布事故从每月 2~3 起降到 0,运维同学对"发布"这件事的焦虑明显降了。代价是 oncall 要懂 Envoy 日志,我们为此写了内部排错手册,新人照着手册能处理八成问题。投入和收益在支付域是平衡的。

给后来者的三句话

第一,先算延迟、内存、人力三笔账,别被"先进"带节奏;第二,局部落地比全量推稳,挑最痛的域先上;第三,可观测性(Envoy metrics + 访问日志)必须同步建,否则排错会疯。Mesh 是重武器,用对了降本增效,用错了只是把复杂度挪了个地方。我们踩过的这些坑,希望你看完能少踩几个。

一句话总结

Mesh 把治理从代码搬进基础设施,代价是运维复杂度和一点延迟。值不值,看你的痛点是不是"多语言 + 强治理 + 合规",是就上,不是就缓。我们支付域中了,所以留着;其他域没中,所以没推。技术选型从来不是"先进就上",是"痛点匹配才上"。这套判断逻辑,后来我们也用在了其他新技术的评估上。

Mesh 把治理从代码搬进基础设施,代价是运维复杂度和一点延迟。值不值,看你的痛点是不是"多语言 + 强治理 + 合规",是就上,不是就缓。我们支付域中了,所以留着;其他域没中,所以没推。技术选型从来不是"先进就上",是"痛点匹配才上"。

先到这

《Service Mesh 之 Istio 接入体验与代价评估》这块我前前后后踩了不止一次。今天先写这些,后面想到新的再补。

参考