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 处理字段变更,避免数据迁移风险。
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不可修改。必须在设计阶段确定作用域。
3.4 作用域选择策略
在 Serverless 平台控制面设计中,作用域的选择应遵循以下策略:
- 租户资源使用 Namespaced:函数、触发器、构建、事件源等资源属于特定租户,使用 Namespaced 作用域天然支持多租户隔离。
- 平台配置使用 Cluster:全局存储类、运行时镜像映射、配额策略等跨租户共享的配置,使用 Cluster 作用域。
- 混合模式:部分资源(如函数模板)可能需要同时支持 Namespaced 和 Cluster 两种作用域,此时可设计两个独立的 CRD 或通过 RBAC 模拟。
Serverless 平台典型 CRD 作用域分配:
| 资源类型 | 推荐作用域 | 理由 |
|---|---|---|
| Function | Namespaced | 每个租户独立管理函数,命名空间隔离 |
| Trigger | Namespaced | 触发器绑定到特定命名空间的函数 |
| Build | Namespaced | 构建任务属于租户,且可能涉及敏感信息 |
| RuntimeConfig | Cluster | 运行时版本映射全局生效 |
| StorageClass | Cluster | 存储类为集群级资源 |
| FunctionTemplate | Cluster | 模板全局共享,租户通过引用使用 |
通过合理选择 CRD 作用域,Serverless 平台控制面可以在多租户隔离、资源管理和 API 设计之间取得平衡,为上层业务提供清晰、可扩展的资源模型基础。