2. 多租户隔离基础:Namespace、RBAC、NetworkPolicy 的租户隔离策略
在云原生多租户集群中,租户隔离是保障安全与资源公平性的第一道防线。Kubernetes 原生提供了三层隔离机制:Namespace(资源边界)、RBAC(权限边界)、NetworkPolicy(网络边界)。这三层共同构成“逻辑隔离 + 权限管控 + 网络封锁”的纵深防御体系,是 Argo CD 多租户模板蓝图落地的前提条件。
核心原则: 租户隔离不是“一刀切”的物理隔离,而是基于命名空间、角色、网络策略的组合逻辑隔离。在 Argo CD 联动场景中,每个租户对应一个或多个 Namespace,并通过 RBAC 限制其只能操作自身命名空间内的资源。
2.1 三层隔离模型总览
下表对比了三种隔离维度的作用范围、核心对象与典型场景:
| 隔离维度 | 核心对象 | 作用范围 | 典型场景 |
|---|---|---|---|
| Namespace | Namespace | 资源分组与配额 | 按团队/项目划分资源池,设置 ResourceQuota、LimitRange |
| RBAC | Role / ClusterRole RoleBinding / ClusterRoleBinding |
API 访问权限 | 租户只能管理自身 Namespace 下的 Deployment、Service、ConfigMap |
| NetworkPolicy | NetworkPolicy | Pod 网络通信 | 禁止跨租户 Pod 直接通信,只允许同 Namespace 或特定标签的流量 |
关键认知: Namespace 提供“房间”,RBAC 提供“钥匙”,NetworkPolicy 提供“隔音墙”。三者缺一不可,且必须按“先划分、再授权、后封锁”的顺序落地。
2.2 Namespace:资源边界与配额管理
Namespace 是 Kubernetes 中最基础的隔离单元。在多租户场景中,每个租户至少拥有一个独立的 Namespace,用于承载其全部工作负载。关键配置包括:
- ResourceQuota:限制租户可消耗的 CPU、内存、存储卷、Service 数量等总量。
- LimitRange:为 Pod 和容器设置默认资源请求/限制,防止单个 Pod 耗尽配额。
- 命名规范:建议使用
<tenant-id>-<env>格式,例如team-alpha-prod、team-alpha-staging。
# 创建租户 Namespace 并设置配额
apiVersion: v1
kind: Namespace
metadata:
name: team-alpha-prod
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-alpha-quota
namespace: team-alpha-prod
spec:
hard:
requests.cpu: "8"
requests.memory: "16Gi"
limits.cpu: "16"
limits.memory: "32Gi"
persistentvolumeclaims: "10"
services: "20"
---
apiVersion: v1
kind: LimitRange
metadata:
name: team-alpha-limits
namespace: team-alpha-prod
spec:
limits:
- default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "200m"
memory: "256Mi"
type: Container
常见陷阱: 仅靠 Namespace 无法阻止租户 A 的 Pod 访问租户 B 的 Service(DNS 可解析)。必须配合 NetworkPolicy 实现网络隔离。同时,RBAC 必须限制租户不能查看或修改其他 Namespace 的资源。
2.3 RBAC:细粒度权限控制
RBAC 决定了“谁”能对“哪些资源”执行“什么操作”。在多租户场景中,我们通常使用 Role + RoleBinding(命名空间级别)而非 ClusterRole + ClusterRoleBinding(集群级别),以确保权限范围被严格限定在租户的 Namespace 内。
典型租户角色设计:
| 角色名称 | 权限范围 | 可操作资源 | 适用对象 |
|---|---|---|---|
tenant-admin |
单个 Namespace | Deployment, StatefulSet, Service, ConfigMap, Secret, Ingress, HPA | 租户团队负责人 |
tenant-developer |
单个 Namespace | Pod (get/list/watch/logs/exec), Deployment (get/list/watch) | 租户普通开发人员 |
tenant-viewer |
单个 Namespace | 所有资源 (get/list/watch) | 审计、只读监控 |
# 创建租户管理员 Role 并绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: team-alpha-prod
name: tenant-admin
rules:
- apiGroups: ["apps", "extensions"]
resources: ["deployments", "statefulsets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: [""]
resources: ["pods", "services", "configmaps", "secrets", "persistentvolumeclaims"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["autoscaling"]
resources: ["horizontalpodautoscalers"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: team-alpha-prod
name: tenant-admin-binding
subjects:
- kind: User
name: "alice@team-alpha.com"
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: tenant-admin
apiGroup: rbac.authorization.k8s.io
Argo CD 集成要点: Argo CD 的 Application 通常使用
argocd-manager ServiceAccount 部署资源。在多租户场景中,应为每个租户 Namespace 创建独立的 ServiceAccount,并通过 RBAC 授予其仅操作本 Namespace 的权限。Argo CD 的 Project 对象会进一步约束 Application 的目标 Namespace。
2.4 NetworkPolicy:网络流量隔离
NetworkPolicy 是 Kubernetes 网络隔离的“最后一公里”。默认情况下,Kubernetes 集群内所有 Pod 可以互相通信(扁平网络)。多租户场景必须打破这种默认行为,实现“默认拒绝,按需放行”。
典型策略组合:
- 默认拒绝所有入站流量:防止外部 Namespace 的 Pod 访问本租户 Pod。
- 允许同 Namespace 内通信:保证租户内部微服务正常调用。
- 允许特定系统组件访问:例如允许
monitoring-ns的 Prometheus 抓取指标,允许ingress-ns的 Ingress Controller 转发流量。 - 可选:限制出站流量:防止租户 Pod 访问外部恶意地址或数据泄露。
# 策略1:默认拒绝所有入站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: team-alpha-prod
spec:
podSelector: {}
policyTypes:
- Ingress
---
# 策略2:允许同 Namespace 内所有 Pod 通信
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-same-namespace
namespace: team-alpha-prod
spec:
podSelector: {}
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: team-alpha-prod
policyTypes:
- Ingress
---
# 策略3:允许 Prometheus 从 monitoring-ns 抓取指标
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-prometheus-scrape
namespace: team-alpha-prod
spec:
podSelector:
matchLabels:
app: my-app
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: monitoring-ns
ports:
- port: 9090
protocol: TCP
policyTypes:
- Ingress
2.5 三层隔离的联动配置清单
在实际落地时,建议按照以下顺序执行配置,避免权限或网络漏洞:
- 创建 Namespace:为每个租户创建独立 Namespace,并设置 ResourceQuota 和 LimitRange。
- 创建 RBAC 角色与绑定:为租户团队创建 Role,并通过 RoleBinding 绑定到用户/ServiceAccount。
- 部署默认拒绝 NetworkPolicy:在每个租户 Namespace 中部署
default-deny-ingress策略。 - 按需添加允许策略:根据业务需求,添加同 Namespace 通信、Ingress Controller、监控系统等白名单策略。
- 验证隔离效果:使用
kubectl auth can-i验证 RBAC,使用临时 Pod 测试网络连通性。
重要提醒: NetworkPolicy 需要 CNI 插件支持(如 Calico、Cilium、Weave Net)。如果集群未安装支持 NetworkPolicy 的 CNI,所有策略将不会生效,租户 Pod 仍可自由通信。务必在集群创建阶段确认 CNI 能力。
完成这三层隔离后,每个租户将拥有一个“独立”的运行环境。下一阶段,我们将基于这些隔离的 Namespace,设计 Argo CD 的 Application 模板与多租户 Project 结构,实现“一次配置,批量部署”的蓝图能力。