Skip to content

16 — Service Mesh 深度教材

Service Mesh 是微服务架构的进阶能力。本章覆盖 Istio 数据面/控制面、Envoy 原理、流量管理、可观测性集成。


1. Service Mesh 原理

传统微服务 vs Service Mesh:

传统:应用代码内置 SDK(如 Spring Cloud/Dubbo)处理服务发现、负载均衡、熔断
  优势:简单  劣势:语言绑定、升级困难、侵入代码

Service Mesh:将流量管理下沉到基础设施层(Sidecar Proxy)
  优势:语言无关、统一管控、透明升级
  劣势:延迟增加(多一跳)、资源开销、复杂度上升

Istio 架构:
┌───────────────────────────────────────┐
│          控制面(istiod)               │
│  Pilot(服务发现)→ Citadel(证书)      │
│  Galley(配置验证)→ 全部合并为 istiod │
├───────────────────────────────────────┤
│          数据面(Envoy Sidecar)        │
│  每个 Pod 注入 envoy-proxy 容器         │
│  所有进出流量经过 Envoy 代理           │
└───────────────────────────────────────┘

2. Istio 安装与 Sidecar 注入

bash
# 安装 Istio
istioctl install --set profile=default
# profile: default / demo / minimal / remote

# 启用自动注入(Namespace 级别)
kubectl label namespace production istio-injection=enabled

# 手动注入
istioctl kube-inject -f deployment.yaml | kubectl apply -f -

# 检查 Sidecar 注入状态
kubectl get pods -n production -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].name}{"\n"}{end}'
# 正常 Pod 应有两个容器:app + istio-proxy

# 查看 Sidecar 配置
kubectl exec <pod> -c istio-proxy -- curl localhost:15000/config_dump | head -100
kubectl exec <pod> -c istio-proxy -- curl localhost:15000/clusters  # 查看上游集群

3. 流量管理

3.1 VirtualService(路由规则)

yaml
# 灰度发布:90% v1,10% v2
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: web-app
spec:
  hosts:
  - web-app
  http:
  - route:
    - destination:
        host: web-app
        subset: v1
      weight: 90
    - destination:
        host: web-app
        subset: v2
      weight: 10
---
# DestinationRule(定义子集)
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: web-app
spec:
  host: web-app
  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: 3
      interval: 10s
      baseEjectionTime: 30s

3.2 Gateway(入口网关)

yaml
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: app-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: SIMPLE
      credentialName: app-tls
    hosts:
    - app.example.com
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: app-route
spec:
  hosts:
  - app.example.com
  gateways:
  - app-gateway
  http:
  - match:
    - uri:
        prefix: /api
    route:
    - destination:
        host: api-service
        port:
          number: 8080

4. 可观测性集成

bash
# Istio 自动生成指标(无需应用埋点)
# istio_requests_total           → 请求总数
# istio_request_duration_seconds → 请求延迟
# istio_request_bytes            → 请求大小
# istio_response_bytes           → 响应大小

# 分布式追踪(需要应用传播 header)
# Istio 支持:Zipkin、Jaeger、SkyWalking
# Envoy 自动注入 x-b3-traceid、x-b3-spanid
# 应用需要传播这些 header(OpenTelemetry SDK)

# Kiali(Service Mesh 可视化)
kubectl port-forward svc/kiali -n istio-system 20001:20001
# 访问 http://localhost:20001 查看服务拓扑、流量、追踪

5. 面试高频问题

Q: Service Mesh 的延迟开销有多大?

单次请求增加 2 跳(request → sidecar → upstream sidecar → service)
典型延迟增加:1-3ms(同节点)/ 3-8ms(跨节点)
优化:
  1. mTLS 复用连接
  2. 调整 Envoy 并发连接数
  3. 对延迟敏感的服务可跳过 Mesh

Q: Istio vs Linkerd 怎么选?

Istio:功能丰富、社区活跃、学习曲线陡、资源占用大
Linkerd:轻量级、简单、性能好、功能较少
生产建议:
  大规模微服务、需要高级流量管理 → Istio
  中小规模、追求简单可靠 → Linkerd