Istio

Istio 是目前最主流的 Service Mesh 实现,基于 Envoy Sidecar 代理,解决微服务间流量治理、安全通信和可观测性问题,无需修改业务代码。

核心架构

┌─────────────────────────────────────────────┐
│            Control Plane                    │
│                                             │
│  ┌──────────────────────────────────────┐   │
│  │              istiod                  │   │
│  │                                      │   │
│  │  Pilot   → 流量规则下发到 Envoy       │   │
│  │  Citadel → 证书颁发与轮换(mTLS)     │   │
│  │  Galley  → 配置验证                  │   │
│  └──────────────────────────────────────┘   │
└──────────────────┬──────────────────────────┘
                   │ xDS 协议
                   ▼
┌─────────────────────────────────────────────┐
│            Data Plane                       │
│                                             │
│  Pod A                     Pod B            │
│  ┌───────────────┐         ┌─────────────┐  │
│  │ app-container │         │ app-container│  │
│  ├───────────────┤  mTLS   ├─────────────┤  │
│  │ envoy sidecar │────────►│envoy sidecar│  │
│  └───────────────┘         └─────────────┘  │
└─────────────────────────────────────────────┘

所有入站和出站流量都经过 Envoy Sidecar,业务容器感知不到代理的存在。

Sidecar 自动注入

在 Namespace 上打标签后,Pod 创建时 Sidecar 自动注入:

kubectl label namespace prod istio-injection=enabled

注入后 Pod 多一个 istio-proxy 容器:

kubectl get pod order-service-xxx -n prod
CONTAINERS:
  order-service   # 业务容器
  istio-proxy     # Envoy Sidecar(自动注入)

流量管理

VirtualService

定义路由规则,决定请求如何转发:

apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: order-service
spec:
  hosts:
  - order-service
  http:
  # 金丝雀:10% 流量到 v2
  - route:
    - destination:
        host: order-service
        subset: v1
      weight: 90
    - destination:
        host: order-service
        subset: v2
      weight: 10

DestinationRule

定义目标服务的负载均衡策略和熔断规则:

apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: order-service
spec:
  host: order-service
  trafficPolicy:
    loadBalancer:
      simple: LEAST_CONN       # 最少连接数
    connectionPool:
      http:
        http1MaxPendingRequests: 100
        http2MaxRequests: 1000
    outlierDetection:           # 熔断
      consecutive5xxErrors: 5   # 连续 5 次 5xx 触发熔断
      interval: 10s
      baseEjectionTime: 30s     # 剔除 30s
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

Gateway

管理进入网格的外部流量(南北向):

apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
  name: api-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: SIMPLE
      credentialName: api-tls-cert
    hosts:
    - api.example.com

熔断与重试

# 在 VirtualService 中配置重试和超时
http:
- timeout: 10s
  retries:
    attempts: 3
    perTryTimeout: 3s
    retryOn: "5xx,reset,connect-failure,retriable-4xx"
  route:
  - destination:
      host: order-service

mTLS(双向 TLS)

Istio 默认开启 mTLS,所有服务间通信自动加密:

# 强制 strict mTLS(拒绝明文请求)
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: default
  namespace: prod
spec:
  mtls:
    mode: STRICT

证书由 Citadel 自动颁发(基于 SPIFFE 标准),每 24 小时轮换一次。

授权策略

细粒度访问控制,控制哪个服务可以调用哪个服务:

# 只允许 order-service 调用 payment-service
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: payment-authz
  namespace: prod
spec:
  selector:
    matchLabels:
      app: payment-service
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/prod/sa/order-service"]
    to:
    - operation:
        methods: ["POST"]
        paths: ["/api/pay"]

可观测性

Istio 自动采集服务间的 Metrics、Traces 和访问日志,无需业务代码埋点。

数据采集内容后端
Metrics请求数、延迟、错误率(RED)Prometheus + Grafana
Traces完整调用链(自动注入 TraceID)Jaeger / Zipkin / Tempo
Access Log每次请求详情Loki / Elasticsearch

Kiali(Istio 官方可视化):

服务拓扑图 → 可视化服务间调用关系、流量权重、健康状态

流量镜像

将生产流量实时复制到影子服务,用于测试新版本而不影响用户:

http:
- route:
  - destination:
      host: order-service
      subset: v1
  mirror:
    host: order-service
    subset: v2         # 镜像到 v2,响应被丢弃
  mirrorPercentage:
    value: 100.0       # 镜像 100% 流量

灰度发布完整流程

1. 部署 v2 版本(副本数为 1,不接收流量)
   kubectl apply -f order-service-v2.yaml

2. 配置 VirtualService:5% 流量到 v2
   weight: v1=95, v2=5

3. 观察 Grafana 面板(错误率、延迟)
   正常 → 下一步
   异常 → 修改 weight: v1=100, v2=0(立即回滚)

4. 逐步提升:5% → 20% → 50% → 100%

5. 全量后下线 v1
   kubectl delete deployment order-service-v1

与其他方案对比

方案数据面控制面特点
IstioEnvoyistiod功能最全,社区最大,复杂度高
LinkerdLinkerd2-proxy(Rust)控制平面轻量,性能好,上手简单
Consul ConnectEnvoyConsulHashicorp 生态,多云
Cilium MesheBPFCilium Operator无 Sidecar,内核级,性能最强

安装(Helm)

# 添加 Helm 仓库
helm repo add istio https://istio-release.storage.googleapis.com/charts
 
# 安装控制平面
helm install istio-base istio/base -n istio-system --create-namespace
helm install istiod istio/istiod -n istio-system
 
# 安装 Ingress Gateway
helm install istio-ingress istio/gateway -n istio-ingress --create-namespace

生产注意事项

  • 资源开销:每个 Pod 多一个 Envoy 容器,默认占 ~100m CPU / 128Mi 内存,大规模部署需评估
  • 冷启动:Sidecar 注入会增加 Pod 启动时间
  • 版本升级:istiod 和 Envoy 版本要保持一致,升级前先升控制平面
  • 调试:使用 istioctl proxy-statusistioctl analyze 排查配置问题

相关链接