第 09 章:服务网格
第 09 章:服务网格
服务网格将服务通信的复杂性从应用代码下沉到基础设施层,让开发者专注于业务逻辑。
9.1 什么是服务网格
9.1.1 定义
服务网格(Service Mesh)是一种专门处理服务间通信的基础设施层。它负责在现代云原生应用中可靠地传递请求,通常通过一组轻量级网络代理(Sidecar)来实现,这些代理与应用代码一起部署,但对应用透明。
9.1.2 Sidecar 模式
没有 Service Mesh:
┌─────────────────┐ ┌─────────────────┐
│ 服务 A │ │ 服务 B │
│ │ │ │
│ ┌─────────────┐ │ │ ┌─────────────┐ │
│ │ 业务逻辑 │ │ │ │ 业务逻辑 │ │
│ └──────┬──────┘ │ │ └──────┬──────┘ │
│ ┌──────┴──────┐ │ │ ┌──────┴──────┐ │
│ │服务发现 │ │ │ │服务发现 │ │
│ │负载均衡 │ │ │ │负载均衡 │ │
│ │重试/超时 │ │ │ │重试/超时 │ │
│ │熔断 │ │ │ │熔断 │ │
│ │mTLS │ │ │ │mTLS │ │
│ │链路追踪 │ │ │ │链路追踪 │ │
│ │日志 │ │ │ │日志 │ │
│ └─────────────┘ │ │ └─────────────┘ │
└─────────────────┘ └─────────────────┘
(通信逻辑嵌入每个服务)
有 Service Mesh:
┌───────────────────────────┐ ┌───────────────────────────┐
│ Pod A │ │ Pod B │
│ ┌──────────┐ ┌──────────┐│ │ ┌──────────┐ ┌──────────┐│
│ │ 服务 A │ │Sidecar A ││ │ │ 服务 B │ │Sidecar B ││
│ │ │ │ (Envoy) ││ │ │ │ │ (Envoy) ││
│ │ 业务逻辑 │ │ ││ │ │ 业务逻辑 │ │ ││
│ │ 只关心业务 │ │ 服务发现 ││ │ │ 只关心业务 │ │ 服务发现 ││
│ │ │ │ 负载均衡 ││ │ │ │ │ 负载均衡 ││
│ │ │ │ 重试/熔断 ││ │ │ │ │ 重试/熔断 ││
│ │ │ │ mTLS ││ │ │ │ │ mTLS ││
│ │ │ │ 遥测 ││ │ │ │ │ 遥测 ││
│ └──────────┘ └──────────┘│ │ └──────────┘ └──────────┘│
└───────────┬───────────────┘ └───────────┬───────────────┘
│ │
└──────── mTLS 加密通信 ─────────┘
9.1.3 服务网格解决的问题
| 问题 | 无 Service Mesh | 有 Service Mesh |
|---|---|---|
| 服务发现 | 每个服务自行实现 | Sidecar 代理处理 |
| 负载均衡 | 各服务各写一套 | 统一策略 |
| mTLS | 每个服务集成证书 | 自动证书管理 |
| 重试/熔断 | 每个服务各写一套 | 统一配置 |
| 流量控制 | 代码中硬编码 | 声明式配置 |
| 可观测性 | 各服务各自埋点 | 自动采集 |
9.2 Service Mesh 架构
9.2.1 数据面与控制面
┌──────────────────────────────────────────────────────────────┐
│ Service Mesh 架构 │
├──────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ 控制面 (Control Plane) │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ 配置管理 │ │ 证书管理 │ │ 服务发现 │ │ │
│ │ │ (Pilot) │ │ (Citadel) │ │ (Galley) │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ 遥测数据汇聚 │ │ 策略执行 │ │ │
│ │ │ (Telemetry) │ │ (Policy) │ │ │
│ │ └──────────────┘ └──────────────┘ │ │
│ └────────────────────────────────────────────────────────┘ │
│ │ xDS API │
│ ┌─────────────────┼─────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Pod A │ │ Pod B │ │ Pod C │ │
│ │ ┌─────────┐ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │
│ │ │ App │ │ │ │ App │ │ │ │ App │ │ │
│ │ ├─────────┤ │ │ ├─────────┤ │ │ ├─────────┤ │ │
│ │ │ Envoy │ │ │ │ Envoy │ │ │ │ Envoy │ │ │
│ │ │ Sidecar │ │ │ │ Sidecar │ │ │ │ Sidecar │ │ │
│ │ └─────────┘ │ │ └─────────┘ │ │ └─────────┘ │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ 数据面 (Data Plane) — Envoy Proxies │
└──────────────────────────────────────────────────────────────┘
9.3 Istio 详解
9.3.1 Istio 架构
┌──────────────────────────────────────────────────────────────┐
│ Istio 架构 │
├──────────────────────────────────────────────────────────────┤
│ │
│ 控制面 (istiod) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ Pilot │ │ Citadel │ │ Galley │ │ │
│ │ │ 流量管理 │ │ 安全/证书 │ │ 配置管理 │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ │ │
│ └──────────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────┼────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Pod A │ │ Pod B │ │ Pod C │ │
│ │ ┌─────────┐ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │
│ │ │ App │ │ │ │ App │ │ │ │ App │ │ │
│ │ ├─────────┤ │ │ ├─────────┤ │ │ ├─────────┤ │ │
│ │ │ Envoy │◄├──├─┤ Envoy │◄├──├─┤ Envoy │ │ │
│ │ └─────────┘ │ │ └─────────┘ │ │ └─────────┘ │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└──────────────────────────────────────────────────────────────┘
9.3.2 Istio 核心功能
| 功能 | 说明 | CRD 资源 |
|---|---|---|
| 流量管理 | 路由、负载均衡、灰度发布 | VirtualService, DestinationRule |
| 安全 | mTLS、认证、授权 | PeerAuthentication, AuthorizationPolicy |
| 可观测性 | 指标、日志、链路追踪 | Telemetry, Kiali |
| 故障注入 | 模拟延迟和错误,用于测试 | VirtualService |
| 熔断 | 连接池/请求数限制 | DestinationRule |
9.3.3 流量管理实战
灰度发布(Canary Deployment):
# VirtualService: 将 90% 流量给 v1,10% 给 v2
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: order-service
spec:
hosts:
- order-service
http:
- route:
- destination:
host: order-service
subset: v1
weight: 90
- destination:
host: order-service
subset: v2
weight: 10
# DestinationRule: 定义版本子集
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: order-service
spec:
host: order-service
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
http:
h2UpgradePolicy: DEFAULT
http1MaxPendingRequests: 100
http2MaxRequests: 1000
outlierDetection:
consecutive5xxErrors: 5
interval: 30s
baseEjectionTime: 30s
基于 Header 的路由:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: order-service
spec:
hosts:
- order-service
http:
# 内部测试用户路由到 v2
- match:
- headers:
x-user-group:
exact: "beta-tester"
route:
- destination:
host: order-service
subset: v2
# 其他用户路由到 v1
- route:
- destination:
host: order-service
subset: v1
9.3.4 mTLS 配置
# 全命名空间启用 mTLS
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: production
spec:
mtls:
mode: STRICT # STRICT | PERMISSIVE | DISABLE
# 授权策略:只允许订单服务调用支付服务
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: payment-service-policy
namespace: production
spec:
selector:
matchLabels:
app: payment-service
rules:
- from:
- source:
principals: ["cluster.local/ns/production/sa/order-service"]
to:
- operation:
methods: ["POST"]
paths: ["/api/v1/payments"]
9.4 Linkerd
9.4.1 Linkerd vs Istio
| 维度 | Istio | Linkerd |
|---|---|---|
| 复杂度 | 高(功能丰富) | 低(轻量简单) |
| 数据面 | Envoy (C++) | linkerd2-proxy (Rust) |
| 资源占用 | 较高 | 极低 |
| 功能 | 全面 | 核心功能 |
| 学习曲线 | 陡峭 | 平缓 |
| 适用场景 | 大型复杂集群 | 中小规模/快速上手 |
| 安装时间 | 分钟级 | 秒级 |
9.4.2 Linkerd 架构
┌──────────────────────────────────────────────────────────┐
│ Linkerd 架构 │
├──────────────────────────────────────────────────────────┤
│ │
│ 控制面 (linkerd-destination) │
│ ┌────────────────────────────────────────────────────┐ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │Destination│ │ Identity │ │ Proxy │ │ │
│ │ │(服务发现) │ │ (证书) │ │ Injector │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ 数据面 (linkerd2-proxy, Rust 实现) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Pod A │ │ Pod B │ │ Pod C │ │
│ │ ┌─────────┐ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │
│ │ │ App │ │ │ │ App │ │ │ │ App │ │ │
│ │ ├─────────┤ │ │ ├─────────┤ │ │ ├─────────┤ │ │
│ │ │linkerd │ │ │ │linkerd │ │ │ │linkerd │ │ │
│ │ │ proxy │ │ │ │ proxy │ │ │ │ proxy │ │ │
│ │ └─────────┘ │ │ └─────────┘ │ │ └─────────┘ │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└──────────────────────────────────────────────────────────┘
9.4.3 Linkerd 快速上手
# 安装 CLI
curl -fsL https://run.linkerd.io/install | sh
# 安装 Linkerd 到集群
linkerd install | kubectl apply -f -
# 验证安装
linkerd check
# 注入 Sidecar 到已有部署
kubectl get deploy -n myapp -o yaml | linkerd inject - | kubectl apply -f -
# 查看仪表板
linkerd viz dashboard &
9.5 服务网格 vs 应用层方案
9.5.1 对比
| 维度 | 应用层方案 (SDK) | 服务网格 (Sidecar) |
|---|---|---|
| 语言绑定 | 需要每个语言一套 SDK | 语言无关 |
| 代码侵入 | 有(引入 SDK 依赖) | 无(透明代理) |
| 升级难度 | 需要重新编译部署 | Sidecar 独立升级 |
| 性能 | 更好(无额外跳转) | 有延迟开销(~1ms) |
| 资源占用 | 应用进程内 | 每个 Pod 额外一个容器 |
| 调试 | 简单 | 复杂(多一层代理) |
| 一致性 | 各语言 SDK 可能有差异 | 完全一致 |
| 适用场景 | 语言单一、团队成熟 | 多语言、大规模 |
9.5.2 决策指南
是否需要 Service Mesh?
┌─ 服务数量 < 10 个?
│ → 不需要,用 SDK 方案即可
│
├─ 只使用一种编程语言?
│ → 考虑 SDK 方案(如 Spring Cloud)
│
├─ 多语言混合 (Java + Go + Python + ...)?
│ → Service Mesh 更合适
│
├─ 需要统一的 mTLS 和授权?
│ → Service Mesh 更合适
│
├─ 需要细粒度流量控制(灰度/金丝雀)?
│ → Service Mesh 更合适
│
└─ 团队 K8s 经验不足?
→ 先用 SDK,积累经验后再考虑 Mesh
9.6 业务场景:电商平台的服务网格实践
┌──────────────────────────────────────────────────────────┐
│ 电商 Service Mesh 部署架构 │
├──────────────────────────────────────────────────────────┤
│ │
│ Ingress Gateway (Istio) │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Gateway + VirtualService │ │
│ │ • HTTPS 终止 │ │
│ │ • 路由规则 │ │
│ │ • 限流 │ │
│ └───────────────────────┬────────────────────────────┘ │
│ │ │
│ ┌───────────┬───────────┼───────────┬───────────┐ │
│ ▼ ▼ ▼ ▼ ▼ │
│ ┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │
│ │用户│ │商品│ │订单│ │支付│ │通知│ │
│ │服务│ │服务│ │服务│ │服务│ │服务│ │
│ └──┬─┘ └──┬─┘ └──┬─┘ └──┬─┘ └──┬─┘ │
│ │E │E │E │E │E │
│ (Envoy Sidecar for each service) │
│ │
│ 策略配置: │
│ • mTLS: STRICT (全命名空间) │
│ • 熔断: 5xx 连续 5 次触发 │
│ • 超时: 全局 10s │
│ • 灰度: order-service v2 10% 流量 │
│ │
│ 可观测性: │
│ • Kiali: 服务拓扑可视化 │
│ • Prometheus + Grafana: 指标监控 │
│ • Jaeger: 链路追踪 │
└──────────────────────────────────────────────────────────┘
⚠️ 注意事项
- 不要过早引入 Service Mesh——服务数量 < 10 时收益不大
- 资源开销不可忽视——每个 Pod 多一个 Sidecar 容器,CPU/内存有开销
- 调试变复杂——网络问题可能出在 Sidecar 代理层
- Istio 升级风险——大版本升级可能不兼容,需谨慎
- 冷启动延迟——Sidecar 注入会增加 Pod 启动时间
📖 扩展阅读
- Istio Documentation (istio.io) — Istio 官方文档
- Linkerd Documentation (linkerd.io) — Linkerd 官方文档
- Pattern: Service Mesh — William Morgan (Buoyant) — 服务网格概念定义
- Envoy Proxy — 服务网格数据面的事实标准
- The Enterprise Path to Service Mesh — Lee Calcote — O’Reilly 免费电子书
本章小结
| 要点 | 说明 |
|---|---|
| 核心概念 | Sidecar 代理模式,数据面 + 控制面 |
| 主流选型 | Istio(功能全面)、Linkerd(轻量简单) |
| 核心功能 | 流量管理、mTLS、可观测性、故障注入 |
| 适用场景 | 大规模多语言微服务集群 |
| 关键权衡 | 运维复杂性 vs 通信治理标准化 |
📌 下一章:第 10 章:分布式事务 — Saga、TCC、最终一致性与补偿机制。