服务网格架构深度剖析
概述
服务网格(Service Mesh)是用于处理服务间通信的基础设施层,提供了一种透明的方式来管理、微观监控和保护微服务。在 Kubernetes 生态中,Istio 和 Linkerd 是最主流的服务网格实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| ┌─────────────────────────────────────────────────────────────────────────┐ │ 服务网格架构图 │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ Service Mesh Layer │ │ │ │ │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ │ │ Service │ │ Service │ │ Service │ │ │ │ │ │ A │────►│ B │────►│ C │ │ │ │ │ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ │ │ │ │ │ │ │ │ ┌────▼────┐ ┌────▼────┐ ┌────▼────┐ │ │ │ │ │ Sidecar │ │ Sidecar │ │ Sidecar │ │ │ │ │ │ (Envoy) │ │ (Envoy) │ │ (Envoy) │ │ │ │ │ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ └────────┼───────────────┼───────────────┼────────────────────────┘ │ │ │ │ │ │ │ └───────────────┼───────────────┘ │ │ │ │ │ ┌────────────────────────┼────────────────────────────────────────┐ │ │ │ │ │ │ │ │ ┌─────────────────────▼─────────────────────┐ │ │ │ │ │ Control Plane │ │ │ │ │ │ │ │ │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ │ │ │ │ Pilot │ │Citadel │ │ Galley │ │ │ │ │ │ │ │ (流量) │ │ (安全) │ │ (配置) │ │ │ │ │ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ │ │ │ │ │ │ │ │ ┌─────────┐ ┌─────────┐ │ │ │ │ │ │ │Mixer │ │ Kiali │ (旧版Istio) │ │ │ │ │ │ │ (遥测) │ │ (可视化)│ │ │ │ │ │ │ └─────────┘ └─────────┘ │ │ │ │ │ └──────────────────────────────────────────────┘ │ │ │ │ │ │ │ └───────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────┘
|
1. 服务网格核心概念
1.1 什么是服务网格
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| ┌─────────────────────────────────────────────────────────────────────────┐ │ 服务网格 vs 无服务网格 │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ 无服务网格: │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ ┌─────────┐ ┌─────────┐ │ │ │ │ │ Service │ ◄─── 业务代码 ──► │ Service │ │ │ │ │ │ A │ │ B │ │ │ │ │ └─────────┘ └─────────┘ │ │ │ │ │ │ │ │ 问题: │ │ │ │ - 重试、超时逻辑耦合在业务代码中 │ │ │ │ - 无法统一管理服务间通信 │ │ │ │ - 可观测性分散在各个服务 │ │ │ └─────────────────────────────────────────────────────────────────┘ │ │ │ │ 有服务网格: │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ ┌─────────┐ ┌──────┐ ┌─────────┐ ┌──────┐ │ │ │ │ │ Service │ │Sidecar│ ◄──► │ Service │ │Sidecar│ │ │ │ │ │ A │ │ Envoy │ │ B │ │ Envoy │ │ │ │ │ └─────────┘ └──────┘ └─────────┘ └──────┘ │ │ │ │ │ │ │ │ │ │ └────────────────────────┴──────────────────────────── │ │ │ │ │ │ │ │ │ ┌────────────▼────────────┐ │ │ │ │ │ Control Plane │ │ │ │ │ │ (统一配置/策略/安全) │ │ │ │ │ └─────────────────────────┘ │ │ │ │ │ │ │ │ 优势: │ │ │ │ - 业务代码无需关心重试、超时、熔断 │ │ │ │ - 统一的流量管理策略 │ │ │ │ - 内置可观测性支持 │ │ │ │ - mTLS 自动加密通信 │ │ │ └─────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────┘
|
1.2 Sidecar 模式
Sidecar 模式将基础设施功能从应用代码中分离出来:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| apiVersion: v1 kind: Pod metadata: name: myapp namespace: default spec: containers: - name: myapp image: myapp:v1 ports: - containerPort: 8080 - name: istio-proxy image: docker.io/istio/proxyv2:1.19.0 ports: - containerPort: 15090 name: "http-envoy-prom" - containerPort: 15021 name: "health" - containerPort: 15000 name: "envoy-admin" env: - name: ISTIO_META_DNS_AUTO_ALLOCATE value: "true" - name: ISTIO_META_DNS_CAPTURE value: "true" - name: CLUSTER_ID value: "Kubernetes" resources: requests: cpu: 100m memory: 128Mi limits: cpu: 2000m memory: 1024Mi
|
1.3 Istio vs Linkerd
| 特性 |
Istio |
Linkerd |
| 架构复杂度 |
高,功能丰富 |
低,简单轻量 |
| 数据平面 |
Envoy |
Linkerd-proxy (Rust) |
| 控制平面 |
Go (多组件) |
Rust + ArMER |
| 资源消耗 |
较高 |
较低 |
| 性能 |
中等 |
较高 |
| 扩展性 |
强 |
中等 |
| 学习曲线 |
陡峭 |
平缓 |
| 生产采用 |
广泛 |
增长中 |
2. Istio 架构详解
2.1 Istio 架构组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| ┌─────────────────────────────────────────────────────────────────────────┐ │ Istio 架构图 │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────┐ │ │ │ Kubernetes │ │ │ │ Cluster │ │ │ └────────┬────────┘ │ │ │ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ Data Plane │ │ │ │ │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ │ │ Service │◄──────►│ Service │◄──────►│ Service │ │ │ │ │ │ A │ │ B │ │ C │ │ │ │ │ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ │ │ │ │ │ │ │ │ ┌────▼────┐ ┌────▼────┐ ┌────▼────┐ │ │ │ │ │ Envoy │ │ Envoy │ │ Envoy │ │ │ │ │ │ Sidecar │ │ Sidecar │ │ Sidecar │ │ │ │ │ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ │ │ │ │ │ │ │ └────────┼──────────────────┼──────────────────┼──────────────────┘ │ │ │ │ │ │ │ └──────────────────┼──────────────────┘ │ │ │ │ │ ┌───────────────────────────┼──────────────────────────────────────┐ │ │ │ Control Plane │ │ │ │ │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ │ │ Istiod │ │ Ingress │ │ Egress │ │ Kiali │ │ │ │ │ │ (统一) │ │ Gateway │ │ Gateway │ │ (可视化) │ │ │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ │ │ │ │ Istiod 包含: │ │ │ │ - Pilot: 流量管理 │ │ │ │ - Citadel: 证书管理/ mTLS │ │ │ │ - Galley: 配置管理 │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────┘
|
2.2 Istiod 核心组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
type DiscoveryServer struct { ConfigGenerator *ConfigGenerator
ServiceHandler func(*model.Service, model.Event) EndpointHandler func(*model.ServiceInstance, model.Event)
ConfigStore model.ConfigStore }
type CA struct { Sign(csrPEM []byte) ([]byte, error)
RotatedCert(cert []byte) bool }
type Galley struct { Validate(e *mcp.Change) error
Distribute(e *mcp.Change) error }
|
2.3 xDS 协议
Envoy 使用 xDS (Extensible Discovery Service) 与控制平面通信:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| ┌─────────────────────────────────────────────────────────────────────────┐ │ xDS 协议族 │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ LDS (Listener Discovery Service) │ │ │ │ ──────────────────────────────────────────────────────────── │ │ │ │ 监听器配置,定义 Envoy 监听的端口和过滤器链 │ │ │ │ 示例: 0.0.0.0:15006 监听入口流量 │ │ │ └─────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ RDS (Route Discovery Service) │ │ │ │ ──────────────────────────────────────────────────────────── │ │ │ │ 路由配置,定义 HTTP 路由规则 │ │ │ │ 示例: /api/v1/* -> v1 版本后端 │ │ │ └─────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ CDS (Cluster Discovery Service) │ │ │ │ ──────────────────────────────────────────────────────────── │ │ │ │ 上游集群配置,定义服务发现端点 │ │ │ │ 示例: cluster.outbound|80||reviews.default.svc.cluster.local │ │ │ └─────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ EDS (Endpoint Discovery Service) │ │ │ │ ──────────────────────────────────────────────────────────── │ │ │ │ 端点配置,定义集群中的实际 IP 和端口 │ │ │ │ 示例: [10.0.0.1:9080, 10.0.0.2:9080] │ │ │ └─────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ EDS (Secret Discovery Service) │ │ │ │ ──────────────────────────────────────────────────────────── │ │ │ │ 秘钥配置,传输 mTLS 证书 │ │ │ │ 示例: Kubernetes secret 用于服务账号认证 │ │ │ └─────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────┘
|
3. Sidecar 注入与流量拦截
3.1 Sidecar 注入流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| ┌─────────────────────────────────────────────────────────────────────────┐ │ Sidecar 注入流程 │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ 自动注入 (MutatingWebhook) │ │ │ └─────────────────────────────────────────────────────────────────┘ │ │ │ │ │ Pod 创建请求 │ │ │ │ │ ▼ │ │ ┌───────────────────┐ │ │ │ API Server │ │ │ └─────────┬─────────┘ │ │ │ │ │ ▼ │ │ ┌───────────────────────────────────────────────────────────────┐ │ │ │ MutatingWebhookConfiguration │ │ │ │ - namespace: istio-system │ │ │ │ - webhook: sidecar-injector │ │ │ │ - rules: │ │ │ │ - operations: [CREATE] │ │ │ │ - resources: [pods] │ │ │ │ - scope: Namespaced │ │ │ └─────────────────────────────┬─────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌───────────────────────────────────────────────────────────────┐ │ │ │ sidecar-injector webhook │ │ │ │ │ │ │ │ 1. 检查 namespace label (istio-injection: enabled) │ │ │ │ 2. 检查 pod annotation (istio.kubernetes.io/inject) │ │ │ │ 3. 渲染 Sidecar 配置 │ │ │ │ 4. 注入 istio-proxy 容器 │ │ │ │ 5. 注入 init 容器 (iptables 规则) │ │ │ └─────────────────────────────┬─────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌───────────────────┐ │ │ │ Pod 创建 │ │ │ │ + istio-proxy │ │ │ │ + istio-init │ │ │ └───────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────┘
|
3.2 Init 容器配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| initContainers: - name: istio-init image: docker.io/istio/proxyv2:1.19.0 args: - istio-iptables - --route uid 1337 - --tcp-dns - --tcp-native - --outbound-owner-groups= - --outbound-owner-ports-exclude=15020 securityContext: capabilities: add: - NET_ADMIN drop: - ALL runAsNonRoot: false runAsUser: 0
|
3.3 流量拦截原理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| ┌─────────────────────────────────────────────────────────────────────────┐ │ 流量拦截原理 │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ Host │ │ ┌───────────────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ 应用容器 istio-proxy │ │ │ │ ┌─────────┐ ┌─────────┐ │ │ │ │ │ App │◄── localhost ──►│ Envoy │ │ │ │ │ │ :8080 │ │ :15006 │ │ │ │ │ └─────────┘ └────┬────┘ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ┌───────▼───────┐ │ │ │ │ │ Outbound │ │ │ │ │ │ (出口流量) │ │ │ │ │ └───────────────┘ │ │ │ │ │ │ │ │ ┌───────────────┐ │ │ │ │ │ Inbound │ │ │ │ │ │ (入口流量) │ │ │ │ │ └───────────────┘ │ │ │ │ │ │ │ └───────────────────────────────────────────────────────────────┘ │ │ │ │ iptables 规则: │ │ ┌───────────────────────────────────────────────────────────────┐ │ │ │ # 重定向所有出口流量到 Envoy │ │ │ │ iptables -t nat -A OUTPUT -p tcp │ │ │ │ -m owner --uid-owner 1337 -j RETURN │ │ │ │ iptables -t nat -A OUTPUT -p tcp -j REDIRECT --to-ports 15001 │ │ │ │ │ │ │ │ # 重定向所有入口流量到 Envoy │ │ │ │ iptables -t nat -A PREROUTING -p tcp -j REDIRECT │ │ │ │ --to-ports 15006 │ │ │ └───────────────────────────────────────────────────────────────┘ │ │ │ │ Envoy 端口: │ │ ┌───────────────────────────────────────────────────────────────┐ │ │ │ 15001: Envoy outbound 代理端口 │ │ │ │ 15006: Envoy inbound 入口端口 │ │ │ │ 15000: Envoy 管理接口 │ │ │ │ 15090: Prometheus metrics 端口 │ │ │ │ 15021: 健康检查端口 │ │ │ └───────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────┘
|
4. 流量管理
4.1 VirtualService 路由规则
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews-route spec: hosts: - reviews http: - match: - headers: cookie: regex: "^(.*?;)?(user=jason)(;.*)?$" route: - destination: host: reviews subset: v2 weight: 100
- route: - destination: host: reviews subset: v1 weight: 50 - destination: host: reviews subset: v3 weight: 50
- match: - uri: prefix: /api/reviews route: - destination: host: reviews subset: v1 timeout: 5s retries: attempts: 3 perTryTimeout: 2s retryOn: 5xx,reset,connect-failure,retriable-4xx
|
4.2 DestinationRule 策略
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: reviews-destination spec: host: reviews trafficPolicy: connectionPool: tcp: maxConnections: 100 http: h2UpgradePolicy: UPGRADE http1MaxPendingRequests: 100 http2MaxRequests: 1000 loadBalancer: simple: LEAST_REQUEST localityLbSetting: enabled: true tls: mode: ISTIO_MUTUAL subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2
|
4.3 流量镜像
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: httpbin-mirror spec: hosts: - httpbin http: - route: - destination: host: httpbin subset: v1 weight: 100 mirror: host: httpbin subset: v2 mirrorPercentage: value: 100
|
4.4 故障注入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: ratings-fault spec: hosts: - ratings http: - match: - headers: end-user: exact: jason fault: delay: percentage: value: 100.0 fixedDelay: 5s route: - destination: host: ratings subset: v1
|
5. 可观测性
5.1 遥测配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| apiVersion: telemetry.istio.io/v1alpha1 kind: Telemetry metadata: name: mesh-default namespace: istio-system spec: tracing: - providers: - name: jaeger randomSamplingPercentage: 10.0 useRequestIdForTracingSampling: true metrics: - providers: - name: prometheus metrics: - providers: - name: prometheus overrides: - match: metric: REQUEST_COUNT tagOverrides: destination_namespace: operation: UPSERT value: 'ISTIO_INGRESS' accessLogging: - providers: - name: envoy
|
5.2 Envoy 指标
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| # Envoy 常用指标 # 请求指标 envoy_cluster_upstream_rq_total{cluster_name="outbound|80||reviews.default.svc.cluster.local"} envoy_cluster_upstream_rq_xx{cluster_name="...", response_code_class="2xx"}
# 延迟指标 envoy_cluster_upstream_rq_time_bucket{cluster_name="..."}
# 连接指标 envoy_cluster_upstream_cx_active{cluster_name="..."} envoy_cluster_upstream_cx_total{cluster_name="..."}
# 重试指标 envoy_cluster_upstream_rq_retry{cluster_name="..."}
|
5.3 分布式追踪
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| ┌─────────────────────────────────────────────────────────────────────────┐ │ 分布式追踪流程 │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ Client │ │ │ │ │ │ 1. 发起请求 (带有 trace context) │ │ │ headers: x-request-id, x-b3-traceid, x-b3-spanid │ │ ▼ │ │ ┌─────────┐ │ │ │ Service │ │ │ │ A │ │ │ │ ┌─────┐│ │ │ │ │Envoy ││ 2. 提取/注入 trace headers │ │ │ └─────┘│ │ │ └────┬────┘ │ │ │ 3. 调用 Service B │ │ ▼ │ │ ┌─────────┐ │ │ │ Service │ │ │ │ B │ │ │ │ ┌─────┐│ │ │ │ │Envoy ││ 4. 继续传播 trace context │ │ │ └─────┘│ │ │ └────┬────┘ │ │ │ 5. 调用 Service C │ │ ▼ │ │ ┌─────────┐ │ │ │ Service │ │ │ │ C │ │ │ │ ┌─────┐│ │ │ │ │Envoy ││ │ │ │ └─────┘│ │ │ └────┬────┘ │ │ │ │ │ ▼ │ │ ┌─────────┐ │ │ │ Jaeger │ │ │ │(Tracing)│ │ │ └─────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────┘
|
6. 安全架构
6.1 mTLS 双向认证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| ┌─────────────────────────────────────────────────────────────────────────┐ │ mTLS 双向认证流程 │ ├─────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────┐ ┌─────────┐ │ │ │ Service │ │ Service │ │ │ │ A │ │ B │ │ │ │ ┌─────┐ │ │ ┌─────┐ │ │ │ │ │Envoy │ │◄── TLS ────►│ │Envoy │ │ │ │ │ └─────┘ │ │ └─────┘ │ │ │ └────┬────┘ └────┬────┘ │ │ │ │ │ │ └────────────────────────┴────────────────────────┐ │ │ │ │ │ │ ▼ ▼ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ Istiod (CA) │ │ │ │ │ │ │ │ 1. Service A 请求证书: │ │ │ │ CSR: {"spiffe://cluster.local/ns/default/sa/service-a"} │ │ │ │ │ │ │ │ 2. Istiod 验证 ServiceAccount │ │ │ │ - 检查 Kubernetes API │ │ │ │ - 确认 service-a 有权使用该 identity │ │ │ │ │ │ │ │ 3. 签发证书 │ │ │ │ Certificate: │ │ │ │ Subject: spiffe://cluster.local/ns/default/sa/service-a │ │ │ │ Issuer: cluster.local │ │ │ │ Validity: 24h │ │ │ │ │ │ │ │ 4. 证书自动续期 (每 24h) │ │ │ │ │ │ │ └─────────────────────────────────────────────────────────────────┘ │ │ │ │ TLS 握手流程: │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ Client │ │ │ │ │ │ │ │ │ │ 1. ClientHello (支持 TLS 版本, 加密套件) │ │ │ │ │────────────────────────────────────────────────────────► │ │ │ │ │ │ │ │ │ │ 2. ServerHello + Certificate + ServerKeyExchange │ │ │ │ │◄──────────────────────────────────────────────────────── │ │ │ │ │ │ │ │ │ │ 3. CertificateVerify (使用私钥签名 challenge) │ │ │ │ │────────────────────────────────────────────────────────► │ │ │ │ │ │ │ │ │ │ 4. Finished │ │ │ │ │◄──────────────────────────────────────────────────────── │ │ │ │ │ │ │ │ │ │ 5. 应用数据 (加密) │ │ │ │ │◄════════════════════════════════════════════════════════► │ │ │ │ │ │ │ │ └─────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────┘
|
6.2 AuthorizationPolicy 授权
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: frontend-ingress namespace: default spec: selector: matchLabels: app: backend action: ALLOW rules: - from: - source: principals: - "cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account" to: - operation: methods: ["GET", "POST"] paths: ["/api/*"]
- from: - source: namespaces: ["default"] to: - operation: methods: ["GET"] paths: ["/health", "/ready"]
|
6.3 PeerAuthentication mTLS 模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: default namespace: istio-system spec: mTLS: mode: STRICT
---
apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: default namespace: production spec: mTLS: mode: STRICT portLevelMtls: 8080: mode: DISABLE
|
6.4 RequestAuthentication JWT
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: jwt-example namespace: default spec: selector: matchLabels: app: api jwtRules: - issuer: "accounts.google.com" audiences: - "my-app" forwardOriginalToken: true headers: - Authorization jwksUri: https://www.googleapis.com/oauth2/v3/certs claimToHeaders: - claim: email header: X-User-Email
|
7. Gateway 管理
7.1 Ingress Gateway
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: ingress-gateway namespace: istio-system spec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - "*.example.com" tls: httpsRedirect: true - port: number: 443 name: https protocol: HTTPS hosts: - "*.example.com" tls: mode: SIMPLE credentialName: example-cert ---
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: api-virtualservice spec: hosts: - "api.example.com" gateways: - istio-system/ingress-gateway http: - match: - uri: prefix: /v1 route: - destination: host: api-service port: number: 8080
|
7.2 Egress Gateway
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: egress-gateway namespace: istio-system spec: selector: istio: egressgateway servers: - port: number: 443 name: https protocol: HTTPS hosts: - "external-service.example.com" tls: mode: SIMPLE credentialName: egress-cert ---
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: external-service spec: hosts: - "external-service.example.com" gateways: - istio-system/egress-gateway tls: - match: - port: 443 sniHosts: - "external-service.example.com" route: - destination: host: istio-egressgateway.istio-system.svc.cluster.local port: number: 443
|
8. 最佳实践
8.1 命名空间隔离
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| apiVersion: v1 kind: Namespace metadata: name: production labels: istio-injection: enabled ---
apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: production-mtls namespace: production spec: mTLS: mode: STRICT
|
8.2 渐进式部署
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: myapp-canary spec: hosts: - myapp http: - match: - headers: x-canary: exact: "true" route: - destination: host: myapp subset: canary weight: 100 - route: - destination: host: myapp subset: stable weight: 100
|
8.3 性能优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| apiVersion: v1 kind: Pod metadata: name: myapp spec: containers: - name: myapp resources: limits: cpu: 500m memory: 512Mi - name: istio-proxy resources: requests: cpu: 10m memory: 64Mi limits: cpu: 1000m memory: 512Mi ---
apiVersion: networking.istio.io/v1alpha3 kind: ProxyConfig metadata: name: default namespace: istio-system spec: concurrency: 2
|
9. 关键源码路径
| 组件 |
路径 |
| Istiod |
istio/istio/pilot/ |
| Envoy xDS |
istio/istio/pilot/pkg/xds/ |
| Sidecar Injector |
istio/istio/pilot/pkg/kube/inject/ |
| Security |
istio/istio/pilot/pkg/security/ |
| Telemetry |
istio/istio/pilot/pkg/telemetry/ |
| Linkerd |
github.com/linkerd/linkerd2/ |
| Envoy |
github.com/envoyproxy/envoy/ |
面试题
基础题
1. 什么是服务网格?为什么需要服务网格?
服务网格是用于处理服务间通信的基础设施层,通过 Sidecar 代理模式实现:
- 将网络、安全、可观测性功能从业务代码中分离
- 统一管理服务间通信策略
- 提供透明的流量管理
需要服务网格的原因:
- 微服务间通信逻辑复杂(重试、超时、熔断)
- 缺乏统一的可观测性
- 安全策略难以集中管理
2. Sidecar 模式是什么?有什么优缺点?
Sidecar 将代理容器与应用容器部署在同一 Pod 中:
- 优点:独立升级、不影响业务代码、透明拦截流量
- 缺点:资源开销增加、延迟略有增加、运维复杂度提高
3. Istio 的主要组件有哪些?
- Istiod:统一控制平面(包含 Pilot、Citadel、Galley)
- Envoy Sidecar:数据平面代理
- Ingress/Egress Gateway:网关
- Kiali:可观测性 UI
4. xDS 协议包含哪些服务?
- LDS:监听器发现
- RDS:路由发现
- CDS:集群发现
- EDS:端点发现
- SDS:秘钥发现
5. mTLS 相比普通 TLS 有什么优势?
mTLS 是双向认证:
- 客户端验证服务端证书
- 服务端也验证客户端证书
- 确保通信双方的身份可信
- 防止中间人攻击和未授权访问
中级题
6. Istio 如何实现流量拦截?
通过 Init 容器设置 iptables 规则:
- Init 容器以 root 权限运行
- 配置 iptables REDIRECT 规则
- 所有入站/出站流量被重定向到 Envoy
- Envoy 处理后再转发给应用
7. VirtualService 和 DestinationRule 的区别是什么?
- VirtualService:定义路由规则(怎么走)
- DestinationRule:定义后端策略(到了之后怎么办)
VirtualService 处理流量分发,DestinationRule 处理连接池、负载均衡、tls 设置。
8. 如何实现金丝雀部署?
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| apiVersion: networking.istio.io/v1alpha3 kind: VirtualService spec: http: - route: - destination: host: myapp subset: stable weight: 90 - destination: host: myapp subset: canary weight: 10
|
9. Istio 的安全架构包含哪些组件?
- Citadel/Istiod:CA,签发证书
- PeerAuthentication:mTLS 模式配置
- AuthorizationPolicy:细粒度访问控制
- RequestAuthentication:JWT 验证
10. 如何排查服务网格问题?
- 检查 Sidecar 是否注入:
kubectl get pod -o yaml | grep istio-proxy
- 检查 Envoy 配置:
istioctl proxy-config
- 查看 Envoy 日志:
kubectl logs -c istio-proxy
- 检查 mTLS 状态:
istioctl authz check
- 使用 Kiali 可视化服务拓扑
高级题
11. 分析 Istio 的证书管理机制
Istiod 作为 CA:
- Kubernetes ServiceAccount 认证
- 签发 SPIFFE 格式证书(spiffe://cluster.local/ns/…)
- SDS 分发证书到 Envoy
- 每 24 小时自动续期
证书包含 identity 信息,支持 workload-to-workload 认证。
12. 如何实现渐进式迁移到服务网格?
- 并行部署:先部署 Gateway,不启用 Sidecar
- 流量镜像:测试 Sidecar 配置
- 逐步注入:按命名空间启用自动注入
- Permissive 模式:允许混合 mTLS 和明文
- Strict 模式:完全迁移到 mTLS
13. Istio 和 Linkerd 应该如何选择?
| 场景 |
推荐 |
| 需要丰富功能 |
Istio |
| 追求简单轻量 |
Linkerd |
| 高性能要求 |
Linkerd |
| 需要深度定制 |
Istio |
| 团队经验不足 |
Linkerd |
| 多团队协作 |
Istio |
场景题
14. 如何配置服务间 100% mTLS?
1 2 3 4 5 6 7 8 9
| apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: default namespace: istio-system spec: mTLS: mode: STRICT
|
15. 如何实现基于权重的灰度发布?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: myapp spec: hosts: - myapp http: - route: - destination: host: myapp subset: v1 weight: 80 - destination: host: myapp subset: v2 weight: 20
|
16. 如何在服务网格中实现外部服务访问控制?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: egress-gateway namespace: istio-system spec: selector: istio: egressgateway servers: - port: number: 443 name: https protocol: HTTPS hosts: - "*.mysql.example.com" ---
apiVersion: networking.istio.io/v1alpha3 kind: ServiceEntry metadata: name: mysql-external spec: hosts: - mysql.external.com location: MESH_EXTERNAL ports: - number: 3306 name: tcp protocol: TCP resolution: DNS
|