Kubernetes 自定义资源、自定义资源定义 (CRD) 与控制器

发布: (2026年1月18日 GMT+8 12:34)
6 min read
原文: Dev.to

Source: Dev.to

SHARON SHAJI

Kubernetes 并不是因为 Pods 或 Services 而强大。
它之所以强大,是因为可以 在不修改 Kubernetes 本身的情况下进行扩展

这种可扩展性来源于 Custom Resources(自定义资源)+ CRDs(自定义资源定义)+ Controllers(控制器)

如果你没有真正理解这三者,你其实并没有在 使用 Kubernetes——你只是在部署 YAML。

为什么会有 CRD

Kubernetes 解决 通用基础设施问题

  • 调度
  • 网络
  • 存储
  • 扩容

但真实的公司面临 特定领域的问题

  • “部署模型”
  • “提供数据库”
  • “创建服务网格规则”
  • “管理证书”

与其把这些硬编码进 Kubernetes,Kubernetes 为我们提供了一种 定义自定义 API 的方式。

框架

组件用途
CRD定义新的 API 类型
Custom Resource该 API 的实例
Controller实现业务逻辑的控制器

心智模型(重要)

Kubernetes 本身对你的 CRD 什么也不做——它只会存储它们。
如果你创建了一个 没有控制器 的 CRD,Kubernetes 会欣然接受它,但 什么也不做。这不是 bug;这是设计如此。

什么是自定义资源 (CR)?

自定义资源 是 Kubernetes 中的 新对象类型,就像:

  • Pod
  • Service
  • Deployment

您可以创建自己的,例如:

  • Database
  • Application
  • MLModel
  • Certificate
  • Gateway

示例

kubectl get databases
kubectl apply -f myapp.yaml

Kubernetes 并不关心 Database 的含义。

什么是 CRD(CustomResourceDefinition)?

A CRD 在 Kubernetes 中定义了一个新的 API 架构。可以把它理解为:

“嘿,Kubernetes,这里有一种新对象。请把它存储下来。”

CRD 指定了:

  • API 组
  • 版本
  • Kind
  • Schema(验证)

简单 CRD 示例

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: databases.mycompany.io
spec:
  group: mycompany.io
  scope: Namespaced
  names:
    plural: databases
    singular: database
    kind: Database
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                engine:
                  type: string
                version:
                  type: string
                storage:
                  type: string

应用此 CRD 后:

kubectl get databases

Kubernetes 现在 Database 识别为有效对象 — 仅此而已。

创建自定义资源 (CR)

apiVersion: mycompany.io/v1
kind: Database
metadata:
  name: user-db
spec:
  engine: postgres
  version: "15"
  storage: 20Gi

Apply it:

kubectl apply -f database.yaml

Result:

  • 存储在 etcd 中
  • 未创建 Pod
  • 未启动数据库

这正是大多数初学者感到困惑的地方。

为什么控制器是必需的

A Controller is the brain. It:

  • 监视自定义资源
  • 比较 期望状态实际状态
  • 调和差异

没有控制器时:

  • CRD = 死的模式
  • CR = 无用的 YAML

控制器调和循环

Every controller follows this loop:

Observe → Compare → Act → Repeat

In code terms:

while True:
    desired_state = cr.spec
    actual_state = cluster_reality
    if desired_state != actual_state:
        fix_it()

此循环 永不停止

CRD + 控制器如何协同工作

User
  |
  | kubectl apply
  v
Kubernetes API Server
  |
  v
etcd (stores CR)
  |
  v
Controller watches CR
  |
  v
Controller creates / updates:
  - Pods
  - Services
  - PVCs
  - ConfigMaps

真实示例:数据库操作器

自定义资源

apiVersion: mycompany.io/v1
kind: Database
metadata:
  name: user-db
spec:
  engine: postgres
  version: "15"
  storage: 20Gi

控制器逻辑

IF Database CR is created:
  - Create StatefulSet
  - Create PVC
  - Create Service

IF Database CR is deleted:
  - Cleanup resources

Kubernetes 并不了解数据库。你的控制器了解。

期望状态 vs 实际状态

Desired State (CR):
  Database:
    engine: postgres
    replicas: 1

Actual State (Cluster):
  StatefulSet: missing

Controller Action:
  Create StatefulSet

如果有人手动删除 StatefulSet,控制器会重新创建它。

CRDs 与 Deployments 对比

功能部署CRD
内置
包含控制器仅当你编写时
逻辑位置Kubernetes
描述Deployment 只是一种 CRD + 由 Kubernetes 提供的控制器

Istio 使用 CRD

Istio 通过以下 CRD 扩展 Kubernetes:

  • VirtualService
  • DestinationRule
  • Gateway

示例

kind: VirtualService
spec:
  hosts:
    - myapp
  http:
    - ...

Istio CRDs Diagram

route:
  - destination:
      host: myapp-v2

Istio 控制器将其转换为

  • Envoy 配置
  • 流量路由
  • 负载均衡

注意: Istio 并不修改 Kubernetes。它 正确地对其进行扩展

为什么公司使用 CRD 构建产品

CRD 允许:

  • Kubernetes 原生 API
  • 声明式行为
  • kubectl 为先的用户体验
  • 强大的调和保证

被以下项目使用:

  • ArgoCD
  • Crossplane
  • Cert‑Manager
  • Prometheus Operator
  • Istio

全部遵循相同的模式。

常见错误

  • “CRD 自动创建资源”
  • 在 YAML 中编写逻辑
  • 忽略 .status 字段
  • 将 CRD 当作配置文件

CRD 是 API,而不是配置。

何时应使用 CRDs?

使用 CRDs 的情况:

  • 您管理的是生命周期,而不仅仅是部署
  • 您需要进行 reconciliation(调和)
  • 您正在构建平台

不应使用 CRDs 的情况:

  • 静态配置
  • 一次性任务
  • 简单值

最终要点

  • CRDs 定义 WHAT 你想要的
  • Controllers 定义 HOW 它的实现方式
  • Kubernetes 强制执行循环

如果你理解了这些,你就已经超越 YAML 理解了 Kubernetes。

Back to Blog

相关文章

阅读更多 »

Rapg:基于 TUI 的密钥管理器

我们都有这种经历。你加入一个新项目,首先听到的就是:“在 Slack 的置顶消息里查找 .env 文件”。或者你有多个 .env …

技术是赋能者,而非救世主

为什么思考的清晰度比你使用的工具更重要。Technology 常被视为一种魔法开关——只要打开,它就能让一切改善。新的 software,...

踏入 agentic coding

使用 Copilot Agent 的经验 我主要使用 GitHub Copilot 进行 inline edits 和 PR reviews,让我的大脑完成大部分思考。最近我决定 t...