4. 租户资源定义与 CRD 设计
在多租户集群中,租户是资源隔离与配额管理的核心抽象。Kubernetes 原生没有“租户”概念,因此需要通过自定义资源定义(Custom Resource Definition, CRD)将租户建模为一级资源。本节详细阐述 Tenant CRD 的字段设计、生命周期管理流程以及状态机转换规则。
4.1 Tenant CRD 字段设计
Tenant CRD 采用 Spec + Status 的标准 Kubernetes 资源结构。Spec 定义租户的期望状态,Status 反映实际运行状态。核心字段如下表所示:
| 字段路径 | 类型 | 必填 | 说明 |
|---|---|---|---|
spec.displayName |
string | 是 | 租户显示名称,用于 UI 展示 |
spec.namespacePrefix |
string | 是 | 命名空间前缀,自动生成 ns-{prefix}-{env} |
spec.environments |
[]string | 是 | 环境列表,如 ["dev","staging","prod"] |
spec.quota |
object | 是 | 资源配额,包含 CPU、内存、存储、Pod 数 |
spec.networkPolicy |
object | 否 | 网络策略模板,默认拒绝跨租户流量 |
spec.adminUsers |
[]string | 是 | 租户管理员列表,绑定 ClusterRole |
status.phase |
string | — | 当前阶段:Pending / Active / Suspended / Terminating |
status.conditions |
[]Condition | — | 详细状态条件,如配额就绪、网络就绪 |
status.namespaces |
[]string | — | 已创建的命名空间列表 |
设计要点: 使用
namespacePrefix 而非固定命名空间名,支持多环境自动生成命名空间;quota 字段直接映射到 ResourceQuota 对象,避免二次转换。
4.2 租户生命周期管理
租户生命周期由 Tenant Controller 驱动,采用 Reconcile 循环模式。每个租户经历以下阶段:
- 创建(Pending → Active):校验 Spec 合法性 → 创建命名空间 → 创建 ResourceQuota → 创建 NetworkPolicy → 创建 RBAC 绑定 → 更新状态为 Active。
- 更新(Active → Active):检测 Spec 变更 → 增量更新配额、网络策略、管理员列表 → 保留已有命名空间。
- 暂停(Active → Suspended):设置所有命名空间
quota.hard为 0 → 停止调度新 Pod → 保留元数据。 - 恢复(Suspended → Active):恢复原始配额 → 重新允许调度。
- 删除(Active/Suspended → Terminating → 删除):设置 Finalizer → 清理命名空间 → 清理 RBAC → 移除 Finalizer → 删除 CR。
最佳实践: 删除操作必须使用 Finalizer 确保子资源完全清理;暂停操作不删除命名空间,仅冻结配额,避免数据丢失。
4.3 租户状态机
租户状态机定义了明确的转换规则,确保控制器行为可预测。下图展示了完整的状态转换关系:
4.4 CRD 示例与控制器逻辑
以下是一个完整的 Tenant CR 实例,展示了 Spec 与 Status 的典型内容:
apiVersion: multi-tenancy.example.com/v1
kind: Tenant
metadata:
name: tenant-alpha
finalizers:
- multi-tenancy.example.com/cleanup
spec:
displayName: "Alpha Team"
namespacePrefix: "alpha"
environments:
- dev
- staging
- prod
quota:
cpu: "40"
memory: "80Gi"
pods: 200
storage: "500Gi"
networkPolicy:
defaultDeny: true
allowedCIDRs:
- "10.0.0.0/8"
adminUsers:
- "alice@example.com"
- "bob@example.com"
status:
phase: Active
conditions:
- type: NamespacesReady
status: "True"
lastTransitionTime: "2025-03-20T10:00:00Z"
- type: QuotaReady
status: "True"
lastTransitionTime: "2025-03-20T10:00:05Z"
- type: NetworkReady
status: "True"
lastTransitionTime: "2025-03-20T10:00:10Z"
namespaces:
- ns-alpha-dev
- ns-alpha-staging
- ns-alpha-prod
避坑指南:
- Finalizer 名称必须与控制器注册的名称完全一致,否则无法拦截删除操作。
- Status 中的
conditions应使用标准 Kubernetes Condition 类型,包含type、status、reason、message和lastTransitionTime。 - 配额字段建议使用 Kubernetes 资源量纲(如
"80Gi"),避免控制器做单位转换。
4.5 控制器 Reconcile 流程
Tenant Controller 的 Reconcile 循环按以下步骤执行,确保状态机正确推进:
- 获取 Tenant 对象:从 Informer 缓存读取,若不存在则跳过。
- 检查 DeletionTimestamp:若非零,进入 Terminating 分支,执行清理逻辑。
- 校验 Spec:检查必填字段、命名空间前缀合法性、配额格式。
- 创建/更新子资源:遍历 environments,为每个环境创建或更新 Namespace、ResourceQuota、NetworkPolicy、RoleBinding。
- 更新 Status:根据子资源就绪情况设置 phase 和 conditions。
- 重新入队:若子资源未就绪,设置 RequeueAfter 为 10 秒,等待下一次 Reconcile。
性能优化: 使用
batch 包批量创建命名空间,减少 API Server 压力;对于大规模集群(1000+ 租户),建议使用 workqueue 的速率限制器。
4.6 租户资源关系图
下图展示了 Tenant CRD 与 Kubernetes 原生资源之间的映射关系,帮助理解租户资源的实际落地方式:
通过上述 CRD 设计与控制器实现,租户资源具备了完整的声明式生命周期管理能力,为后续的隔离策略、配额管理和测试验证奠定了坚实基础。