前言

微服务多了,治理需求爆炸:灰度、熔断、重试、加密、链路追踪……把这些能力从业务代码里抽出来下沉到基础设施,就是服务网格(Service Mesh)。Istio 是这个领域的事实标准。

一、为什么需要服务网格

没有网格:                          有网格:
┌────────────┐                    ┌────────────┐
│ 业务代码     │                    │ 业务代码     │ ← 只关心业务
│ + 重试逻辑   │                    ├────────────┤
│ + 熔断逻辑   │                    │ Envoy代理   │ ← 重试/熔断/加密
│ + 加密代码   │                    │ (sidecar)  │    全在这里
│ + 追踪埋点   │                    └────────────┘
└────────────┘
框架SDK耦合: 换语言=重写治理         多语言天然统一, 业务零侵入

核心机制:Sidecar 模式——每个 Pod 注入一个 Envoy 代理容器,进出 Pod 的所有流量都被它劫持:

# 注入后看 Pod
kubectl get pods
# api-7d9f6c-x2v4x   2/2   Running    ← 2 个容器 = 业务 + istio-proxy
kubectl exec -it api-xxx -c istio-proxy -- pilot-agent version

二、架构与安装

┌─ 控制面 istiod ──────────────┐
│ 配置下发(xDS) + 证书签发(CA)  │──► 所有 Envoy
└──────────────────────────────┘
数据面: 每个 Pod 里的 Envoy ↔ 组成服务间通信的实际通路
# 安装(国内镜像)
curl -L https://istio.io/installIstio | ISTIO_VERSION=1.23.0 sh -
export PATH=$PATH:$(pwd)/istio-1.23.0/bin

istioctl install --set profile=demo -y

# 给 namespace 打标签, 新 Pod 自动注入 sidecar
kubectl label namespace prod istio-injection=enabled
kubectl rollout restart deploy/api -n prod      # 重启生效

# 验证
istioctl proxy-status

三、流量管理:网格的看家本领

VirtualService:路由规则

apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: api
spec:
  hosts: [api]
  http:
  - match:
    - headers: {x-canary: {exact: "true"}}       # 按请求头路由
    route:
    - destination: {host: api, subset: v2}
  - route:
    - destination: {host: api, subset: v1}
      weight: 95                                 # 默认流量 95% 走 v1
    - destination: {host: api, subset: v2}
      weight: 5                                  # 5% 灰度 v2

DestinationRule:定义版本与策略

apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: api
spec:
  host: api
  subsets:
  - name: v1
    labels: {version: v1}
  - name: v2
    labels: {version: v2}
  trafficPolicy:
    connectionPool:
      tcp: {maxConnections: 100}
    outlierDetection:            # 熔断: 连续5次5xx则踢出30秒
      consecutive5xxErrors: 5
      interval: 10s
      baseEjectionTime: 30s

金丝雀发布全流程(对应 CI/CD 篇的策略):

kubectl apply -f dr.yaml            # v1/v2 subset 就位
kubectl apply -f vs-5.yaml          # 5% → v2
# 观察错误率/延迟 → OK
kubectl apply -f vs-50.yaml         # 50%
kubectl apply -f vs-100.yaml        # 全量
# 出问题? vs-0.yaml 一键回 0(秒级, 不用动 Deployment)

四、弹性能力:重试与超时

http:
- route: [{destination: {host: api}}]
  timeout: 2s                       # 请求级超时
  retries:
    attempts: 3
    perTryTimeout: 500ms
    retryOn: "5xx,reset,connect-failure"   # 只重试幂等可重试错误

治理能力完全 YAML 化——改重试策略不用改代码发版,这是网格相对 SDK 的本质优势。

五、安全:mTLS 零改造加密

apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: default
  namespace: istio-system          # 全网格生效
spec:
  mtls: {mode: STRICT}             # 服务间通信强制双向TLS
# 验证: 抓包看到的全是 TLS
istioctl x authn check api.xxx

# 控制谁能访问谁(L7 授权)
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: api-only-from-gateway
  namespace: prod
spec:
  selector: {matchLabels: {app: api}}
  action: ALLOW
  rules:
  - from: [{source: {principals: ["cluster.local/ns/istio-system/sa/istio-ingressgateway"]}}]

六、可观测性:开箱即用的黄金指标

装上 Kiali(拓扑图)+ 内置的指标上报(Prometheus 格式):

kubectl apply -f samples/addons/kiali.yaml
kubectl apply -f samples/addons/prometheus.yaml
# 访问 Kiali: 服务拓扑、流量动画、错误率一目了然

# istioctl 也能直接查
istioctl x describe pod api-xxx       # 这个Pod的配置/证书状态

Envoy 自动上报请求级指标(成功率/延迟/p200…)——微服务监控从"进程级"升到"服务调用级"。

七、代价:不是免费的午餐

代价 说明
延迟 每跳多经过两层代理(客户端+服务端 sidecar),P99 增加约 1~3ms
资源 每个 Pod 多一个容器(内存 ~100MB 起),百 Pod 规模=一台节点的开销
复杂度 排障链路多了一层(istioctl proxy-status/log 是新必修课)

什么时候值得上:

  • ✅ 微服务 > 20 个、多语言并存、有专职平台团队
  • ✅ 强合规要求(全链路 mTLS、审计)
  • ⚠️ 几个服务的中小团队:K8s 原生 + 网关层治理先够用,别为简历上网格

八、排障速查

istioctl proxy-status                    # 所有 sidecar 同步状态
istioctl proxy-config routes api-xxx    # 查看生效的路由(vs没生效先看这!)
istioctl proxy-config cluster api-xxx
kubectl logs api-xxx -c istio-proxy --tail=50

# 常见坑
sidecar 没注入            → namespace label + 重启 Pod
503 no healthy upstream   → subset label 不匹配 / 探针失败
路由规则不生效            → hosts 写错(短名/FQDN)、DR/VS 顺序
UDP/特殊协议不通          → 网格默认代理 TCP, 例外要显式配置

小结

概念 作用
Sidecar (Envoy) 劫持进出流量, 承载全部治理
istiod 控制面: 配置下发 + 证书
VirtualService 怎么路由(灰度/分流/匹配)
DestinationRule 到哪里去(版本/连接池/熔断)
PeerAuthentication mTLS 加密
AuthorizationPolicy 服务级授权

本文是「云原生」系列第 16 篇。