Operator 运行需 CRD、RBAC、控制器三者严格对齐;常见失败点为权限缺失、CRD 未生效、OwnerReference 绑定失败;CRD 是“语言基础”,须先安装并验证为 Established 状态;RBAC 需最小化但必须包含子资源操作及 update ownerReferences 权限;make deploy 易因镜像问题静默失败,需优先检查 Pod 状态与 Events;连通性验证首选 kubectl get myapps -A 返回空列表。

Operator 不是“部署完就跑起来”的黑盒程序,它依赖 CRD 安装、RBAC 权限、控制器运行时三者严格对齐;本地 make run 成功不等于集群可运行,常见失败点集中在权限缺失、CRD 未生效、OwnerReference 绑定失败这三类。
CRD 必须先安装,且不能跳过 make install
CRD 是 Operator 的“语言基础”——没它,Kubernetes 根本不认识你定义的资源类型,kubectl apply -f myapp.yaml 会直接报错 error: unable to recognize "myapp.yaml": no matches for kind "MyApp" in version "apps.example.com/v1"。
实操建议:
-
make install本质是执行kubectl apply -f config/crd/bases/,它把 Go 类型里定义的字段(靠//+kubebuilder:*注释驱动)生成并推送到集群;别手动改config/crd/bases/下的 YAML,下次make manifests会覆盖掉 - 安装后必须验证:运行
kubectl get crd | grep myapp,看到状态为Established才算就绪;如果卡在Pending,大概率是 Kubernetes 版本太低(sigs.k8s.io/controller-runtimev0.17+ 要求 K8s ≥ 1.25) - 多版本 CRD(如
v1alpha1→v1)升级时,仅make install不够,必须配 conversion webhook,否则老对象无法读取
RBAC 权限要最小化,但 controller 必须能操作子资源
Operator 在集群中运行时,是以 ServiceAccount 身份调用 API 的。权限不足会导致 Reconcile 函数反复失败,日志里频繁出现 forbidden: User "system:serviceaccount:default:myapp-operator" cannot get resource "deployments" in API group "" in the namespace "myns" 这类错误。
立即学习“go语言免费学习笔记(深入)”;
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
实操建议:
- 权限不是越宽越好:
make manifests自动生成的config/rbac/role.yaml默认只给MyApp本身读写权限,你必须手动补全对 Deployment、Service、Secret 等子资源的权限(比如加- apiGroups: [""]和resources: ["deployments", "services"]) - 特别注意
ownerReferences依赖的权限:controller 需要update对象的metadata.ownerReferences字段,所以verbs列表里必须含update,光有create和get不够 - 本地调试(
make run)走的是 kubeconfig 文件,权限由当前用户决定;集群部署时则完全依赖 RBAC 清单,二者权限模型不同,别混淆
make deploy 启动的是 Pod,但容易因镜像拉取失败静默退出
make deploy 会构建镜像、推送到 registry、生成 Deployment 并 apply。看似一键,实际最常卡在镜像环节:Pod 处于 ImagePullBackOff 或 ErrImagePull,describe 看不到明显报错,Reconcile 根本没机会执行。
实操建议:
- 默认 Makefile 用
IMG变量指定镜像地址,例如make deploy IMG=quay.io/myorg/myapp-operator:v0.1;若用本地 kind 集群,推荐改用kind load docker-image加载,避免推拉镜像网络问题 - 检查 Pod 日志前,先确认
kubectl get pod -n myapp-system是否 Running;如果不是,用kubectl describe pod -n myapp-system看 Events,90% 的问题是镜像不存在或 Secret 没配 registry 认证 - Controller 启动后,第一件事是 watch CR,所以
kubectl get myapps -A应该能立刻返回空列表(而非报错),这是最轻量的连通性验证
真正难调试的从来不是代码逻辑,而是 CRD 是否被识别、RBAC 是否漏了某个 verb、OwnerReference 的 UID 是否和实际 CR 实例一致——这三个点出问题,Reconcile 函数压根不会被调用,日志里一片空白,比 panic 更让人抓狂。

















