3. 多租户模型设计:租户隔离策略与资源配额管理
在多租户 Kubernetes 集群中,租户隔离是保障安全性与稳定性的核心。本章围绕 Namespace、RBAC、NetworkPolicy 三大隔离支柱,结合资源配额管理,构建一套可落地、可审计的多租户模型。该模型与 Argo CD 的 ApplicationSet 及 Project 配置深度绑定,实现“声明式租户定义”。
3.1 租户隔离的三层模型
我们将租户隔离拆解为三个逻辑层,每一层解决不同维度的隔离问题:
| 隔离层 | 核心机制 | 隔离目标 | Argo CD 关联 |
|---|---|---|---|
| 工作负载隔离 | Namespace | Pod、Service、ConfigMap 等资源命名空间隔离 | Application 的 destination.namespace |
| 权限隔离 | RBAC (Role / RoleBinding) | 租户管理员/开发者/只读用户的细粒度访问控制 | Argo CD Project 的 sourceNamespaces 与 role 绑定 |
| 网络隔离 | NetworkPolicy | Pod 间、Namespace 间、外部流量访问控制 | Application 中作为资源清单同步 |
3.2 Namespace 策略:租户边界定义
每个租户对应一个或多个 Namespace。我们采用 “一租户一主 Namespace + 可选子 Namespace” 的扁平化结构,避免过深的层级嵌套导致管理复杂度上升。
- 命名规范:
<tenant-name>-<env>,例如fintech-prod、fintech-staging。 - 标签注入: 强制为每个 Namespace 打上
tenant: <tenant-name>和environment: <env>标签,用于后续 NetworkPolicy 和 ResourceQuota 的选择器匹配。 - 生命周期: 通过 Argo CD ApplicationSet 的
generators自动创建 Namespace,避免手动 kubectl 操作。
apiVersion: v1
kind: Namespace
metadata:
name: fintech-prod
labels:
tenant: fintech
environment: prod
managed-by: argocd
3.3 RBAC 权限隔离:最小权限原则
RBAC 配置分为两个维度:集群维度(ClusterRole / ClusterRoleBinding)和 命名空间维度(Role / RoleBinding)。对于多租户场景,我们优先使用命名空间维度的 Role,避免跨租户权限泄露。
典型租户角色定义:
| 角色 | 权限范围 | 典型操作 |
|---|---|---|
| 租户管理员 | Namespace 内所有资源 | 创建/删除 Deployment、Service、ConfigMap、Secret |
| 租户开发者 | Namespace 内工作负载资源 | 更新 Deployment、查看 Pod 日志、滚动升级 |
| 租户只读者 | Namespace 内查看权限 | get/list/watch Pod、Service、Event |
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: fintech-prod
name: tenant-developer
rules:
- apiGroups: ["apps", "extensions"]
resources: ["deployments", "statefulsets"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["pods", "pods/log", "services"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: fintech-prod
name: fintech-developer-binding
subjects:
- kind: User
name: "alice@fintech.com"
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: tenant-developer
apiGroup: rbac.authorization.k8s.io
3.4 NetworkPolicy 网络隔离:默认拒绝 + 显式放行
Kubernetes 默认的“全通”网络模型在多租户环境下是安全风险。我们采用 “默认拒绝所有入站/出站流量,仅显式放行业务所需流量” 的策略。
以下是一个典型租户的 NetworkPolicy 配置,实现三层隔离:
- 隔离层 1: 拒绝所有非本 Namespace 的入站流量。
- 隔离层 2: 允许同 Namespace 内所有 Pod 通信。
- 隔离层 3: 显式放行来自监控系统(如 Prometheus)和 Ingress Controller 的流量。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: fintech-prod
spec:
podSelector: {}
policyTypes:
- Ingress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-same-namespace
namespace: fintech-prod
spec:
podSelector: {}
ingress:
- from:
- namespaceSelector:
matchLabels:
tenant: fintech
environment: prod
policyTypes:
- Ingress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-monitoring
namespace: fintech-prod
spec:
podSelector:
matchLabels:
app: web
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoring
podSelector:
matchLabels:
app: prometheus
ports:
- port: 8080
protocol: TCP
policyTypes:
- Ingress
3.5 资源配额管理:防止“吵闹邻居”
资源配额(ResourceQuota)和限制范围(LimitRange)是防止单个租户耗尽集群资源的最后防线。我们为每个租户的 Namespace 设置以下配额:
| 配额类型 | 示例值 | 说明 |
|---|---|---|
| requests.cpu | 8 | CPU 请求总量上限(单位:核) |
| requests.memory | 16Gi | 内存请求总量上限 |
| limits.cpu | 16 | CPU 限制总量上限 |
| limits.memory | 32Gi | 内存限制总量上限 |
| count/deployments.apps | 20 | Deployment 数量上限 |
| count/services | 30 | Service 数量上限 |
| count/secrets | 50 | Secret 数量上限 |
apiVersion: v1
kind: ResourceQuota
metadata:
name: tenant-quota
namespace: fintech-prod
spec:
hard:
requests.cpu: "8"
requests.memory: "16Gi"
limits.cpu: "16"
limits.memory: "32Gi"
count/deployments.apps: "20"
count/services: "30"
count/secrets: "50"
---
apiVersion: v1
kind: LimitRange
metadata:
name: tenant-limits
namespace: fintech-prod
spec:
limits:
- max:
cpu: "4"
memory: "8Gi"
min:
cpu: "100m"
memory: "128Mi"
default:
cpu: "500m"
memory: "1Gi"
defaultRequest:
cpu: "200m"
memory: "512Mi"
type: Container
3.6 多租户隔离架构总览
下图展示了单个租户(fintech)在集群内的完整隔离架构,包含 Namespace 边界、RBAC 角色绑定、NetworkPolicy 规则以及 ResourceQuota 的协同工作关系。
3.7 租户配置的 GitOps 化
所有上述隔离策略(Namespace、RBAC、NetworkPolicy、ResourceQuota)都应作为 Kubernetes 清单存储在 Git 仓库中,并通过 Argo CD ApplicationSet 自动同步到目标集群。每个租户对应一个独立的 Application,其 spec.source.path 指向租户专属的配置目录。
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: tenant-applications
spec:
generators:
- list:
elements:
- tenant: fintech
env: prod
- tenant: fintech
env: staging
- tenant: retail
env: prod
template:
metadata:
name: '{{tenant}}-{{env}}'
spec:
project: default
source:
repoURL: https://git.company.com/tenants/{{tenant}}.git
targetRevision: main
path: '{{env}}/overlays'
destination:
server: https://kubernetes.default.svc
namespace: '{{tenant}}-{{env}}'
syncPolicy:
automated:
prune: true
selfHeal: true
overlays/base 目录中,作为所有环境的公共配置;将 NetworkPolicy 放在 overlays/{{env}} 中,按环境差异化调整。RBAC 的 Role 和 RoleBinding 建议与租户的团队 Git 仓库绑定,通过 CI/CD 流水线自动生成。