2. Envoy 基础架构回顾:Listener、Cluster、Endpoint、Route、Filter 工作机制
在深入多租户流量隔离与故障域演练之前,必须重新梳理 Envoy 代理的核心抽象层。Envoy 的架构设计遵循“四层一链”原则:Listener(监听器)负责接收流量,Filter(过滤器)负责处理流量,Route(路由)负责匹配流量,Cluster(集群)负责管理上游端点,Endpoint(端点)代表实际服务实例。理解这五个组件之间的协作关系,是构建隔离策略的基础。
2.1 五大核心组件概览
| 组件 | 职责 | 多租户隔离中的角色 |
|---|---|---|
| Listener | 绑定端口/Unix Domain Socket,接收入站连接 | 按租户分配独立监听端口或协议(如 TLS SNI) |
| Filter | 处理请求/响应的可插拔逻辑单元 | 注入租户识别、限流、Header 改写、日志标签 |
| Route | 根据请求属性(Host、Path、Header)匹配路由规则 | 按租户 ID 分发到不同集群或权重分组 |
| Cluster | 定义上游服务集群的连接策略、负载均衡、健康检查 | 每个租户独立 Cluster,实现连接池与熔断隔离 |
| Endpoint | 上游服务实例的 IP:Port 地址 | 按故障域(AZ/Region)分组,支持优先级切流 |
2.2 组件协作流程与内联 SVG 架构图
下图展示了 Envoy 从接收到上游响应的完整数据流。注意 Filter Chain 在 Listener 和 Route 之间执行,而 Cluster 负责管理到 Endpoint 的连接池。
2.3 Listener:流量入口与协议分化
Listener 是 Envoy 的流量入口点。每个 Listener 绑定一个独立端口或 Unix Domain Socket,并指定接收流量的传输协议(TCP、UDP、TLS)。在多租户场景中,通常采用以下隔离模式:
- 端口隔离: 每个租户分配独立端口(如 10001、10002),每个端口对应一个 Listener。
- SNI 隔离: 共享 443 端口,通过 TLS 的 Server Name Indication 区分租户域名。
- 协议分化: 同一 Listener 可配置多个 Filter Chain,按协议类型(HTTP/1.1、HTTP/2、gRPC)分流。
2.4 Filter:可插拔的流量处理管道
Filter 是 Envoy 最灵活的扩展点。它分为 Listener Filter(连接建立阶段)、Network Filter(L4 层)、HTTP Filter(L7 层)。在多租户隔离中,以下 Filter 至关重要:
| Filter 类型 | 典型实现 | 隔离用途 |
|---|---|---|
| Listener Filter | TLS Inspector | 提取 SNI 识别租户 |
| Network Filter | TCP Proxy | 按源 IP 限制连接速率 |
| HTTP Filter | Router / Lua / External Authorization | Header 改写、租户鉴权、请求限流 |
| HTTP Filter | gRPC-Web / gRPC-JSON Transcoder | 协议转换,适配不同租户客户端 |
2.5 Route:请求匹配与流量分发
Route 配置位于 RouteConfiguration 中,通过 VirtualHost 和 Route 两层匹配规则实现。一个典型的租户路由配置如下:
static_resources:
listeners:
- name: ingress_listener
address:
socket_address: { address: 0.0.0.0, port_value: 8080 }
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
route_config:
name: tenant_routes
virtual_hosts:
- name: tenant_a
domains: ["tenant-a.example.com"]
routes:
- match: { prefix: "/api" }
route: { cluster: "tenant_a_cluster" }
- name: tenant_b
domains: ["tenant-b.example.com"]
routes:
- match: { prefix: "/api" }
route: { cluster: "tenant_b_cluster" }
2.6 Cluster:连接池与熔断隔离
Cluster 是 Envoy 管理上游连接的核心抽象。每个 Cluster 拥有独立的:
- 连接池: 最大连接数、最大请求数、空闲超时。
- 熔断器: 主动检测、被动检测、异常点驱逐。
- 负载均衡策略: 轮询、最少请求、一致性哈希。
- 健康检查: HTTP/TCP/gRPC 健康探测。
在多租户架构中,每个租户对应一个独立 Cluster,确保一个租户的流量突发不会耗尽另一个租户的连接池资源。故障域演练时,可以通过调整 Cluster 的 circuit_breakers 阈值模拟上游故障。
2.7 Endpoint:故障域感知与优先级切流
Endpoint 是 Cluster 下的实际服务实例。Envoy 支持 LocalityLbEndpoints 按地域(Region、Zone、Sub-zone)分组,并设置优先级。这是实现故障域切流的关键机制:
clusters:
- name: tenant_a_cluster
type: STRICT_DNS
lb_policy: LEAST_REQUEST
load_assignment:
cluster_name: tenant_a_cluster
endpoints:
- locality:
region: us-east-1
zone: us-east-1a
lb_endpoints:
- endpoint: { address: { socket_address: { address: "10.0.1.10", port_value: 80 } } }
priority: 0
- locality:
region: us-east-1
zone: us-east-1b
lb_endpoints:
- endpoint: { address: { socket_address: { address: "10.0.2.10", port_value: 80 } } }
priority: 1
当 priority 0 的端点全部不健康时,Envoy 自动将流量切换到 priority 1 的端点。这种机制天然支持跨可用区故障转移。
2.8 组件协作总结:从请求到响应的完整路径
结合上述组件,一个完整的请求处理路径如下:
- Listener 接收 TCP 连接,根据 SNI 或端口选择 Filter Chain。
- Filter Chain 执行租户识别、限流、Header 注入等前置逻辑。
- Route 根据 Host/Path/Header 匹配到目标 Cluster。
- Cluster 从连接池获取连接,应用熔断与负载均衡策略。
- Endpoint 根据优先级和健康状态选择具体实例,转发请求。
- 响应沿原路径返回,Filter Chain 执行后置处理(日志、指标)。