Kubebuilder v4 用 kubebuilder init 和 create api 可快速生成 Operator 骨架,但需严格匹配 go≥1.24.6、kubectl≥1.11.3、docker≥17.03,且 PROJECT 文件、注释(如 +kubebuilder:object:root=true)与环境三者必须对齐,否则 make run 报 “no matches for kind”。

用 kubebuilder init 和 kubebuilder create api 两条命令就能生成可运行的 Operator 骨架,不需要手写 CRD YAML、Scheme 注册、Manager 初始化或 Reconcile 循环框架——但前提是环境、PROJECT 文件、注释三者全部对齐,漏一个就卡在 make run 报 “no matches for kind”。
环境版本必须严格匹配,不是“够新就行”
Kubebuilder v4(当前主流)不是向下兼容的玩具,它对底层工具链有硬性依赖:
-
go ≥ 1.24.6:低于此版本会导致make generate失败,原因是泛型约束或embed包支持不全,错误常表现为undefined: fs.FS或cannot use ~T -
kubectl ≥ 1.11.3:旧版无法识别 v1 CRD 的spec.conversion等字段,make install会静默跳过 CRD 安装,后续make run查不到资源定义 -
docker ≥ 17.03:make docker-build依赖其构建 manager 镜像;Mac 上用 Colima 或 Rancher Desktop 时需确认docker version输出真实有效,别被 alias 欺骗
验证方式不是看“有没有”,而是跑一次:kubebuilder version && go version && kubectl version --client && docker version --format '{{.Server.Version}}'。
PROJECT 文件是运行时配置源,不是只读文档
执行 kubebuilder init --domain example.com --repo example.com/myop 后生成的 PROJECT 文件,直接控制后续所有命令行为:
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
立即学习“go语言免费学习笔记(深入)”;
-
layout: ["go.kubebuilder.io/v4"]表示启用 kustomize/v2 插件,make deploy就走 kustomize 流程;若手动改成v3,make manifests会报错找不到插件 -
resources:下为空才允许kubebuilder create api;已有条目时再执行会报resource already exists,必须先删PROJECT里对应项,再删api/和controllers/下文件,最后make generate - 改
domain或repo后,go.mod和所有import路径(比如example.com/myop/api/v1alpha1)必须同步更新,否则make build报cannot find module
CRD 生成靠注释,不是靠 struct 字段自动推导
make manifests 的本质是调用 controller-gen 解析 Go 文件里的 // +kubebuilder:* 注释,不是反射 struct:
-
// +kubebuilder:object:root=true必须加在顶层 struct 上(如MyApp),否则不会生成 CRD 的kind和plural -
// +kubebuilder:subresource:status必须加在同一 struct 上,否则r.Status().Update()会返回404 Not Found - 字段级注释如
// +kubebuilder:validation:Required或// +kubebuilder:default:=1写错位置(比如加在 private 字段上)会导致 CRD YAML 缺失对应 validation 规则,kubectl apply 不报错但校验不生效 - 不要手动改
config/crd/bases/下的 YAML——它每次make manifests都会被覆盖;所有定义逻辑只写在api/v1alpha1/xxx_types.go里
Reconcile 入口已生成,但业务逻辑必须自己填,且不能忽略删除路径
kubebuilder create api 生成的 controllers/xxx_controller.go 里,Reconcile 函数只是占位符,关键逻辑要手写:
- 第一件事是检查
myCR.DeletionTimestamp != nil,不处理这个,CR 删除后关联的 Deployment/Service 就会残留(除非你显式设了orphan) - 创建子资源时,必须调用
ctrl.SetControllerReference(&myCR, &dep, r.Scheme),否则 Kubernetes 不知道该不该级联删除;漏掉这行,kubectl delete mycr xxx后 Deployment 还在 - 更新
Status字段要用r.Status().Update(ctx, &myCR),不能用普通r.Update(),否则报the server does not allow this method on the requested resource - 本地调试用
make run,它默认以 cluster-admin 权限连接 kube-apiserver;上线前务必用make manifests+make install验证 RBAC 是否覆盖所有用到的资源(特别是configmaps、secrets这类易漏项)
最容易被忽略的是:PROJECT 文件改完、注释加完、Reconcile 写完之后,必须按顺序跑 make generate && make manifests && make install ——少一步,make run 就可能连 CRD 都没注册进集群。

















