K8s Operator开发入门:从CRD到控制器跑通第一个实例

K8s Operator开发入门的核心路径并不复杂:先用 CRD 声明一个自定义资源,再写一个控制器监听它,把期望状态和实际状态对齐。
本文用 Kubebuilder 脚手架带你从零跑通一个最小 Operator,环境为 Kubebuilder 3.x 加 Kubernetes 1.24 以上集群,命令和路径都可直接复制执行。

前置准备:确认工具链和集群可用

开始前先确认本地已经具备以下条件,缺一个后面都可能报错:

  • Go 1.19 或更高版本,执行 go version 能看到输出。
  • 一个可用的 Kubernetes 集群,kubectl cluster-info 能返回 API Server 地址。
  • 本地有 kubectl 的 kubeconfig 权限,能创建 CRD 和 Deployment。
  • 安装 Kubebuilder,下载对应系统二进制后放到 /usr/local/bin,执行 kubebuilder version 验证。

如果只是学习,不想影响正式集群,可以先用 kind 或 minikube 起一个本地集群,避免误操作生产资源。

用 Kubebuilder 生成项目骨架

在空目录下执行初始化,项目名建议全小写,避免生成的文件名带大写字符:

mkdir -p ~/demo-operator && cd ~/demo-operator
kubebuilder init --domain example.local --repo github.com/yourname/demo-operator

接着生成 API 和控制器代码。
这里定义一个叫 App 的资源,组为 apps,版本为 v1:

kubebuilder create api --group apps --version v1 --kind App

执行过程中会询问是否创建 Resource 和 Controller,两个都选 y。
生成后目录结构大致是:api/v1/app_types.go 放 CRD 结构体,controllers/app_controller.go 放控制器逻辑,config/ 下是部署用的 YAML。

编写 CRD 字段和控制器逻辑

打开 api/v1/app_types.go,在 AppSpec 里加一个副本数字段,在 AppStatus 里加一个就绪副本字段:

type AppSpec struct {
    Replicas int32 `json:"replicas,omitempty"`
}

type AppStatus struct {
    ReadyReplicas int32 `json:"readyReplicas,omitempty"`
}

改完执行 make manifests 重新生成 CRD YAML。
控制器部分在 controllers/app_controller.go 的 Reconcile 方法里,核心是读取 App 对象,再创建或更新对应的 Deployment。
逻辑可以简化成三步:获取 App 实例、拼出期望的 Deployment、调用 CreateOrUpdate。
写完后用 make generate 和 make manifests 同步代码与配置。

本地运行与集群部署验证

调试阶段可以先把控制器跑在本地,直接连接集群:

make install
make run

另开一个终端提交一个最小实例:

apiVersion: apps.example.local/v1
kind: App
metadata:
  name: demo-app
spec:
  replicas: 2

保存为 demo.yaml 后执行 kubectl apply -f demo.yaml。
用 kubectl get app 能看到实例,用 kubectl get deploy 应该出现控制器创建的 Deployment。
如果本地调试没问题,再执行 make docker-build 和 make deploy 部署到集群。

常见报错和避坑要点

  • no matches for kind "App":CRD 还没 apply,先执行 make install。
  • 控制器不触发:检查 Reconcile 是否真的被调用,可以加日志打印 req.NamespacedName。
  • 权限不足:在 config/rbac/ 下确认 ClusterRole 是否包含 apps 资源的 get、list、watch、create、update 权限。
  • 修改结构体后忘记 make manifests:CRD 字段不会同步,提交时会报 unknown field。
  • 删除 App 时 Deployment 残留:需要在控制器里处理 DeletionTimestamp,或用 OwnerReference 做级联删除。

避坑重点是把 CRD 和控制器当成一对:CRD 决定能提交什么,控制器决定提交后发生什么,两边字段必须一致。

效果验证与下一步

验证是否成功,
可以看三个结果:kubectl get crd 里有 apps.example.local;kubectl get app demo-app 返回实例;kubectl get deploy 出现由控制器创建的 Deployment,
副本数与 spec 一致。

跑通这个最小闭环后,可以继续加 finalizer、事件记录和状态更新,把 Operator 从能跑推进到好用。
Operator 开发入门的门槛主要在理解控制器循环,而不是工具本身。

开发 Operator 必须用 Go 吗

不必须。
Kubebuilder 和 controller-runtime 生态以 Go 为主,但也可以用 Java 的 Java Operator SDK 或 Python 的 Kopf。
选 Go 的原因是社区示例多、调试链路短。

本地 make run 和集群里 make deploy 有什么区别

make run 是控制器进程跑在你本机,连的是 kubeconfig 指向的集群,适合调试;make deploy 会把控制器打包成镜像部署到集群,更接近生产形态。

CRD 字段改了为什么提交不生效

大概率是没重新生成 manifests。
改 _types.go 后要执行 make manifests,再 kubectl apply -f config/crd/bases/ 下的 CRD 文件。

Operator 和 Helm 应该选哪个

Helm 适合一次性渲染并提交一组静态资源,Operator 适合需要持续观察状态并自动纠偏的场景。
如果只是部署固定应用,Helm 更轻;
如果要处理备份、扩缩容、故障自愈这类动态逻辑,Operator 更合适。

分享到:
上一篇
服务器零日漏洞应急处理:从隔离到修复的完整操作流程
下一篇
Proxmox VE安装教程:从ISO到Web管理后台可用
1
系统公告

泽御云中秋国庆双节活动上线:新购8折,拼团3.99元起

尊敬的用户:
泽御云“月满中秋·礼贺国庆”双节活动现已开启,活动时间为2026年9月23日至10月10日。 活动期间可享以下福利:
1. 常规云服务器新购使用优惠码“泽御中秋国庆同乐”,符合条件的订单享8折优惠。
2. 香港精品云服务器5人拼团低至3.99元,部分4核4G套餐3人拼团年付388元,续费同价。
3. 新用户购买年付云服务器,符合活动规则可赠送2个月使用时长。
4. 老用户续费季度赠15天,续费年度赠2个月;活动期间升级配置免收配置迁移手续费。
5. 推荐好友成功下单,符合条件的推荐人可获赠7天服务器使用时长。
6. 活动期间享宕机补偿标准翻倍、简单网站迁移协助及技术工单优先处理权益。
温馨提示:优惠码不适用于拼团套餐、活动轻量产品、年付订单及续费订单;拼团套餐为独立特价活动,不与赠时类福利叠加。赠送时长不可折现、退款或跨账户转移,具体规则以活动页面说明为准。
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意