3. 租户边界定义:Kubernetes多租户模型与RBAC设计
在多集群与Helm结合的场景下,租户边界是配额校准的基石。本章定义Kubernetes原生多租户模型、资源隔离策略以及身份与RBAC设计,确保每个租户在集群内拥有清晰、安全且可审计的操作边界。
3.1 Kubernetes多租户模型:Namespace与ClusterScope
Kubernetes本身不提供“租户”原生对象,而是通过Namespace和ClusterScope资源组合实现多租户隔离。下表对比两种作用域的核心差异:
| 维度 | Namespace(命名空间级) | ClusterScope(集群级) |
|---|---|---|
| 资源范围 | Pod、Service、ConfigMap、Secret、Deployment等 | Node、PersistentVolume、ClusterRole、Namespace本身 |
| 隔离粒度 | 逻辑隔离,网络策略可跨Namespace | 全局可见,需谨慎授权 |
| 配额控制 | ResourceQuota + LimitRange | 无原生配额,需通过准入控制或外部策略引擎 |
| 租户归属 | 每个租户独占一个或多个Namespace | 集群管理员或平台服务使用 |
| Helm部署影响 | Release作用域默认绑定Namespace | ClusterRole/ClusterRoleBinding需手动管理 |
实践建议:在多租户Helm部署中,每个租户至少分配一个专属Namespace,并将所有工作负载Release限定在该Namespace内。集群级资源(如StorageClass、ClusterRole)由平台团队统一管理,不归属任何租户。
3.2 租户资源隔离策略
资源隔离是多租户安全的核心。以下策略按隔离强度从低到高排列,适用于不同合规等级:
- Namespace隔离(基础):每个租户使用独立Namespace,通过ResourceQuota限制CPU/内存/PVC总量,通过LimitRange设置容器默认资源请求。
- 网络隔离(中等):部署NetworkPolicy,默认拒绝所有跨Namespace流量,仅允许租户内部通信及必要的监控/日志出口。
- 节点隔离(严格):使用NodeSelector + Taint/Toleration将租户Pod调度到专属节点池,避免资源争抢。
- 存储隔离(数据安全):为每个租户创建独立StorageClass或PVC命名前缀,配合RBAC限制PersistentVolume的创建与挂载。
Helm集成要点:在Chart的values.yaml中暴露
tenantId参数,模板中自动注入Namespace标签、NetworkPolicy选择器以及ResourceQuota名称,实现租户级配置模板化。
3.3 租户身份与RBAC设计
租户身份通常映射为Kubernetes中的ServiceAccount或User,通过RBAC绑定控制权限。设计原则遵循最小权限与租户边界自包含:
- 租户管理员角色(TenantAdmin):可在租户Namespace内创建/删除Deployment、Service、ConfigMap等资源,但无权操作集群级资源或其他租户Namespace。
- 租户开发者角色(TenantDeveloper):仅能查看和更新已有工作负载,不能创建或删除Namespace。
- 租户只读角色(TenantViewer):仅具备Namespace内资源的get/list/watch权限。
注意:Helm安装Release时,Tiller(或Helm 3的SDK)使用当前kubeconfig的权限。若租户管理员通过Helm部署Chart,必须确保其ServiceAccount具备在目标Namespace创建资源的权限,且不能越权修改集群级ClusterRole。
3.4 RBAC绑定与Helm模板化
以下是一个典型的租户RBAC模板片段,在Helm Chart中通过tenantId动态生成:
# templates/rbac.yaml
{{- range .Values.tenants }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ .name }}-admin
namespace: {{ .namespace }}
rules:
- apiGroups: [""]
resources: ["pods", "services", "configmaps", "secrets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["apps"]
resources: ["deployments", "statefulsets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ .name }}-admin-binding
namespace: {{ .namespace }}
subjects:
- kind: ServiceAccount
name: {{ .name }}-sa
namespace: {{ .namespace }}
roleRef:
kind: Role
name: {{ .name }}-admin
apiGroup: rbac.authorization.k8s.io
{{- end }}
关键设计:每个租户的ServiceAccount、Role、RoleBinding全部限定在租户专属Namespace内,不创建任何ClusterRole/ClusterRoleBinding。这确保了即使某个租户的凭证泄露,攻击者也无法影响其他租户或集群全局资源。
3.5 租户边界设计清单
在Helm接入多集群拓扑前,请逐项确认以下设计要点:
| 检查项 | 描述 | Helm集成方式 |
|---|---|---|
| Namespace分配 | 每个租户至少一个专属Namespace | values.yaml中定义tenants[].namespace |
| ResourceQuota | 限制CPU/内存/PVC数量 | 模板中根据tenantId生成Quota对象 |
| NetworkPolicy | 默认拒绝跨Namespace流量 | 模板中生成隔离策略,允许监控出口 |
| ServiceAccount | 每个租户独立SA,不共享 | 模板中创建{{ .name }}-sa |
| Role/RoleBinding | 仅限Namespace内权限,无ClusterRole | 模板中生成Role并绑定SA |
| 节点亲和性 | 可选:将租户绑定到专属节点池 | 模板中注入nodeSelector与tolerations |
| 存储隔离 | PVC命名前缀或独立StorageClass | 模板中拼接pvc-{{ .name }}-前缀 |
下一步准备:完成租户边界定义后,即可进入第4章“多集群拓扑与Helm Release映射”,将本章定义的租户模型映射到实际的多集群部署拓扑中。