2. 服务网格基础:Istio/Envoy 数据平面与控制平面架构、Sidecar 代理模式、流量劫持原理
服务网格(Service Mesh)是云原生微服务通信的基础设施层,它将服务间通信的复杂性从应用代码中剥离,交由专门的代理层处理。Istio 是目前最主流的服务网格实现,其底层核心代理为 Envoy。理解 Istio 的数据平面与控制平面架构、Sidecar 代理模式以及流量劫持原理,是构建安全流量拓扑基线的第一步。
2.1 控制平面与数据平面架构
Istio 采用经典的控制平面/数据平面分离架构,两者职责明确,协同工作。
核心原则: 数据平面负责处理所有业务流量,控制平面负责下发配置与策略,两者通过 xDS 协议通信,实现“数据与逻辑分离”。
| 平面 | 核心组件 | 主要职责 | 通信协议 |
|---|---|---|---|
| 控制平面 | istiod (Pilot、Citadel、Galley) | 服务发现、证书签发、配置管理、策略下发 | xDS (CDS/EDS/LDS/RDS/SDS) |
| 数据平面 | Envoy Proxy (Sidecar) | 流量转发、负载均衡、健康检查、TLS 终止、遥测数据采集 | HTTP/1.1, HTTP/2, gRPC, TCP |
控制平面(istiod) 是网格的大脑。它将用户定义的路由规则、安全策略、监控配置等转换为 Envoy 可理解的 xDS 协议配置,并通过 gRPC 流推送到每个 Sidecar 代理。
数据平面(Envoy) 是网格的肌肉。它以 Sidecar 模式部署在每个业务 Pod 中,拦截所有进出 Pod 的流量,并根据控制平面下发的配置执行路由、熔断、重试、认证等操作。
2.2 Sidecar 代理模式
Sidecar 模式是服务网格的核心部署形态。Istio 通过自动注入或手动注入的方式,将 Envoy 代理作为一个独立的容器添加到业务 Pod 中,与业务容器共享网络命名空间。
关键特性: Sidecar 代理对业务应用完全透明。应用无需感知代理的存在,也无需修改代码即可获得流量管理、安全、可观测性能力。
Sidecar 模式的优势:
- 非侵入式: 业务容器只关注业务逻辑,通信能力由 Sidecar 统一提供。
- 语言无关: 无论应用使用 Java、Go、Python 还是 Node.js,Sidecar 都使用统一的 Envoy 代理。
- 独立升级: 代理的升级、配置变更不影响业务容器,反之亦然。
- 安全隔离: 代理可以独立实施 TLS 终止、访问控制、限流等安全策略。
| 对比维度 | 传统 SDK 模式 | Sidecar 代理模式 |
|---|---|---|
| 侵入性 | 高,需引入特定语言库 | 低,完全透明 |
| 升级成本 | 需重新编译部署所有服务 | 仅需重启 Sidecar 容器 |
| 多语言支持 | 每种语言需独立实现 | 统一代理,语言无关 |
| 资源开销 | 集成在进程内,开销较低 | 额外代理进程,增加少量延迟 |
2.3 流量劫持原理
流量劫持是 Sidecar 代理能够拦截所有进出 Pod 流量的关键技术。Istio 利用 iptables 规则,在 Pod 的网络命名空间内将流量重定向到 Envoy 代理的监听端口。
劫持流程:
- 入站劫持: 所有发往 Pod IP 的入站流量(目标端口非 15006),被 iptables 规则重定向到 Envoy 的入站端口(15006)。
- 出站劫持: 所有从业务容器发出的出站流量(目标端口非 15001),被 iptables 规则重定向到 Envoy 的出站端口(15001)。
- Envoy 处理: Envoy 根据控制平面下发的配置,对流量进行路由、策略执行、TLS 握手等操作,然后将流量转发到实际目标。
注意: 流量劫持依赖于 Pod 的 NET_ADMIN 和 NET_RAW 能力。在安全要求极高的环境中,可以通过配置
traffic.sidecar.istio.io/includeOutboundIPRanges 等注解来精细化控制劫持范围,或使用 cni 模式替代 iptables 劫持。
2.4 流量劫持的配置与验证
Istio 通过 istio-init 初始化容器在 Pod 启动时注入 iptables 规则。用户可以通过 Pod 注解或全局配置调整劫持行为。
常用劫持配置注解:
traffic.sidecar.istio.io/includeInboundPorts:指定需要劫持的入站端口列表,默认劫持所有端口。traffic.sidecar.istio.io/excludeInboundPorts:排除不需要劫持的入站端口。traffic.sidecar.istio.io/includeOutboundIPRanges:指定需要劫持的出站 IP 范围,默认劫持所有出站流量。sidecar.istio.io/inject:设置为"true"或"false"控制是否注入 Sidecar。
验证劫持是否生效:
# 进入 Pod 查看 iptables 规则
kubectl exec -it <pod-name> -c istio-proxy -- iptables -t nat -L -n -v
# 预期输出应包含类似以下规则
# Chain PREROUTING (policy ACCEPT)
# ISTIO_INBOUND tcp -- anywhere anywhere tcp dpt:8080
# Chain OUTPUT (policy ACCEPT)
# ISTIO_OUTPUT tcp -- anywhere anywhere
安全基线提示: 在配置 OPA 策略时,应确保 Sidecar 注入和流量劫持的配置符合安全基线。例如,禁止通过注解排除关键端口(如 22、6443)的劫持,防止绕过安全策略。同时,建议启用
STRICT 模式的 mTLS,确保所有网格内流量都经过加密和身份验证。