2. 多租户架构基础:多租户定义、租户隔离模型与 Envoy 中的租户标识
2.1 多租户定义与核心概念
多租户(Multi-Tenancy)是一种软件架构模式,允许单个软件实例或集群同时服务多个独立的用户群体(即“租户”)。在云原生和微服务环境中,每个租户通常对应一个业务部门、一个外部客户组织或一个内部项目团队。
多租户架构的核心目标是实现资源复用与逻辑隔离的平衡。与单租户架构相比,多租户能显著降低运维成本和基础设施开销,但必须确保租户之间的数据、流量和性能互不干扰。
关键区分:多租户 ≠ 多用户。多用户指同一系统内有多个账号,但共享同一数据空间和配置;多租户则要求每个租户拥有独立的逻辑或物理边界,包括配置、路由规则、限流策略和可观测性数据。
2.2 租户隔离模型:硬隔离与软隔离
根据隔离的严格程度和实现方式,租户隔离模型主要分为硬隔离和软隔离两大类。下表对比了两种模型的核心差异:
| 维度 | 硬隔离(Hard Isolation) | 软隔离(Soft Isolation) |
|---|---|---|
| 资源分配 | 每个租户独占物理或虚拟资源(独立集群、独立节点) | 租户共享同一集群,通过配额和优先级进行资源竞争 |
| 故障影响 | 一个租户的故障不会扩散到其他租户 | 故障可能通过共享资源池影响其他租户(需流控保护) |
| 性能保障 | 严格保证,无“吵闹邻居”效应 | 通过权重、限流和优先级尽力保障 |
| 运维成本 | 高(独立部署、独立升级、独立监控) | 低(统一运维、统一升级、统一监控) |
| 适用场景 | 金融核心、合规敏感、超大规模租户 | SaaS 多租户、内部开发环境、中小规模租户 |
在 Envoy 和 Istio 的实践中,软隔离是更常见的模式。Envoy 通过连接池、HTTP/2 流控、熔断器和限流等机制,在共享数据平面内实现租户间的软隔离。硬隔离则通常通过 Kubernetes 节点亲和性、独立 Sidecar 或独立控制平面来实现。
架构决策提示:选择硬隔离还是软隔离,取决于租户的 SLA 要求和故障容忍度。对于需要严格故障边界的租户(如生产环境 vs 测试环境),建议采用硬隔离;对于需要灵活扩缩容的 SaaS 场景,软隔离配合 Envoy 的精细化流控是更优解。
2.3 Envoy 中的租户标识机制
Envoy 本身不感知“租户”这一业务概念,但提供了多种机制来标识和区分不同租户的流量。这些标识是后续实现流控、路由和故障隔离的基础。
常见的租户标识方式包括:
- HTTP Header 标识:在请求中插入自定义 Header(如
X-Tenant-ID),Envoy 通过header_matcher或metadata动态路由。 - JWT Claim 标识:从 JWT 的
sub、iss或自定义 Claim 中提取租户信息。 - 源 IP/子网标识:根据请求来源 IP 或 CIDR 范围划分租户。
- gRPC Metadata:在 gRPC 请求的 Metadata 中携带租户上下文。
以下是一个典型的 Envoy 动态转发配置片段,展示如何根据 X-Tenant-ID Header 将流量路由到不同的上游集群:
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
stat_prefix: ingress_http
route_config:
name: tenant_routes
virtual_hosts:
- name: tenant_a
domains: ["*"]
routes:
- match:
headers:
- name: X-Tenant-ID
string_match: { exact: "tenant-alpha" }
route:
cluster: tenant_alpha_cluster
- name: tenant_b
domains: ["*"]
routes:
- match:
headers:
- name: X-Tenant-ID
string_match: { exact: "tenant-beta" }
route:
cluster: tenant_beta_cluster
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
下图展示了 Envoy 中基于 Header 的租户标识与路由流程:
2.4 租户标识的最佳实践
在实际部署中,租户标识的选取直接影响流控策略的准确性和可维护性。以下是几条经过验证的实践原则:
- 标准化标识名称:在整个网格内统一使用
X-Tenant-ID或X-Org-ID等标准 Header,避免不同服务使用不同命名。 - 标识不可伪造:在入口网关处验证 JWT 签名或从可信的认证服务中获取租户信息,防止客户端伪造租户标识绕过隔离策略。
- 标识与元数据绑定:将租户标识与 Envoy 的
metadata动态元数据绑定,便于在限流、熔断和可观测性中引用。 - 考虑嵌套租户:对于大型组织,可能需要支持“租户组”或“子租户”层级,此时标识应包含层级信息(如
X-Tenant-ID: org:dept:team)。
常见陷阱:不要仅依赖请求路径(如
/tenant-a/api/)来标识租户。路径容易因路由重写或 API 版本升级而改变,且难以在 gRPC 等非 HTTP/1.x 协议中统一处理。优先使用 Header 或 JWT Claim 作为稳定的标识载体。
下图展示了在 Istio/Envoy 网格中,租户标识从入口网关到 Sidecar 再到上游服务的完整传递链路: