服务网格架构深度剖析

概述

服务网格(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
# Istio 自动注入 Sidecar
apiVersion: v1
kind: Pod
metadata:
name: myapp
namespace: default
spec:
containers:
- name: myapp
image: myapp:v1
ports:
- containerPort: 8080
# Istio 自动注入的 Sidecar
- 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
// Istiod 主要组件

// 1. Discovery Server (原 Pilot)
// 处理服务发现和 xDS 配置分发
type DiscoveryServer struct {
// Envoy 配置生成
ConfigGenerator *ConfigGenerator

// 服务发现
ServiceHandler func(*model.Service, model.Event)
EndpointHandler func(*model.ServiceInstance, model.Event)

// Config 存储
ConfigStore model.ConfigStore
}

// 2. Certificate Authority (原 Citadel)
// 生成和管理 mTLS 证书
type CA struct {
// 证书签发
Sign(csrPEM []byte) ([]byte, error)

// 证书轮换
RotatedCert(cert []byte) bool
}

// 3. Configuration Controller (原 Galley)
// 验证和分发配置
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
# Init 容器配置 - 设置 iptables 规则
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
# VirtualService 示例
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 # 优先路由到 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
# DestinationRule - 定义后端服务策略
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 # mTLS
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
# 镜像到 v2(不返回结果)
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
# 或注入错误
# abort:
# httpStatus: 500
# percentage:
# value: 100
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
# Telemetry 配置 (Istio 1.20+)
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
# AuthorizationPolicy - 细粒度访问控制
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: frontend-ingress
namespace: default
spec:
# 作用目标
selector:
matchLabels:
app: backend
# 作用层级
action: ALLOW # ALLOW, DENY, AUDIT, CUSTOM
rules:
# 规则 1: 允许 ingress-gateway 访问
- from:
- source:
principals:
- "cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account"
to:
- operation:
methods: ["GET", "POST"]
paths: ["/api/*"]

# 规则 2: 允许带特定 header 的请求
- 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
# PeerAuthentication - 全局 mTLS 配置
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: istio-system
spec:
mTLS:
mode: STRICT # STRICT, PERMISSIVE, DISABLE

---
# 命名空间级别配置
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: production
spec:
mTLS:
mode: STRICT
portLevelMtls:
8080:
mode: DISABLE # 特定端口禁用 mTLS

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
# RequestAuthentication - JWT 验证
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
# 从 Authorization header 提取 token
headers:
- Authorization
# JWT public key 来源
jwksUri: https://www.googleapis.com/oauth2/v3/certs
# 自定义 claim 提取
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
# Istio Ingress Gateway
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"
# HTTP 重定向到 HTTPS
tls:
httpsRedirect: true
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- "*.example.com"
tls:
mode: SIMPLE
credentialName: example-cert
---
# 绑定 VirtualService
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
# Egress Gateway - 控制出口流量
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
---
# 出口流量 VirtualService
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
# 命名空间启用 Istio
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:
# 基于 header 的灰度
- 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 # 降低 Sidecar CPU 预留
memory: 64Mi
limits:
cpu: 1000m
memory: 512Mi
---
# 全局 Sidecar 配置
apiVersion: networking.istio.io/v1alpha3
kind: ProxyConfig
metadata:
name: default
namespace: istio-system
spec:
concurrency: 2 # Envoy 工作线程数

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 规则:

  1. Init 容器以 root 权限运行
  2. 配置 iptables REDIRECT 规则
  3. 所有入站/出站流量被重定向到 Envoy
  4. 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. 如何排查服务网格问题?

  1. 检查 Sidecar 是否注入:kubectl get pod -o yaml | grep istio-proxy
  2. 检查 Envoy 配置:istioctl proxy-config
  3. 查看 Envoy 日志:kubectl logs -c istio-proxy
  4. 检查 mTLS 状态:istioctl authz check
  5. 使用 Kiali 可视化服务拓扑

高级题

11. 分析 Istio 的证书管理机制

Istiod 作为 CA:

  1. Kubernetes ServiceAccount 认证
  2. 签发 SPIFFE 格式证书(spiffe://cluster.local/ns/…)
  3. SDS 分发证书到 Envoy
  4. 每 24 小时自动续期

证书包含 identity 信息,支持 workload-to-workload 认证。

12. 如何实现渐进式迁移到服务网格?

  1. 并行部署:先部署 Gateway,不启用 Sidecar
  2. 流量镜像:测试 Sidecar 配置
  3. 逐步注入:按命名空间启用自动注入
  4. Permissive 模式:允许混合 mTLS 和明文
  5. Strict 模式:完全迁移到 mTLS

13. Istio 和 Linkerd 应该如何选择?

场景 推荐
需要丰富功能 Istio
追求简单轻量 Linkerd
高性能要求 Linkerd
需要深度定制 Istio
团队经验不足 Linkerd
多团队协作 Istio

场景题

14. 如何配置服务间 100% mTLS?

1
2
3
4
5
6
7
8
9
# 全局 STRICT 模式
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
# Egress Gateway 控制出口流量
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"
---
# ServiceEntry 声明外部服务
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