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 循环模式。每个租户经历以下阶段:

  1. 创建(Pending → Active):校验 Spec 合法性 → 创建命名空间 → 创建 ResourceQuota → 创建 NetworkPolicy → 创建 RBAC 绑定 → 更新状态为 Active。
  2. 更新(Active → Active):检测 Spec 变更 → 增量更新配额、网络策略、管理员列表 → 保留已有命名空间。
  3. 暂停(Active → Suspended):设置所有命名空间 quota.hard 为 0 → 停止调度新 Pod → 保留元数据。
  4. 恢复(Suspended → Active):恢复原始配额 → 重新允许调度。
  5. 删除(Active/Suspended → Terminating → 删除):设置 Finalizer → 清理命名空间 → 清理 RBAC → 移除 Finalizer → 删除 CR。
最佳实践: 删除操作必须使用 Finalizer 确保子资源完全清理;暂停操作不删除命名空间,仅冻结配额,避免数据丢失。

4.3 租户状态机

租户状态机定义了明确的转换规则,确保控制器行为可预测。下图展示了完整的状态转换关系:

租户状态机转换图 租户状态机转换图 Pending Active Suspended Terminating 创建成功 暂停 恢复 删除 删除 清理完成 状态转换规则: • 只有 Active 和 Suspended 状态可以进入 Terminating • 创建失败时 Pending 状态保留,控制器持续重试

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 循环按以下步骤执行,确保状态机正确推进:

  1. 获取 Tenant 对象:从 Informer 缓存读取,若不存在则跳过。
  2. 检查 DeletionTimestamp:若非零,进入 Terminating 分支,执行清理逻辑。
  3. 校验 Spec:检查必填字段、命名空间前缀合法性、配额格式。
  4. 创建/更新子资源:遍历 environments,为每个环境创建或更新 Namespace、ResourceQuota、NetworkPolicy、RoleBinding。
  5. 更新 Status:根据子资源就绪情况设置 phase 和 conditions。
  6. 重新入队:若子资源未就绪,设置 RequeueAfter 为 10 秒,等待下一次 Reconcile。
性能优化: 使用 batch 包批量创建命名空间,减少 API Server 压力;对于大规模集群(1000+ 租户),建议使用 workqueue 的速率限制器。

4.6 租户资源关系图

下图展示了 Tenant CRD 与 Kubernetes 原生资源之间的映射关系,帮助理解租户资源的实际落地方式:

租户资源映射关系图 Tenant CRD → 原生资源映射 Tenant CR (alpha) spec.namespacePrefix spec.quota spec.networkPolicy Namespace 列表 ResourceQuota NetworkPolicy 控制器将 Tenant CR 的 Spec 字段转换为多个原生 Kubernetes 资源,并在 Status 中记录映射结果。

通过上述 CRD 设计与控制器实现,租户资源具备了完整的声明式生命周期管理能力,为后续的隔离策略、配额管理和测试验证奠定了坚实基础。