4. 多租户隔离模型:租户标识、路由隔离、资源配额
在多租户服务网格中,Envoy 作为数据面代理需要同时承载多个租户的流量。本章节聚焦于如何通过租户标识、路由隔离和资源配额三个维度,构建一个可观测、可控制、可保障的隔离模型。该模型是后续 HTTP/2 流控参数调优的基础上下文——不同的隔离策略直接影响流控参数的生效范围和配置粒度。
4.1 租户标识:从请求到连接的归属判定
租户标识是多租户隔离的第一道关卡。Envoy 支持在多个层级提取租户信息,并将其注入到请求上下文中,供后续路由和限流决策使用。
| 标识层级 | 典型字段 | 提取方式 | 适用场景 |
|---|---|---|---|
| HTTP Header | x-tenant-id |
Header 匹配 / 动态元数据 | 网关入口、外部请求 |
| JWT Claim | sub / tenant |
JWT 认证过滤器提取 | 需要身份认证的租户 |
| TLS 证书 | Subject / SAN | DownstreamTlsContext 解析 | mTLS 双向认证场景 |
| 连接元数据 | 源 IP / 端口 | 原始连接匹配 | 内部服务间调用 |
x-tenant-id 标准 Header 作为租户标识载体,配合 Envoy 的 DynamicMetadata 机制将租户信息传递到限流和路由过滤器链中,避免在多个过滤器间重复解析。
4.2 路由隔离:基于租户的流量分片
路由隔离确保不同租户的请求被导向各自专属的后端集群,避免租户间流量串扰。Envoy 通过 VirtualHost 和 Route 的层级组合实现细粒度隔离。
4.2.1 虚拟主机级隔离
为每个租户创建独立的 VirtualHost,通过域名或 Header 值进行区分。这种方式隔离粒度最粗,但配置清晰,适合租户数量较少(通常 < 50)的场景。
virtual_hosts:
- name: tenant_a_vh
domains: ["tenant-a.example.com"]
routes:
- match: { prefix: "/" }
route: { cluster: "tenant-a-backend" }
- name: tenant_b_vh
domains: ["tenant-b.example.com"]
routes:
- match: { prefix: "/" }
route: { cluster: "tenant-b-backend" }
4.2.2 路由级隔离
在同一个 VirtualHost 内,通过路由匹配条件(Header、Path、Query 参数)区分租户。这种方式适合共享域名但需要逻辑隔离的场景,例如 SaaS 平台。
routes:
- match:
headers:
- name: "x-tenant-id"
string_match: { exact: "tenant-a" }
route: { cluster: "tenant-a-backend" }
- match:
headers:
- name: "x-tenant-id"
string_match: { exact: "tenant-b" }
route: { cluster: "tenant-b-backend" }
direct_response 或返回 404,防止未携带租户标识的请求被错误路由到任意后端。
4.3 资源配额:保障租户间的公平性与稳定性
资源配额是多租户隔离的最终保障。Envoy 通过全局限流(Global Rate Limiting)和本地限流(Local Rate Limiting)两个维度,对每个租户的请求速率、并发连接数、内存占用进行约束。
4.3.1 全局限流配置
基于 envoy.extensions.filters.http.ratelimit.v3.RateLimit 过滤器,配合外部限流服务(如 Envoy 自带的 envoy.rate_limit 或独立的限流集群)实现跨实例的租户级配额控制。
http_filters:
- name: envoy.filters.http.ratelimit
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit
domain: tenant-quota
rate_limit_service:
grpc_service:
envoy_grpc:
cluster_name: rate_limit_cluster
request_type: both
4.3.2 本地限流配置
使用 envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit 过滤器,在每个 Envoy 实例上独立执行限流。本地限流延迟更低,适合对延迟敏感的租户,但无法保证全局公平性。
http_filters:
- name: envoy.filters.http.local_ratelimit
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
stat_prefix: tenant_local_ratelimit
_bucket:
max_tokens: 100
tokens_per_fill: 10
fill_interval: 1s
filter_enabled:
runtime_key: local_ratelimit.enabled
default_value:
numerator: 100
denominator: HUNDRED
4.3.3 配额维度与参数
| 配额维度 | 参数 | 推荐初始值 | 超限行为 |
|---|---|---|---|
| 请求速率 (RPS) | max_tokens / tokens_per_fill |
100 / 10 | 429 Too Many Requests |
| 并发连接数 | max_connections (连接管理器) |
200 | 连接拒绝 |
| 并发请求数 | max_requests (连接管理器) |
500 | 503 Service Unavailable |
| 内存占用 | listener_udp_write_buffer / 连接池限制 |
64 MB | 连接池驱逐 |
4.4 隔离模型架构总览
下图展示了从租户标识提取到路由隔离、再到资源配额控制的完整数据流。该架构是后续 HTTP/2 流控参数调优的部署上下文。
4.5 隔离模型与 HTTP/2 流控的关联
多租户隔离模型直接影响 HTTP/2 流控参数的配置策略:
- 连接级流控:每个租户的
initial_connection_window_size应独立配置,避免一个租户的慢消费阻塞其他租户的连接。 - 流级流控:租户级
initial_stream_window_size需要与配额中的并发请求数联动,防止单个租户的突发流量耗尽全局流控窗口。 - 连接复用:路由隔离后,每个租户的后端连接池独立管理,
max_concurrent_streams参数应基于租户配额动态调整。