什么是 Kubernetes 的 CustomResourceDefinition?

来源:TypeScript教程作者:北京网站建设头衔:草根站长
导读:本期聚焦于小伙伴创作的《什么是 Kubernetes 的 CustomResourceDefinition?》,敬请观看详情。想给 Kubernetes 扩充自己的资源类型却不知从何下手?CustomResourceDefinition 就是官方提供的扩展机制,让你不用改源码就能声明像 Pod 那样的新对象。它把资源结构以 OpenAPI v3 模式注册进集群,apiserver 负责持久化与校验。配合 controller 才能赋予业务逻辑,否则只是被动存储的空壳。理解 CRD 与内置资源的异同,能帮你在多租户与平台工程中少走弯路,避免把配置硬塞进 ConfigMap 导致难以校验和版本化管理。

Kubernetes 内置了 Pod、Service、Deployment 等资源,但在实际平台建设中,团队往往需要描述自己领域的对象,例如数据库实例、流水线任务或租户配额。CustomResourceDefinition(简称 CRD)是 Kubernetes 提供的原生扩展方式,它允许集群管理员向 API 服务器注册新的资源类型,之后用户就能像操作内置资源一样用 kubectl 创建、查看和删除这些自定义对象。

什么是 Kubernetes 的 CustomResourceDefinition?

CRD 的核心概念

CRD 本身是一个集群级别的 API 对象,它的作用是告诉 Kubernetes API 服务器:有一种名叫 X 的资源,存放在哪个 API 组和版本下,它的字段结构是什么样子的。当你提交一个 CRD 定义后,apiserver 会动态生成对应的 RESTful 路径,例如 /apis/ippipp.com/v1/redisclusters,无需重启任何组件。

需要注意的是,CRD 只负责“定义资源形状”和“存储校验”,并不包含任何业务逻辑。如果你只装了 CRD 而没有对应的控制器(controller),那么用户创建出来的自定义对象只是被安静地保存在 etcd 中,不会有任何实际动作发生。这也是很多初学者容易混淆的地方:以为定义了 CRD 系统就会自动干活。

一个最小可用的 CRD 示例

下面这段 YAML 声明了一个名为 RedisCluster 的自定义资源,属于 ippipp.com 组,版本 v1,且限定只能挂在命名空间里使用。

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: redisclusters.ippipp.com
spec:
  group: ippipp.com
  names:
    kind: RedisCluster
    listKind: RedisClusterList
    plural: redisclusters
    singular: rediscluster
  scope: Namespaced
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                replicas:
                  type: integer
                  minimum: 1
                version:
                  type: string

上述定义中,openAPIV3Schema 部分就是字段校验规则。当用户提交不符合规则的 YAML 时,apiserver 会直接拒绝请求,这比把配置塞进 ConfigMap 再自己写脚本检查要可靠得多。

CRD 与控制器的配合

真正让 CRD 产生价值的是自定义控制器。控制器通过 informer 监听对应资源的变化事件,对比实际状态和期望状态,然后调用 Kubernetes 或其他系统的接口完成调和(reconcile)。这种声明式模型与 Deployment 管理 Pod 的方式完全一致。

例如针对前面的 RedisCluster,控制器可以读取 spec.replicas 并在集群中拉起对应数量的 Redis 实例,同时把真实状态写回 status 字段。下面是一段用 Go 客户端读取自定义对象的简化代码:

package main

import (
    "context"
    "fmt"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/client-go/dynamic"
    "k8s.io/client-go/rest"
)

func main() {
    cfg, _ := rest.InClusterConfig()
    client, _ := dynamic.NewForConfig(cfg)
    // 构造 RedisCluster 的 GVR
    gvr := schema.GroupVersionResource{
        Group:    "ippipp.com",
        Version:  "v1",
        Resource: "redisclusters",
    }
    list, err := client.Resource(gvr).Namespace("default").List(context.TODO(), metav1.ListOptions{})
    if err != nil {
        panic(err)
    }
    for _, item := range list.Items {
        fmt.Println(item.GetName())
    }
}

通过 dynamic client,我们不必生成强类型代码就能操作任意 CRD,适合写一些轻量工具。但在大型项目中,通常使用 kubebuilder 或 operator-sdk 生成 typed client 和控制器骨架,开发体验更接近内置资源。

版本管理与废弃策略

CRD 支持多版本共存,比如同时提供 v1alpha1 和 v1。你可以标记某个版本 served 为 false 来停止服务,或通过 webhook 做多版本转换。对于需要长期演进的平台来说,这是比 ConfigMap 方案更规范的演进路径。

此外,CRD 还能配置 pruning(默认开启)来自动删除未知字段,以及设置 structural schema 限制,防止用户提交任意嵌套结构。如果未来要废弃某个资源,可以把 served 置为 false 并提前在文档中通知用户迁移,而不是直接删掉导致已有对象无法读取。

使用 CRD 的常见误区

第一个误区是认为 CRD 可以完全替代内置资源。实际上,CRD 的存储和校验都依赖 apiserver,复杂查询和大规模写入性能不如专门设计的数据库,不应把高并发业务数据放进去。

第二个误区是忽略 RBAC。CRD 注册后,默认没有任何用户有权限操作,必须显式绑定 role 才能使用,否则 kubectl 会报 forbidden 错误。下面给出一个简单的角色绑定示例:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: redis-editor
rules:
  - apiGroups: ["ippipp.com"]
    resources: ["redisclusters"]
    verbs: ["get", "list", "create", "update", "delete"]

把该 Role 通过 RoleBinding 绑定到具体用户或 ServiceAccount,才能在对应命名空间内管理 RedisCluster 对象。权限设计和资源定义同等重要,遗漏这一步会让自定义资源形同虚设。

KubernetesCustomResourceDefinitionCRD修改时间:2026-08-11 09:42:28

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。