2. Kubernetes 原生多租户模型:Namespace、RBAC、NetworkPolicy、ResourceQuota、LimitRange
Kubernetes 本身并未提供“租户”这一高层抽象,但通过组合五个原生资源,可以构建出逻辑隔离的多租户环境。这五个资源分别从命名空间隔离、权限控制、网络隔离、资源配额、资源限制五个维度实现租户间的安全与资源边界。理解它们的协作关系,是设计多租户集群模板蓝图的基础。
2.1 五层隔离模型总览
下表总结了每个原生资源在隔离模型中的角色、作用范围以及典型配置项:
| 资源名称 | 隔离维度 | 作用范围 | 核心配置项 |
|---|---|---|---|
| Namespace | 命名空间隔离 | 集群级 | 名称、标签、注解 |
| RBAC | 权限控制 | 集群/命名空间 | Role、ClusterRole、RoleBinding、ClusterRoleBinding |
| NetworkPolicy | 网络隔离 | 命名空间 | podSelector、ingress、egress、policyTypes |
| ResourceQuota | 资源配额 | 命名空间 | requests.cpu、requests.memory、limits.cpu、limits.memory、count/pods |
| LimitRange | 资源限制 | 命名空间 | default、defaultRequest、max、min、maxLimitRequestRatio |
2.2 五层隔离协作关系图
下图展示了在一个多租户集群中,五个原生资源如何围绕 Namespace 形成隔离边界:
2.3 各资源深度解析
2.3.1 Namespace:隔离的第一道边界
Namespace 是 Kubernetes 中用于将集群资源划分为逻辑分组的虚拟集群。每个 Namespace 内的资源名称必须唯一,但不同 Namespace 之间可以重名。在多租户场景中,通常为每个租户创建一个独立的 Namespace。
- 创建命令:
kubectl create namespace tenant-a - 查看资源:
kubectl get pods -n tenant-a - 注意事项: 默认情况下,不同 Namespace 之间的 Pod 可以互相通信(通过 Service 名称),因此必须配合 NetworkPolicy 实现网络隔离。
2.3.2 RBAC:权限隔离
RBAC(基于角色的访问控制)通过定义角色(Role/ClusterRole)和绑定(RoleBinding/ClusterRoleBinding)来控制用户或服务账户对资源的操作权限。
- Role: 作用于特定 Namespace,定义该 Namespace 内的权限。
- ClusterRole: 作用于整个集群,可用于定义集群级别的资源权限(如 Node、PV)。
- RoleBinding: 将 Role 绑定到用户/组/服务账户,限定在特定 Namespace 内生效。
- ClusterRoleBinding: 将 ClusterRole 绑定到用户/组/服务账户,在整个集群生效。
2.3.3 NetworkPolicy:网络隔离
NetworkPolicy 通过标签选择器定义 Pod 之间以及 Pod 与外部之间的网络通信规则。默认情况下,Kubernetes 允许所有 Pod 之间的通信;一旦在 Namespace 中应用了 NetworkPolicy,未显式允许的流量将被拒绝。
- 入站规则(Ingress): 控制哪些来源可以访问目标 Pod。
- 出站规则(Egress): 控制目标 Pod 可以访问哪些目的地。
- 策略类型: 必须显式设置
policyTypes字段,否则默认只处理 Ingress。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: tenant-a
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
2.3.4 ResourceQuota:资源配额
ResourceQuota 用于限制 Namespace 内所有 Pod 的资源使用总量,防止单个租户过度消耗集群资源。可以限制 CPU、内存、存储以及对象数量(如 Pod、Service、PVC 的数量)。
apiVersion: v1
kind: ResourceQuota
metadata:
name: tenant-quota
namespace: tenant-a
spec:
hard:
requests.cpu: "4"
requests.memory: "8Gi"
limits.cpu: "8"
limits.memory: "16Gi"
pods: "20"
services: "10"
persistentvolumeclaims: "5"
2.3.5 LimitRange:资源限制
LimitRange 在 Namespace 级别为 Pod 或容器设置默认的资源请求/限制值,以及最小/最大值。它确保每个 Pod 都设置了资源约束,避免因未设置资源请求而导致调度失败或资源争抢。
apiVersion: v1
kind: LimitRange
metadata:
name: tenant-limits
namespace: tenant-a
spec:
limits:
- max:
cpu: "2"
memory: "4Gi"
min:
cpu: "100m"
memory: "128Mi"
default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "200m"
memory: "256Mi"
type: Container
2.4 五层隔离的依赖关系
下图展示了五个资源之间的依赖与协作流程:
2.5 常见配置陷阱与避坑指南
| 陷阱场景 | 问题描述 | 解决方案 |
|---|---|---|
| 未设置 LimitRange | Pod 未设置资源请求,ResourceQuota 拒绝调度 | 为每个 Namespace 配置 LimitRange,设置 defaultRequest |
| NetworkPolicy 未设置 policyTypes | 默认只处理 Ingress,Egress 未限制 | 显式设置 policyTypes: [Ingress, Egress] |
| RBAC 使用 ClusterRoleBinding | 租户获得跨 Namespace 的权限 | 使用 RoleBinding 限定在租户 Namespace 内 |
| ResourceQuota 与 LimitRange 冲突 | LimitRange 的 max 大于 Quota 的 hard | 确保 LimitRange 的 max ≤ Quota 的 hard / Pod 数量 |