4. 多租户模型设计:命名空间(Namespace)作为租户边界,RBAC与网络策略的协同

在多租户 Kubernetes 集群中,命名空间(Namespace)是最基础、最自然的租户隔离边界。每个租户独占一个或多个命名空间,所有工作负载、配置和网络资源都在该边界内运行。然而,仅靠命名空间无法实现真正的安全隔离——必须将 RBAC(基于角色的访问控制)与 NetworkPolicy(网络策略)深度协同,才能构建从“管理平面”到“数据平面”的完整租户隔离体系。

4.1 命名空间作为租户边界的核心原则

将命名空间视为租户边界时,需遵循以下设计原则:

原则 说明 实施要点
独占性 每个租户至少拥有一个独立命名空间,不允许跨租户共享 通过准入控制器(如 OPA/NAC)强制命名空间与租户 ID 绑定
资源配额 为每个命名空间设置 ResourceQuota 和 LimitRange 防止单个租户耗尽集群资源,保障公平调度
网络边界 默认拒绝跨命名空间流量,仅显式允许的通信可通过 配合 NetworkPolicy 实现“白名单”模式
管理隔离 租户管理员只能操作自己命名空间内的资源 通过 RBAC Role/ClusterRole 精确授权
关键设计决策: 对于大型租户,建议采用“一个租户多个命名空间”模式(如 dev/staging/prod 环境分离),但所有命名空间必须共享统一的租户标签(如 tenant: acme-corp),以便网络策略和审计日志的聚合管理。

4.2 RBAC 与 NetworkPolicy 的协同模型

RBAC 控制“谁能做什么”(管理平面),NetworkPolicy 控制“哪个 Pod 能与哪个 Pod 通信”(数据平面)。两者协同才能形成完整的租户隔离矩阵:

协同口诀: RBAC 管人,NetworkPolicy 管网。人进不去命名空间,网就无需考虑他的流量;网不通,人即使有权限也无法访问服务。

4.2.1 协同层次结构

  1. 第一层:RBAC 命名空间准入 — 租户管理员只能看到和操作自己命名空间内的 Deployment、Service、Pod 等资源。
  2. 第二层:NetworkPolicy 默认拒绝 — 在租户命名空间内创建默认拒绝所有入站/出站流量的策略,防止 Pod 被意外暴露。
  3. 第三层:显式允许策略 — 根据业务需求,通过 NetworkPolicy 开放特定端口和标签选择器,允许跨命名空间通信(如共享数据库服务)。
  4. 第四层:审计与监控 — 结合 RBAC 审计日志和网络流量日志,验证隔离策略是否被绕过。

4.3 典型多租户网络策略设计模式

以下 SVG 图展示了三个租户(Tenant-A、Tenant-B、Tenant-C)在共享集群中的网络隔离架构,以及 RBAC 与 NetworkPolicy 的协同作用点:

多租户网络隔离架构:RBAC 与 NetworkPolicy 协同 多租户网络隔离架构:RBAC 与 NetworkPolicy 协同 Kubernetes 集群边界 Tenant-A 命名空间 Pod: frontend Pod: backend NetworkPolicy: 默认拒绝入站 RBAC Role: tenant-a-admin • 允许 frontend → backend: 8080 • 拒绝外部命名空间入站 • 允许访问共享 DNS Tenant-B 命名空间 Pod: web Pod: api NetworkPolicy: 仅允许同命名空间 RBAC Role: tenant-b-developer • 仅允许 web ↔ api 通信 • 拒绝所有跨命名空间流量 • 允许访问集群 DNS Tenant-C 命名空间 Pod: app Pod: cache NetworkPolicy: 开放特定端口 RBAC Role: tenant-c-readonly • 允许 app → cache: 6379 • 允许 Tenant-A backend 访问 (通过 namespaceSelector) ❌ 拒绝 ✅ 允许 共享服务: kube-dns / ingress

4.4 RBAC 与 NetworkPolicy 协同配置示例

以下是一个完整的 Helm Chart 模板片段,展示如何在部署时同时创建 RBAC 角色和网络策略:

{{- /* templates/tenant-isolation.yaml */ -}}
{{- range .Values.tenants }}
---
apiVersion: v1
kind: Namespace
metadata:
  name: {{ .name }}
  labels:
    tenant: {{ .name }}
    environment: {{ .environment | default "production" }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: {{ .name }}-admin
  namespace: {{ .name }}
rules:
- apiGroups: [""]
  resources: ["pods", "services", "configmaps", "secrets"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["networking.k8s.io"]
  resources: ["networkpolicies"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: {{ .name }}-admin-binding
  namespace: {{ .name }}
subjects:
- kind: User
  name: {{ .adminUser }}
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: {{ .name }}-admin
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: {{ .name }}
spec:
  podSelector: {}
  policyTypes:
  - Ingress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-intra-tenant
  namespace: {{ .name }}
spec:
  podSelector: {}
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          tenant: {{ .name }}
  policyTypes:
  - Ingress
{{- end }}
常见陷阱: 仅创建 default-deny-ingress 策略而不创建出站策略,可能导致 Pod 无法访问集群 DNS 或监控 Agent。建议同时创建允许出站到 kube-system 命名空间 DNS 服务的策略,或使用 default-deny-egress 配合显式允许。

4.5 多租户网络策略命中与隔离验证矩阵

下表总结了不同场景下 RBAC 与 NetworkPolicy 的协同效果:

场景 RBAC 权限 NetworkPolicy 规则 实际结果
租户 A 管理员查看租户 B 的 Pod 无权限(Role 限定命名空间) 不相关 ❌ API 返回 403 Forbidden
租户 A 的 frontend 访问租户 B 的 api 有权限(Pod 可出站) 租户 B 默认拒绝入站 ❌ 网络层丢弃,连接超时
租户 A 的 backend 访问租户 C 的 cache 有权限 租户 C 显式允许(namespaceSelector) ✅ 连接成功,端口 6379
租户 C 的 app 访问集群外部数据库 有权限 出站策略允许 egress 到特定 CIDR ✅ 连接成功
恶意用户尝试创建跨租户 NetworkPolicy 无权限(ClusterRole 限制) 不相关 ❌ API 拒绝,审计日志记录

4.6 最佳实践与避坑指南

  • 标签标准化: 所有命名空间必须包含统一的租户标签(如 tenant-id),NetworkPolicy 的 namespaceSelector 依赖此标签进行跨命名空间授权。
  • 默认拒绝策略先行: 在创建任何允许策略之前,先部署 default-deny-ingress 和 default-deny-egress,避免策略生效前的窗口期暴露。
  • RBAC 最小权限: 租户管理员角色只授予其命名空间内的 NetworkPolicy 管理权限,禁止修改集群级别的 ClusterNetworkPolicy(如果使用 Cilium 等 CNI)。
  • 审计与告警: 开启 Kubernetes 审计日志,监控 NetworkPolicy 的创建/更新/删除操作,并设置告警规则检测非预期的策略变更。
  • Helm 模板化: 将租户配置抽象为 values.yaml 中的列表,通过 range 循环生成命名空间、RBAC 和 NetworkPolicy,确保一致性并减少手工错误。
生产级建议: 对于超过 50 个租户的集群,考虑使用 vCluster 或 Kiosk 等虚拟集群方案,将每个租户的 API Server 隔离,从根本上避免 RBAC 配置错误导致的越权风险。此时 NetworkPolicy 仍作为第二层网络隔离防线。