3. 租户隔离蓝图设计:基于 CiliumNetworkPolicy 的租户隔离模型、租户标识(Label/ServiceAccount)设计
在 Kubernetes 多租户环境中,网络隔离是保障租户安全的第一道防线。Cilium 通过 CiliumNetworkPolicy (CNP) 提供了比传统 NetworkPolicy 更精细、更高效的隔离能力。本章将深入设计基于 CNP 的租户隔离模型,并明确租户标识(Label / ServiceAccount)的设计策略。
3.1 租户隔离模型架构
本课程采用的租户隔离模型遵循 “命名空间 + 标识 + 策略” 三层架构。每个租户拥有独立的命名空间,通过 ServiceAccount 和自定义 Label 进行身份标识,再通过 CiliumNetworkPolicy 实现东西向与南北向的流量控制。
设计原则:
- 最小权限:默认拒绝所有跨租户流量,仅显式允许必要通信。
- 标识驱动:使用 ServiceAccount 作为租户身份的核心载体,Label 作为辅助分组。
- 策略分层:基础隔离策略由平台团队统一部署,租户自定义策略在命名空间内叠加。
3.2 租户标识设计:Label 与 ServiceAccount
租户标识是策略匹配的基础。CiliumNetworkPolicy 支持基于 Label 和 ServiceAccount 两种方式进行身份选择。本设计采用 “ServiceAccount 为主,Label 为辅” 的策略。
| 标识类型 | 作用范围 | 设计建议 | 示例 |
|---|---|---|---|
| ServiceAccount | 命名空间级别 | 每个租户创建一个专用 ServiceAccount,作为身份锚点 | tenant-a-sa |
| 租户 Label | 跨命名空间 | 使用 tenant=<租户名> 统一标识,便于策略匹配 |
tenant=tenant-a |
| 应用 Label | 命名空间内 | 用于区分租户内部的不同服务(如 frontend、backend) | app=frontend |
| 环境 Label | 全局 | 标识部署环境(prod、staging),用于环境级隔离 | env=prod |
最佳实践: 将 ServiceAccount 作为策略中的
fromEndpoints 或 toEndpoints 匹配条件,可以避免因 Pod 重启或 Label 变更导致的策略失效。Label 更适合用于分组和可视化。
3.3 CiliumNetworkPolicy 隔离策略设计
基于上述标识设计,我们定义三类核心策略:
- 基础拒绝策略(Default Deny):在每个租户命名空间内部署,拒绝所有入站和出站流量,除非被显式允许。
- 同租户允许策略:允许相同
tenantLabel 的 Pod 之间通信。 - 跨租户白名单策略:在需要时,显式允许特定 ServiceAccount 或 Label 的跨租户访问。
3.4 策略示例:同租户内部通信
以下策略允许租户 A 命名空间内所有具有 tenant=tenant-a Label 的 Pod 相互通信:
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-same-tenant-a
namespace: ns-tenant-a
spec:
endpointSelector:
matchLabels:
tenant: tenant-a
ingress:
- fromEndpoints:
- matchLabels:
tenant: tenant-a
egress:
- toEndpoints:
- matchLabels:
tenant: tenant-a
3.5 策略示例:跨租户白名单通信
当租户 A 的 backend 服务需要访问租户 B 的 db 服务时,需要在租户 B 的命名空间中创建入站策略:
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-from-tenant-a-backend
namespace: ns-tenant-b
spec:
endpointSelector:
matchLabels:
app: db
ingress:
- fromEndpoints:
- matchLabels:
tenant: tenant-a
app: backend
注意: 跨租户策略必须部署在目标租户的命名空间中,且需要双方管理员协商确认。Cilium 支持
fromEndpoints 跨命名空间匹配,但前提是源端 Pod 携带了正确的 Label。
3.6 标识设计对比总结
| 维度 | Label 方式 | ServiceAccount 方式 | 推荐场景 |
|---|---|---|---|
| 灵活性 | 高,可动态增删改 | 中,创建后相对固定 | Label 适合动态分组;ServiceAccount 适合固定身份 |
| 安全性 | 中,Label 可能被误修改 | 高,ServiceAccount 受 RBAC 保护 | 核心身份用 ServiceAccount,辅助属性用 Label |
| 策略可读性 | 中,需要理解 Label 语义 | 高,ServiceAccount 名称直观 | 策略中优先使用 ServiceAccount 匹配 |
| 运维成本 | 低,Label 随 Pod 自动继承 | 中,需要为每个 Pod 指定 ServiceAccount | 大规模集群建议结合使用 |
最终设计决策: 本课程采用 “ServiceAccount 作为租户身份主键,tenant Label 作为辅助分组” 的混合模式。所有 Pod 必须绑定对应租户的 ServiceAccount,同时携带
tenant=<租户名> Label。CiliumNetworkPolicy 中优先使用 fromEndpoints.matchLabels 匹配 ServiceAccount,其次使用 tenant Label 进行批量允许。