导读:本期聚焦于BIT程序员创作的《Kubernetes 对象资源与自定义资源到底有什么区别?》,敬请观看详情。同样是操作 Kubernetes 集群,为什么有时只需要 Deployment 这类内置对象,有时又必须通过 CRD 创建自定义资源?这两类资源在存储机制、控制器行为和 API 设计上并不一样。内置对象由 kube-apiserver 和核心控制器直接管理,服务发现、调度、扩缩容等能力由系统组件统一实现。自定义资源则是用户通过 CustomResourceDefinition 向 API Server 注册的新类型,它只负责数据存储和 REST API 暴露,不包含业务逻辑,需要配合自定义控制器才能实现完整功能。理解这个边界,有助于在扩展 Kubernetes 时少走弯路。本文将围绕概念模型、声明式 API 机制、Controller 协作方式以及实际选型建议展开,让你能够判断什么时候用原生对象,什么时候该写 CRD。

Kubernetes 的核心能力建立在资源对象模型之上。用户通过 YAML 或 JSON 描述期望状态,API Server 将其持久化到 etcd,控制器持续调谐使实际状态向期望状态靠拢。内置对象资源(如 Pod、Service、Deployment)由 Kubernetes 核心组件直接识别和处理;自定义资源(Custom Resource,CR)则允许用户扩展 API。两者本质区别不在于是否存储在 etcd,而在于是否有系统级控制器自动响应变更。没有控制器监听的自定义资源,只是一份静态配置数据。我们先看几个核心概念。

Kubernetes 对象资源与自定义资源到底有什么区别?

资源对象的存储与 API 注册机制

内置资源对象在 Kubernetes 源码编译阶段就已经注册到 API Server 中。像 Pod、Node、Service 这些核心类型,它们的结构体定义、默认值逻辑、校验规则以及版本转换函数都直接写死在 kube-apiserver 的代码里。API Server 启动时会自动加载这些内置类型,并在 /api/v1、/apis/apps/v1 等路径下暴露对应的 RESTful 接口。内置资源的生命周期完全由 Kubernetes 核心团队维护,升级集群版本时,这些对象的 schema 变化会经过严格的兼容性评估。

自定义资源则完全不同。用户不需要修改任何 Kubernetes 源码,只需要向集群提交一个 CustomResourceDefinition(CRD)对象。API Server 监听到这个 CRD 之后,会动态注册一个全新的 API 组和版本,并在 etcd 中为新资源建立独立的存储映射。CRD 中定义的 OpenAPI schema 用于校验提交进来的自定义资源实例,但 API Server 不会干预这些资源实例的具体业务逻辑。换句话说,CRD 只是让集群“认识”了一种新的数据类型,它自己并不会“理解”这些数据应该怎么处理。

下面是一个典型的 CRD 定义示例,它向集群注册了一个 ipipp.com 组下的 App 资源:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: apps.ipipp.com
spec:
  group: ipipp.com
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                replicas:
                  type: integer
                image:
                  type: string
  scope: Namespaced
  names:
    plural: apps
    singular: app
    kind: App
    shortNames:
      - ap

这条 CRD 提交后,API Server 会立即创建 /apis/ipipp.com/v1/namespaces/{namespace}/apps 这样的访问路径。你可以用 kubectl get apps 查看资源列表,但前提是必须有对应的控制器去创建实际的资源实例,否则这个列表永远是空的。这也说明了存储机制与业务逻辑分离的关键特征。

控制器协同与调谐循环的差异

内置对象之所以能够自动完成扩缩容、自愈、服务发现等功能,是因为 kube-controller-manager 中运行着一批系统级控制器。每个控制器都针对特定的内置对象类型编写,例如 DeploymentController 监听 Deployment 对象的变更,然后创建或更新 ReplicaSet;ReplicaSetController 再进一步保证 Pod 副本数量达标。这套调谐循环是 Kubernetes 声明式 API 的核心引擎,用户不需要关心控制器如何工作,只需要声明期望状态即可。

自定义资源本身不会触发任何系统级控制器行为。如果你提交了一个 kind: App 的实例,并设置了 replicas: 3,API Server 只会把这个对象存储起来,不会去创建 3 个 Pod,也不会做任何健康检查或滚动更新。要让自定义资源真正“活”起来,必须自己编写一个自定义控制器。这个控制器通常使用 client-go 的 informer 机制监听自定义资源的增删改事件,然后在自己的调谐循环里执行业务逻辑,比如创建 Deployment、调用外部 API 或者更新状态字段。

以下是一个简化的 Go 控制器调谐逻辑片段,演示如何监听并处理自定义资源:

package main

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

func reconcileApp(ctx context.Context, client kubernetes.Interface, namespace string) error {
    // 获取命名空间下所有自定义资源实例
    apps, err := client.AppsV1().Apps(namespace).List(ctx, metav1.ListOptions{})
    if err != nil {
        return err
    }
    for _, app := range apps.Items {
        if app.Spec.Replicas > 0 {
            fmt.Printf("需要为 %s 创建 %d 个副本\n", app.Name, app.Spec.Replicas)
            // 这里可以调用 client.AppsV1().Deployments(...) 创建 Deployment
        }
    }
    return nil
}

这种设计与内置控制器形成了明显对比:内置对象的控制器复杂度对用户完全透明,而自定义控制器可以完全按照业务需求定制,但同时也意味着用户要自己处理并发、重试、状态更新、leader election 等问题。好在 Kubernetes 生态提供了 Kubebuilder、Operator SDK 等工具,可以大幅降低编写自定义控制器的门槛。

实际场景中的选择权衡

判断一个需求应该使用内置对象还是自定义资源,核心看两点:是否需要系统级控制器自动处理,以及是否需要独立的 API 生命周期管理。如果需求完全可以通过 Deployment、StatefulSet、Service 等原生对象组合实现,那就没有必要引入 CRD。例如运行一个无状态 Web 应用,Deployment 就能完成副本管理、滚动更新和回滚,强行编写 CRD 反而增加了维护负担。

但是当你的应用需要描述 Kubernetes 原生对象无法表达的状态时,自定义资源就变得非常合适。比如在数据库 Operator 中,你需要一个资源来描述数据库集群的拓扑、备份策略、故障切换行为,这些信息无法直接塞进 ConfigMap 或 Annotation 里。通过 CRD 定义一个 MySQLCluster 资源,可以让用户以声明式方式管理复杂的数据库生命周期,同时利用 Kubernetes 的 RBAC、审计和命名空间隔离能力。

还有一个常见误区是滥用 ConfigMap 或 Annotation 来存储结构化配置。ConfigMap 没有强类型校验,字段写错只能等到应用运行时才暴露问题;Annotation 虽然灵活但缺少版本管理和 API 文档支持。自定义资源通过 OpenAPI schema 提供字段级校验,通过版本转换支持平滑升级,这是普通配置存储无法替代的。因此,当你发现团队内部开始用大量 Annotation 来传递复杂业务语义时,通常就是考虑引入 CRD 的信号。

总的来说,内置对象资源解决的是 Kubernetes 平台级的通用问题,而自定义资源解决的是你的业务领域特有的扩展问题。两者在 Kubernetes 生态中各司其职,理解它们之间的边界,可以帮助你设计出更清晰、更可维护的云原生架构。

Kubernetes对象资源自定义资源CRD修改时间:2026-10-05 06:13:07

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