4、租户隔离模型设计:基于 Namespace 的软隔离、基于 NetworkPolicy 的网络隔离、基于 ResourceQuota 的资源隔离
在多租户 Kubernetes 集群中,租户隔离是保障安全性与稳定性的核心基石。本章围绕三层隔离模型展开:Namespace 软隔离提供逻辑边界,NetworkPolicy 网络隔离控制流量访问,ResourceQuota 资源隔离确保公平调度。三者组合形成纵深防御体系,适用于开发/测试环境隔离、部门级租户隔离以及生产级严格隔离场景。
4.1 三层隔离模型总览
下表对比了三种隔离机制的关注点、实现层次与典型用途:
| 隔离维度 | 实现层次 | 核心机制 | 隔离强度 | 典型场景 |
|---|---|---|---|---|
| Namespace 软隔离 | 控制面逻辑 | 资源命名空间 + RBAC | 弱(逻辑隔离) | 多团队共享集群,资源命名与权限分离 |
| NetworkPolicy 网络隔离 | 数据面网络 | CNI 插件 + 网络策略规则 | 中(L3/L4 流量控制) | 微服务间访问控制,禁止跨租户通信 |
| ResourceQuota 资源隔离 | 调度面配额 | 资源配额 + LimitRange | 中(资源上限保障) | 防止单个租户耗尽集群资源 |
4.2 基于 Namespace 的软隔离
Namespace 是 Kubernetes 中最基础的隔离单元,本质上是控制面内的逻辑分区。它不提供网络或资源层面的硬隔离,但结合 RBAC 可以实现“谁可以操作哪些资源”的权限隔离。
- 命名隔离:同一 Namespace 内的资源名称必须唯一,跨 Namespace 可重名。
- 权限隔离:通过 RoleBinding 将角色绑定到特定 Namespace,实现最小权限原则。
- 服务发现隔离:默认情况下,Service 的 DNS 名称仅在相同 Namespace 内可直接解析(
svc.cluster.local),跨 Namespace 需使用svc.namespace.svc.cluster.local全限定名。
# 创建租户隔离 Namespace 示例
apiVersion: v1
kind: Namespace
metadata:
name: tenant-alpha
labels:
tenant: alpha
environment: production
---
apiVersion: v1
kind: Namespace
metadata:
name: tenant-beta
labels:
tenant: beta
environment: production
4.3 基于 NetworkPolicy 的网络隔离
NetworkPolicy 是 Kubernetes 原生的网络隔离机制,通过标签选择器定义 Pod 组之间的入站(Ingress)和出站(Egress)流量规则。其生效前提是集群已安装支持 NetworkPolicy 的 CNI 插件(如 Calico、Cilium、Weave Net)。
4.3.1 默认拒绝策略
在启用 NetworkPolicy 的 Namespace 中,如果未定义任何策略,默认允许所有流量。要实现租户隔离,通常先部署一条“默认拒绝所有入站流量”的策略:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: tenant-alpha
spec:
podSelector: {}
policyTypes:
- Ingress
4.3.2 跨租户隔离策略
以下策略确保 tenant-alpha 的 Pod 只能被同一 Namespace 内带有 app: frontend 标签的 Pod 访问,拒绝来自 tenant-beta 或其他 Namespace 的流量:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-only-internal-frontend
namespace: tenant-alpha
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
tenant: alpha
podSelector:
matchLabels:
app: frontend
namespaceSelector 与 podSelector 组合使用,可以精确控制“哪些 Namespace 中的哪些 Pod”可以访问目标 Pod。这是实现租户级网络隔离的核心语法。
4.4 基于 ResourceQuota 的资源隔离
ResourceQuota 为每个 Namespace 设置资源上限,防止单个租户的 Pod 或 PVC 消耗过多集群资源,导致其他租户的服务受影响。它覆盖计算资源(CPU、内存)、存储资源(PVC 容量、存储类数量)以及对象数量(Pod、Service、ConfigMap 等)。
4.4.1 配额定义示例
apiVersion: v1
kind: ResourceQuota
metadata:
name: tenant-alpha-quota
namespace: tenant-alpha
spec:
hard:
requests.cpu: "8"
requests.memory: "16Gi"
limits.cpu: "16"
limits.memory: "32Gi"
persistentvolumeclaims: "10"
pods: "50"
services: "20"
configmaps: "30"
4.4.2 LimitRange 配合使用
仅设置 ResourceQuota 还不够——如果 Pod 未设置 requests/limits,配额无法生效。LimitRange 可以为 Namespace 内的容器设置默认资源请求与限制,确保每个 Pod 都纳入配额管理:
apiVersion: v1
kind: LimitRange
metadata:
name: tenant-alpha-limits
namespace: tenant-alpha
spec:
limits:
- default:
cpu: 500m
memory: 512Mi
defaultRequest:
cpu: 200m
memory: 256Mi
type: Container
4.5 三层隔离组合架构图
下图展示了三层隔离模型在单个租户 Namespace 内的协同工作方式:
4.6 隔离模型选择矩阵
根据租户隔离需求强度,推荐以下组合方案:
| 隔离等级 | Namespace | NetworkPolicy | ResourceQuota | 适用场景 |
|---|---|---|---|---|
| L1 基础隔离 | ✅ 必须 | ❌ 可选 | ✅ 推荐 | 开发环境、非敏感业务 |
| L2 中等隔离 | ✅ 必须 | ✅ 必须 | ✅ 必须 | 测试环境、部门级租户 |
| L3 严格隔离 | ✅ 必须 | ✅ 必须 + 默认拒绝 | ✅ 必须 + LimitRange | 生产环境、金融/合规场景 |
准入控制 Webhook 自动为每个新 Namespace 注入默认的 NetworkPolicy(默认拒绝入站)和 ResourceQuota 模板,确保租户隔离策略从创建之初就生效,避免人工遗漏。
4.7 隔离模型验证清单
部署完成后,建议按以下步骤验证隔离效果:
- Namespace 隔离验证:使用
kubectl auth can-i检查跨 Namespace 的 RBAC 权限是否被拒绝。 - 网络隔离验证:在租户 A 的 Pod 内执行
curl或nc访问租户 B 的 Service IP,确认连接超时或被拒绝。 - 资源配额验证:尝试在租户 Namespace 内创建超过配额上限的 Pod 或 PVC,确认被 API Server 拒绝并返回
403 Forbidden。 - LimitRange 验证:创建未设置 requests/limits 的 Pod,确认自动注入默认值。
# 验证网络隔离示例命令
# 在 tenant-alpha 的 Pod 中测试访问 tenant-beta 的 Service
kubectl exec -n tenant-alpha deploy/test-pod -- curl -m 3 http://service-b.tenant-beta.svc.cluster.local
# 预期输出:连接超时或拒绝(取决于 NetworkPolicy 配置)
# curl: (28) Connection timed out after 3000 milliseconds