2. K8s多租户架构基础:命名空间、RBAC、资源配额与LimitRange
多租户是K8s性能优化的核心场景之一。本章从K8s原生的多租户隔离机制入手,解析命名空间、RBAC、资源配额(ResourceQuota)与LimitRange四大基础组件,为后续瓶颈分析奠定架构基础。
2.1 命名空间:逻辑隔离的第一层
命名空间(Namespace)是K8s实现多租户隔离的基本单元。它将集群内的资源划分为逻辑组,每个租户拥有独立的命名空间,实现资源命名隔离与访问边界。
| 特性 | 说明 |
|---|---|
| 资源命名隔离 | 同一命名空间内资源名称唯一,不同命名空间可重名 |
| 默认命名空间 | default、kube-system、kube-public、kube-node-lease |
| 资源归属 | Pod、Service、Deployment等资源必须属于某个命名空间 |
| 集群级资源 | Node、PV、ClusterRole等不属于任何命名空间 |
性能视角:命名空间本身不消耗计算资源,但大量命名空间(>1000)会加重API Server的缓存压力,建议按业务单元合理规划命名空间数量。
2.2 RBAC:细粒度权限控制
基于角色的访问控制(RBAC)通过角色(Role/ClusterRole)与绑定(RoleBinding/ClusterRoleBinding)实现权限管理。多租户场景下,RBAC确保租户只能操作自己命名空间内的资源。
RBAC核心对象
- Role:命名空间级别的权限集合,如对Pod的get/watch/list权限
- ClusterRole:集群级别的权限集合,如查看Node状态
- RoleBinding:将Role绑定到用户/组/ServiceAccount,作用域为命名空间
- ClusterRoleBinding:将ClusterRole绑定到主体,作用域为整个集群
# 示例:为租户A创建只读角色并绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: tenant-a
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: tenant-a
name: read-pods
subjects:
- kind: User
name: tenant-a-user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
常见误区:不要为所有租户绑定cluster-admin ClusterRole,这会导致租户越权操作集群级资源,引发安全与性能风险。
2.3 资源配额:硬性资源上限
ResourceQuota为命名空间设置资源使用上限,防止单个租户耗尽集群资源。它作用于Pod、Service、PVC等资源的数量与计算资源(CPU/内存)总和。
ResourceQuota配置示例
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"
| 配额字段 | 含义 | 典型值 |
|---|---|---|
| requests.cpu | 所有Pod CPU请求总和上限 | 4-16 core |
| requests.memory | 所有Pod内存请求总和上限 | 8-64 Gi |
| limits.cpu | 所有Pod CPU限制总和上限 | 8-32 core |
| limits.memory | 所有Pod内存限制总和上限 | 16-128 Gi |
| pods | 命名空间内最大Pod数量 | 20-100 |
性能优化要点:ResourceQuota的校验发生在API Server端,每次Pod创建都会触发配额检查。当命名空间内Pod数量较大(>5000)时,配额校验可能成为瓶颈,建议使用优先级类(PriorityClass)配合配额管理。
2.4 LimitRange:容器级别的资源约束
LimitRange在命名空间级别为容器设置默认资源请求/限制以及取值范围,确保每个容器都有合理的资源声明,避免单个容器过度占用。
LimitRange配置示例
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
| LimitRange字段 | 作用 | 性能影响 |
|---|---|---|
| max | 容器资源上限 | 防止单容器抢占过多资源 |
| min | 容器资源下限 | 保证容器有基础资源保障 |
| default | 未设置limits时的默认值 | 避免容器无限制导致OOM |
| defaultRequest | 未设置requests时的默认值 | 影响调度决策与资源分配 |
2.5 多租户架构关系图
下图展示了命名空间、RBAC、ResourceQuota与LimitRange在多租户场景下的协作关系:
2.6 多租户性能优化清单
基于上述基础组件,多租户性能优化的关键检查点如下:
- 配额合理性:ResourceQuota的requests与limits比例建议为1:2,避免过度承诺导致节点过载
- LimitRange默认值:为每个命名空间设置合理的default与defaultRequest,防止容器无资源声明
- RBAC最小权限:遵循最小权限原则,避免租户拥有集群级权限影响其他租户
- 命名空间数量:单个集群命名空间建议不超过500个,避免API Server缓存膨胀
- 配额校验性能:大量Pod并发创建时,配额校验可能成为瓶颈,建议使用准入控制器缓存
实战建议:在性能测试环境中,先为每个租户设置保守的ResourceQuota(如CPU 2核/内存4Gi),通过监控逐步调整至合理值。LimitRange的defaultRequest应参考实际业务容器的资源使用基线。
2.7 本章小结
命名空间、RBAC、ResourceQuota与LimitRange构成了K8s多租户架构的四大支柱。命名空间提供逻辑隔离边界,RBAC控制访问权限,ResourceQuota设定资源硬上限,LimitRange约束容器级别的资源声明。理解这四者的协作关系与性能影响,是后续进行瓶颈分析与优化调优的前提。