必须用 kubebuilder create api 生成 CRD 和类型定义,它自动创建 CRD YAML、含 Spec/Status 的 Go struct 及 Scheme 注册代码;需指定 --group、--version、--kind,保留关键注释,确保 CRD 正确 apply 并等待 READY,且 Scheme 注册完整无遗漏。

直接用 kubebuilder create api 生成,别手写 CRD YAML 或 Go struct —— 拼错 spec.group、漏掉 // +kubebuilder:subresource:status 注释、忘记注册 Scheme,都会导致后续 Reconcile 根本不触发或 manager 启动 panic。
用 kubebuilder create api 生成 CRD 和类型定义
这是唯一推荐的起点。运行命令后,它会同时生成三样东西:CRD YAML、Go struct(含 Spec/Status)、Scheme 注册代码。
- 必须指定
--group、--version、--kind,例如:kubebuilder create api --group cache --version v1alpha1 --kind RedisCluster - 生成的 Go 文件在
api/v1alpha1/rediscluster_types.go,里面自动带了metav1.TypeMeta和metav1.ObjectMeta嵌入 -
// +kubebuilder:object:root=true和// +kubebuilder:subresource:status注释必须保留,否则make manifests不会生成 status 子资源字段 - 不要手动改 struct 字段后再补注释——
controller-gen只认注释驱动的 schema 生成
make manifests 后检查生成的 CRD YAML
生成的 YAML 在 config/crd/bases/cache.example.com_redisclusters.yaml,关键字段必须正确,否则 kubectl apply 会静默失败或 API Server 返回 404。
-
metadata.name必须是格式,比如. redisclusters.cache.example.com -
spec.group要和kubebuilder init --domain的 domain 对齐,否则 client-go 找不到该 group - 如果 Spec 里用了嵌套
map[string]interface{}或[]interface{},确保schema.openAPIV3Schema下有x-kubernetes-preserve-unknown-fields: true,否则字段会被 API Server 静默丢弃 - 检查
spec.versions[0].name是不是v1alpha1(不是v1alpha1version这类拼写错误)
CRD 必须先 apply 到集群,Operator 才能启动成功
Operator 启动时会调 mgr.GetClient().Get() 尝试加载 CR 实例,如果 CRD 还没存在,会直接 panic 报 no matches for kind "RedisCluster" in version "cache.example.com/v1alpha1",而不是等你 later apply。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 执行
make install(它本质是kubectl apply -f config/crd/bases/),不是kubectl apply -f单个文件 - 确认
kubectl get crd redisclusters.cache.example.com返回 READY 状态,不是None - 如果用
kind本地调试,make install必须在make run之前;否则 manager.Start() 会卡住或崩溃退出 - CRD apply 后,要等几秒让 API Server 完成 discovery 缓存刷新,再启动 Operator
Scheme 注册漏掉任何一步,Reconcile 就拿不到对象
Controller runtime 不认识你的 CR 类型,r.Get(ctx, req.NamespacedName, &obj) 就会返回 no kind "RedisCluster" is registered,即使 CRD 已存在、YAML 也完全合法。
- 确保
main.go中调用了cachev1alpha1.AddToScheme(scheme)(生成器已写好,别删) - 必须显式调
clientgoscheme.AddToScheme(scheme)和apiextensionsv1.AddToScheme(scheme),否则连 CRD 自身都解析不了 - struct 必须实现
runtime.Object接口,即包含GetObjectKind()和DeepCopyObject()方法 ——kubebuilder create api已自动生成,别手动改签名 - 如果用了 Finalizer 或自定义 subresource,还要加
ctrl.SetFields或额外 Scheme 注册,但基础 CR 不需要
最容易被忽略的是:CRD YAML 正确、make install 成功、kubectl get crd 显示 READY,但 Operator 仍不触发 Reconcile —— 大概率是 Scheme 注册顺序错或漏了 clientgoscheme.AddToScheme。这时候日志里不会报 CRD 相关错误,只会安静地跳过整个资源类型。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










