3. 多租户模型设计:租户定义、命名空间隔离、资源配额与网络策略基础
在 Kubernetes 集群中实现多租户隔离,核心在于将逻辑租户映射到物理集群资源上,并通过一系列原生机制确保故障域、资源域与安全域的独立。本节将定义租户模型,并深入讲解命名空间隔离、ResourceQuota 与 NetworkPolicy 的基础配置。
3.1 租户定义与模型抽象
租户(Tenant)是集群资源与工作负载的逻辑所有者。在云原生架构中,租户通常对应一个团队、一个项目或一个业务线。租户模型需明确以下属性:
| 属性 | 描述 | 示例值 |
|---|---|---|
| Tenant ID | 全局唯一标识符,用于审计与计费 | tenant-001 |
| Namespace 集合 | 租户独占的命名空间列表 | ns-team-alpha-prod, ns-team-alpha-staging |
| 资源配额 | CPU、内存、存储、对象数的上限 | CPU: 32 cores, Memory: 128Gi |
| 网络策略 | 入站/出站流量控制规则 | 仅允许同租户 Namespace 通信 |
| RBAC 绑定 | 租户管理员与成员的角色绑定 | ClusterRoleBinding 或 RoleBinding |
设计原则: 每个租户至少拥有一个生产 Namespace 和一个预发 Namespace。禁止跨租户共享 Namespace,这是故障域隔离的底线。
3.2 命名空间隔离:租户的边界墙
Kubernetes Namespace 是隔离的基础单元。每个租户的工作负载、ConfigMap、Secret 都应部署在专属 Namespace 内。命名空间隔离策略如下:
- 命名规范:
<tenant-id>-<environment>,例如tenant-alpha-prod。 - 标签注入: 每个 Namespace 必须携带
tenant: <tenant-id>标签,便于策略匹配与审计。 - 禁止默认 Namespace: 生产环境禁止使用
defaultNamespace 部署任何业务负载。
# 创建租户 Namespace 示例
apiVersion: v1
kind: Namespace
metadata:
name: tenant-alpha-prod
labels:
tenant: tenant-alpha
environment: production
isolation-tier: high
注意: 命名空间隔离仅提供逻辑分组,不提供网络或资源硬隔离。必须配合 NetworkPolicy 与 ResourceQuota 才能形成完整的多租户故障域。
3.3 资源配额(ResourceQuota):防止租户资源抢占
ResourceQuota 是 Kubernetes 原生资源管控机制,用于限制一个 Namespace 内所有 Pod 的资源总和。在多租户场景下,它为每个租户划定资源上限,避免某个租户的异常流量或错误配置耗尽集群资源,从而保护其他租户的稳定性。
| 配额类型 | 作用范围 | 典型配置 |
|---|---|---|
| 计算资源 | CPU / Memory 请求与限制 | requests.cpu: "32", limits.memory: "128Gi" |
| 存储资源 | PVC 总容量与数量 | requests.storage: "500Gi", persistentvolumeclaims: "10" |
| 对象数量 | Pod、Service、ConfigMap 等数量 | pods: "50", services: "20" |
# 租户 ResourceQuota 配置示例
apiVersion: v1
kind: ResourceQuota
metadata:
name: tenant-alpha-quota
namespace: tenant-alpha-prod
spec:
hard:
requests.cpu: "32"
requests.memory: "128Gi"
limits.cpu: "64"
limits.memory: "256Gi"
pods: "50"
persistentvolumeclaims: "10"
requests.storage: "500Gi"
最佳实践: 为每个租户的每个 Namespace 创建独立的 ResourceQuota。同时设置
LimitRange 来约束单个 Pod 的资源范围,防止单个 Pod 占满整个租户配额。
3.4 网络策略(NetworkPolicy):租户间流量隔离
NetworkPolicy 是 Kubernetes 原生的网络访问控制机制,基于 Pod 标签和 Namespace 选择器实现精细化的流量管控。在多租户架构中,NetworkPolicy 是防止租户间横向移动攻击、保障网络故障域隔离的关键。
基础策略模型包含三类规则:
- 默认拒绝入站: 拒绝所有非本租户 Namespace 的入站流量。
- 允许同租户通信: 允许同一租户下不同 Namespace 之间的必要通信。
- 允许系统组件: 允许监控、日志、DNS 等基础设施组件的访问。
# 租户隔离 NetworkPolicy 示例
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tenant-alpha-isolation
namespace: tenant-alpha-prod
spec:
podSelector: {} # 匹配该 Namespace 下所有 Pod
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
tenant: tenant-alpha # 仅允许同租户 Namespace 的流量
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system # 允许系统组件
egress:
- to:
- namespaceSelector:
matchLabels:
tenant: tenant-alpha
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
关键点: NetworkPolicy 需要 CNI 插件支持(如 Calico、Cilium)。在 etcd 故障场景下,NetworkPolicy 控制器可能失效,因此建议在集群升级前验证策略的持久化状态。
3.5 多租户隔离架构总览
下图展示了基于命名空间、资源配额与网络策略的多租户隔离架构。每个租户拥有独立的 Namespace 集合,ResourceQuota 划定资源边界,NetworkPolicy 控制流量边界,共同构成故障域隔离的基础。
3.6 多租户隔离清单与验证
在集群升级前,必须逐项验证多租户隔离配置的有效性。以下为关键检查项:
| 检查项 | 验证方法 | 预期结果 |
|---|---|---|
| Namespace 标签完整性 | kubectl get ns --show-labels |
每个 Namespace 携带 tenant 标签 |
| ResourceQuota 生效 | kubectl describe quota -n <ns> |
配额已绑定,且当前使用量在限制内 |
| NetworkPolicy 隔离 | 从跨租户 Pod 发起 curl 测试 |
连接超时或被拒绝 |
| 同租户通信 | 从同租户不同 Namespace 发起 curl |
连接正常 |
升级前必做: 在 etcd 故障模拟场景中,NetworkPolicy 控制器可能因 etcd 不可用而无法同步最新规则。建议在升级前将关键 NetworkPolicy 规则导出为静态备份,并验证 CNI 插件在 etcd 恢复后的策略重载能力。