3. 多租户概念与模型:租户定义、租户隔离级别与身份标识设计
在构建基于 Istio 的多租户签名链路通信机制之前,必须首先建立清晰的多租户概念模型。本章将定义租户的边界、隔离级别以及共享集群下的核心挑战,并最终给出租户身份标识的设计方案。
3.1 租户定义与核心属性
在多租户系统中,租户 是一个逻辑隔离单元,代表一组共享访问权限、配置策略和资源配额的用户或服务集合。在云原生环境中,租户可以映射为组织、团队、项目或业务线。
| 属性 | 说明 | 示例 |
|---|---|---|
| 租户 ID | 全局唯一标识符,用于区分不同租户 | tenant-a、tenant-b |
| 命名空间集合 | 租户所拥有的 Kubernetes 命名空间列表 | ns-a1、ns-a2 |
| 服务账户集合 | 租户下所有工作负载使用的服务账户 | sa-backend、sa-frontend |
| 策略绑定 | 授权策略、网络策略、配额策略的集合 | AuthorizationPolicy、QuotaSpec |
| 签名密钥 | 用于请求签名的私钥/公钥对或证书 | ECDSA P-256 密钥对 |
设计要点: 租户 ID 应设计为不可变字符串,并在整个集群范围内唯一。推荐使用 UUID 或具有业务含义的短字符串(如
tenant-{org}-{env}),以便于审计和策略匹配。
3.2 租户隔离级别
Kubernetes 与 Istio 提供了三种主要的隔离粒度,每种粒度对应不同的安全边界和运维复杂度。
- 集群级隔离: 每个租户独占一个 Kubernetes 集群。隔离性最强,但资源利用率低,管理成本高。
- 命名空间级隔离: 每个租户占用一个或多个命名空间。通过 RBAC、NetworkPolicy 和 Istio AuthorizationPolicy 实现隔离。这是最常见的多租户模式。
- 服务级隔离: 在同一个命名空间内,通过服务账户和细粒度策略区分不同租户。适用于轻量级租户或内部子租户场景。
推荐实践: 在共享集群的多租户场景中,优先采用 命名空间级隔离,并结合 Istio 的
AuthorizationPolicy 和 PeerAuthentication 实现服务间通信的强制签名校验。
3.3 共享集群下的多租户挑战
当多个租户共享同一个 Kubernetes 集群时,会面临以下核心挑战:
- 命名空间冲突: 不同租户可能使用相同的命名空间名称(如
default、production),需要前缀或映射机制。 - 网络策略穿透: 默认情况下,命名空间之间可以互相通信,必须通过 NetworkPolicy 和 Istio AuthorizationPolicy 显式阻断跨租户流量。
- 证书与密钥管理: 每个租户需要独立的签名密钥,且密钥的轮换、吊销不能影响其他租户。
- 资源竞争与配额: 一个租户的异常流量或资源消耗可能影响其他租户的服务质量。
- 审计与可观测性: 日志、指标和追踪需要按租户维度进行隔离和聚合,避免数据泄露。
关键风险: 如果未正确配置 Istio 的
PeerAuthentication 为 STRICT 模式,且未绑定到具体租户的命名空间,则恶意租户可能绕过签名校验,伪造请求访问其他租户的服务。
3.4 租户身份标识设计
租户身份标识是签名链路通信的基础。在 Istio 环境中,我们利用 服务账户 和 自定义请求头 来传递租户身份。
3.4.1 身份标识载体
| 载体 | 位置 | 示例值 | 安全性 |
|---|---|---|---|
| SPIFFE ID | mTLS 证书 SAN | spiffe://cluster.local/ns/ns-a/sa/sa-backend |
高(由 Istio 自动注入) |
| 自定义请求头 | HTTP Header | X-Tenant-ID: tenant-a |
中(需签名保护) |
| JWT 令牌 | Authorization Header | Bearer <jwt> |
高(可携带租户声明) |
3.4.2 推荐设计方案:SPIFFE ID + 签名请求头
本课程采用 SPIFFE ID 作为租户身份的基础锚点,同时通过 签名请求头 传递租户 ID 和请求摘要,实现请求级别的身份验证。
# 租户身份标识结构示例
# SPIFFE ID: spiffe://cluster.local/ns/tenant-a-ns/sa/tenant-a-sa
# 签名请求头:
X-Tenant-ID: tenant-a
X-Request-Digest: sha256=abc123...
X-Request-Signature: MEUCIQD...
X-Signature-Algorithm: ecdsa-p256
设计原则: 租户 ID 必须同时出现在 SPIFFE ID 的命名空间或服务账户名称中,以及签名请求头中。接收方在验证签名后,还需比对 SPIFFE ID 中的租户信息与请求头中的租户 ID 是否一致,防止身份伪造。
3.5 多租户身份与隔离模型总览
下图展示了共享集群下,两个租户(Tenant A 和 Tenant B)在命名空间级隔离下的身份标识与通信路径。
3.6 租户身份标识设计决策矩阵
下表总结了不同身份标识方案在关键维度上的对比,帮助你在实际项目中做出选择。
| 方案 | 实现复杂度 | 安全强度 | 运维成本 | 适用场景 |
|---|---|---|---|---|
| SPIFFE ID 仅 | 低 | 中 | 低 | 内部服务间通信,无需请求级身份 |
| SPIFFE ID + 签名请求头 | 中 | 高 | 中 | 本课程推荐,适用于签名链路通信 |
| JWT 令牌 | 高 | 高 | 高 | 需要携带额外声明(如角色、权限)的场景 |
| 自定义请求头(无签名) | 低 | 低 | 低 | 仅用于调试或内部非敏感环境 |