kubebuilder init 后项目跑不起来,因默认未启用 webhook 或配置 rbac,导致 manager.start 卡在 leader election,需先 make install 安装 crd、make deploy 配置 rbac 权限,并注意证书、resourceversion 冲突及 ownerreference 等细节。

为什么 kubebuilder init 后的项目跑不起来?
因为默认生成的项目没启用 Webhook 或没配置 RBAC,控制器启动时会卡在 manager.Start 等待 leader election 成功,但实际因权限不足反复失败,日志里看不到明显报错,只看到 failed to acquire lease 或 no matches for kind。
- 运行前必须先
make install:它会把 CRD 安装到集群,否则mgr.GetClient()查不到自定义资源 -
make deploy会生成 RBAC 清单,但如果你用kubectl apply -f config/手动部署,得确认config/rbac/role.yaml里包含对目标 CR 的get/list/watch权限,漏掉watch就不会触发 Reconcile - 本地调试用
make run ENABLE_WEBHOOKS=false,避免证书问题干扰;Webhook 开启后必须先make cert-manager和make deploy,否则 admission server 启动失败
Reconcile 函数里怎么安全读写自定义资源?
别直接用 client.Get 拿到对象后就改字段再 Update——并发 Reconcile 下大概率触发 resourceVersion conflict 错误。Kubernetes 要求乐观锁校验,而 Update 不自动重试。
- 优先用
client.Patch+client.MergeFrom,只提交变更字段,天然避开 resourceVersion 冲突 - 如果必须全量更新,用
client.Get→ 修改 →client.Update,但得包一层retry.RetryOnConflict,否则第一次失败就退出 - 永远检查
err != nil后立刻return ctrl.Result{}, err,不要忽略 client 错误;特别是IsNotFound(err)要特殊处理,避免误删或无限重试 - CR 的 Status 字段更新必须走
status.SubResource().Update(),否则 APIServer 会拒绝
如何让 Operator 响应 ConfigMap 或 Secret 变更?
Operator 默认只监听自己管理的 CR,要关联外部资源,得显式声明 Owns 关系,并确保 OwnerReference 正确设置,否则垃圾回收或事件触发都会失效。
- 在
SetupWithManager里调用mgr.GetCache().IndexField为 ConfigMap 建索引(比如按 label),再用Watches注册自定义 EventHandler - 更简单的方式:在 Reconcile 中用
client.List查 ConfigMap,然后比对ObjectMeta.ResourceVersion判断是否变化;但注意别漏掉初始状态,首次 Reconcile 必须加载 - 如果 ConfigMap 是由 Operator 自己创建的,用
controllerutil.SetControllerReference设置 OwnerReference,这样删除 CR 时 ConfigMap 会自动级联删除 - 别在 Reconcile 里直接修改外部资源的 Spec —— 它们不属于你的 CR 范围,APIServer 可能拒绝,且违反 operator 设计原则
本地调试时 make run 报 x509: certificate signed by unknown authority
这是 kubebuilder 自动生成的 webhook 证书没被集群信任,但本地开发通常不需要真启用 webhook,强行开启只会增加调试负担。
- 最省事:启动时加
ENABLE_WEBHOOKS=false,即make run ENABLE_WEBHOOKS=false - 如果必须测试 webhook,别用
make cert-manager(它依赖 cert-manager CRD),改用make certs生成本地证书,再手动把config/webhook/certificate.yaml应用进去 - 证书路径默认是
/tmp/k8s-webhook-server/serving-certs,确保该目录存在且可读;若用kind集群,记得挂载该路径进容器 - Webhook 配置里的
caBundle必须和证书的 CA 一致,kubebuilder v3.12+ 会自动注入,老版本需手动cat config/webhook/certs/ca.crt | base64 -w 0替换
真正难的不是写完 Reconcile,而是搞清哪个 resourceVersion 没对上、哪条 OwnerReference 漏了、或者哪次 Patch 没带正确类型选项——这些细节不出现在文档里,只藏在 controller-runtime 的 error message 里。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











