3. CRD 基础概念:CustomResourceDefinition 定义、版本管理与作用域

CustomResourceDefinition(CRD)是 Kubernetes 扩展 API 的核心机制,也是 Serverless 平台控制面定义资源模型的基石。通过 CRD,平台开发者可以声明式地定义新的资源类型(如 Function、Trigger、Build),Kubernetes API Server 会自动生成对应的 RESTful 端点、存储 schema 和校验逻辑。本节将深入剖析 CRD 的定义结构、版本管理策略以及作用域选择。

3.1 CRD 定义结构

一个 CRD 对象本身是一个 Kubernetes 资源,其 spec 字段描述了要注册的自定义资源的元数据、Schema 和访问方式。以下是一个典型的 CRD 定义示例:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: functions.serverless.example.com
spec:
  group: serverless.example.com
  names:
    kind: Function
    listKind: FunctionList
    plural: functions
    singular: function
    shortNames:
      - fn
  scope: Namespaced
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                runtime:
                  type: string
                handler:
                  type: string
                replicas:
                  type: integer
                  minimum: 0
关键字段说明:
  • group:API 组,用于逻辑隔离,通常使用域名格式。
  • names:定义资源的 kind、单复数形式及短名称,影响 kubectl 的使用方式。
  • scope:决定资源是 Namespaced 还是 Cluster 级别。
  • versions:声明支持的版本列表,每个版本可独立定义 schema。
  • openAPIV3Schema:基于 OpenAPI v3 的校验规则,控制资源字段的类型、格式和约束。

3.2 CRD 版本管理

Kubernetes CRD 支持多版本共存,允许平台在演进过程中平滑升级资源模型。版本管理涉及三个核心概念:served、storage 和 conversion。

概念 说明 典型场景
served 该版本是否可通过 API 读写。设为 true 表示客户端可以访问该版本。 旧版本保留 served: true 以兼容存量客户端。
storage 该版本是否作为持久化存储版本。整个 CRD 只能有一个 storage 版本。 新版本稳定后,将 storage 切换到新版本,旧版本仅用于读取。
conversion 不同版本间的数据转换策略。支持 None 或 Webhook。 字段重命名或结构调整时,通过 Webhook 实现无损转换。
最佳实践:在 Serverless 平台中,建议始终保留至少两个 served 版本(如 v1 和 v1beta1),并在 v1 稳定后将 storage 标记为 v1。使用 Conversion Webhook 处理字段变更,避免数据迁移风险。
CRD 版本管理生命周期 v1alpha1 served: true v1beta1 served: true v1 (storage) served: true Conversion Webhook 负责 v1beta1 ↔ v1 之间的字段映射 旧版本 served: true 保证客户端兼容,新版本 storage: true 保证数据一致性 存储版本切换流程 1. 创建 CRD 时指定 v1alpha1 为 storage 版本 2. 添加 v1beta1 版本,通过 Webhook 实现数据转换 3. 稳定后标记 v1 为 storage,移除旧版本 served 标志

3.3 CRD 作用域:Namespaced vs Cluster

CRD 的 scope 字段决定了自定义资源实例的隔离范围。选择合适的作用域直接影响 Serverless 平台的多租户模型和资源管理方式。

作用域 资源实例归属 API 路径 适用场景
Namespaced 属于某个命名空间,命名空间之间完全隔离 /apis/<group>/<version>/namespaces/<ns>/<plural> 函数、触发器、构建任务等租户级资源
Cluster 属于整个集群,不绑定命名空间 /apis/<group>/<version>/<plural> 集群级配置、存储类、全局策略、平台设置
作用域选择陷阱:
  • Namespaced 资源无法跨命名空间访问,若平台需要全局唯一的资源标识(如函数名全局唯一),需额外设计命名规范或使用 Cluster 作用域。
  • Cluster 作用域的资源实例名称必须全局唯一,且 RBAC 权限模型不同,需要谨慎设计访问控制。
  • 一旦 CRD 创建后,scope 不可修改。必须在设计阶段确定作用域。
Namespaced vs Cluster 作用域对比 Namespaced 作用域 Namespace: ns1 Function: fn-a Namespace: ns2 Function: fn-a 同名资源可在不同命名空间共存 API 路径包含命名空间 RBAC 可细化到命名空间级别 适合多租户隔离场景 Cluster 作用域 ClusterScopedConfig: global-settings 资源名称全局唯一 API 路径不包含命名空间 RBAC 需要 ClusterRole/ClusterRoleBinding 适合全局配置、存储类、策略

3.4 作用域选择策略

在 Serverless 平台控制面设计中,作用域的选择应遵循以下策略:

  1. 租户资源使用 Namespaced:函数、触发器、构建、事件源等资源属于特定租户,使用 Namespaced 作用域天然支持多租户隔离。
  2. 平台配置使用 Cluster:全局存储类、运行时镜像映射、配额策略等跨租户共享的配置,使用 Cluster 作用域。
  3. 混合模式:部分资源(如函数模板)可能需要同时支持 Namespaced 和 Cluster 两种作用域,此时可设计两个独立的 CRD 或通过 RBAC 模拟。
Serverless 平台典型 CRD 作用域分配:
资源类型 推荐作用域 理由
Function Namespaced 每个租户独立管理函数,命名空间隔离
Trigger Namespaced 触发器绑定到特定命名空间的函数
Build Namespaced 构建任务属于租户,且可能涉及敏感信息
RuntimeConfig Cluster 运行时版本映射全局生效
StorageClass Cluster 存储类为集群级资源
FunctionTemplate Cluster 模板全局共享,租户通过引用使用

通过合理选择 CRD 作用域,Serverless 平台控制面可以在多租户隔离、资源管理和 API 设计之间取得平衡,为上层业务提供清晰、可扩展的资源模型基础。