1. CRD 基础概念:CustomResourceDefinition 的定义、作用与生命周期

CustomResourceDefinition(CRD)是 Kubernetes 内置的一种 API 资源,它允许用户在不修改核心 Kubernetes 源码的前提下,向集群声明新的自定义资源类型。CRD 是 Operator 模式的基石——没有 CRD,Operator 就失去了它所管理的“物”。理解 CRD 的定义、作用与生命周期,是掌握 Operator 控制面蓝图的第一步。

1.1 什么是 CRD?

CRD 本质上是一个资源类型的元描述。当你创建一个 CRD 对象时,你实际上是在告诉 Kubernetes API Server:“请注册一个新的 RESTful 资源路径,并按照我定义的 schema 来验证和存储该资源的数据。” 从此,用户可以通过 kubectl 或 API 调用来创建、读取、更新、删除该自定义资源的实例(即 Custom Resource,CR)。

概念 类比 Kubernetes 中的角色
CRD 数据库中的表结构定义(DDL) 声明一种新的资源类型及其验证规则
CR(Custom Resource) 表中的一行记录 该资源类型的一个具体实例
API Server 数据库引擎 提供 REST 端点、存储、认证与校验
关键认知: CRD 本身是一个 Kubernetes 资源(属于 apiextensions.k8s.io/v1 API 组),而它定义出来的自定义资源则属于你指定的 group/version。两者处于不同的 API 层级。

1.2 CRD 的核心作用

CRD 在 Operator 生态中承担三个不可替代的作用:

  1. 扩展 API 面:将领域对象(如数据库集群、消息队列、监控告警规则)映射为 Kubernetes 原生的 API 资源,使它们可以被 kubectl、RBAC、审计日志等统一管理。
  2. 声明式配置入口:用户通过 YAML 声明期望状态,Operator 通过控制器循环不断调和实际状态,CRD 就是这份“期望状态”的载体。
  3. 版本化演进:CRD 支持多个 API 版本共存(如 v1alpha1、v1beta1、v1),允许资源 schema 在不中断现有用户的情况下逐步成熟。
CRD 在 Operator 架构中的核心位置 CRD 在 Operator 架构中的核心位置 用户 (kubectl / 客户端) CRD (CustomResourceDefinition) 声明资源类型、Schema、版本、作用域 CR (Custom Resource 实例) 用户定义的期望状态(spec) Operator 控制器 (Controller / Reconciler) 监听 CR 事件 → 调和实际状态 → 更新 status 被管理资源 (Deployment/Service/ConfigMap)

1.3 CRD 的生命周期

一个 CRD 从创建到最终被清理,经历以下四个阶段:

阶段 触发动作 关键行为 注意事项
1. 注册 kubectl apply -f crd.yaml API Server 注册新的 REST 路径,生成 OpenAPI schema 同名 CRD 不可重复注册;spec.names.singular 必须唯一
2. 版本发布 更新 CRD 的 spec.versions 字段 新增/废弃/升级 API 版本;可设置 storage 版本与 served 版本 废弃版本需通过 deprecated 标记,不能直接删除
3. 实例管理 用户创建/更新/删除 CR CR 数据按 CRD schema 校验后存入 etcd;Operator 监听并调和 删除 CRD 前必须先清理所有 CR 实例,否则会残留孤儿对象
4. 注销与清理 kubectl delete crd <name> API Server 移除 REST 路径;如果存在 Finalizer 则阻塞删除 Finalizer 机制是安全清理的关键,也是本课程后续重点

1.4 CRD 定义的关键字段

一个典型的 CRD YAML 包含以下核心结构:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: mongodbs.example.com          # 必须格式:<plural>.<group>
spec:
  group: example.com                   # API 组
  names:
    plural: mongodbs                   # 复数名,用于 URL 路径
    singular: mongodb                  # 单数名
    kind: MongoDB                      # 资源类型名,用于 YAML 的 kind 字段
    shortNames:                        # 简写,可选
      - mdb
  scope: Namespaced                    # 作用域:Namespaced 或 Cluster
  versions:
    - name: v1alpha1                   # 版本名
      served: true                     # 是否对外提供该版本 API
      storage: true                    # 是否将该版本数据持久化到 etcd
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                replicas:
                  type: integer
                version:
                  type: string
      subresources:
        status: {}                     # 启用 /status 子资源
      additionalPrinterColumns:        # kubectl 额外输出列
        - name: Replicas
          type: integer
          jsonPath: .spec.replicas
  conversion:
    strategy: None                     # 版本转换策略:None 或 Webhook
设计要点:
  • scope:Namespaced 资源受命名空间隔离,适合多租户场景;Cluster 资源全局唯一,适合集群级配置。
  • storage:只能有一个版本标记为 storage: true,该版本决定 etcd 中实际存储的数据结构。
  • subresources.status:启用后,Operator 可以独立更新 status 而不触发 spec 的调和循环。

1.5 CRD 与 Operator 的关系

CRD 和 Operator 是“契约”与“执行者”的关系:

  • CRD 定义契约:规定用户能写什么(spec)、系统能报什么(status)、资源如何被分类(group/version/kind)。
  • Operator 履行契约:监听 CR 的增删改事件,读取 spec,创建/更新/删除下层 Kubernetes 资源,并将运行状态写回 status。

没有 CRD,Operator 就失去了与用户交互的标准化接口;没有 Operator,CRD 只是一堆躺在 etcd 中的静态 JSON 数据。两者共同构成了 Kubernetes 声明式自动化的闭环。

CRD 与 Operator 的契约关系 CRD 与 Operator 的契约关系 CRD(契约) 定义 spec / status / 版本 Operator(执行者) 调和循环 / 资源编排 用户通过 CR 实例传递期望 → Operator 负责实现
常见陷阱: 初学者容易混淆 CRD 与 CR。CRD 是“资源类型的定义”,全局只有一个;CR 是“资源实例”,可以有成千上万个。删除 CRD 会级联删除所有 CR 实例(除非有 Finalizer 拦截),务必在生产环境中谨慎操作。

1.6 小结

CRD 是 Kubernetes 扩展性的核心机制,它让平台能够理解并管理任意领域对象。作为 Operator 开发者,你需要:

  • 精确设计 CRD 的 group/version/kind 命名空间,避免与现有资源冲突。
  • 合理规划 版本演进策略,利用 served 和 storage 字段实现平滑升级。
  • 深刻理解 CRD 的 生命周期,特别是删除阶段 Finalizer 的作用——这是下一章将要深入的主题。