Operator启动失败、Reconcile不触发、报cannot list resource或no matches for kind,根本原因是RBAC配置错误:role.yaml中apiGroups、resources、verbs未与代码实际调用对齐,或RoleBinding未正确关联ServiceAccount;须补全mydatabases/status和leases权限。

Operator 启动失败、Reconcile 不触发、日志里反复报 cannot list resource "mydatabases" 或 no matches for kind,基本都是 RBAC 没配对——不是代码问题,是 config/rbac/role.yaml 里漏了资源、动词,或没绑定到 ServiceAccount。
Role 和 ClusterRole 该选哪个?看 Operator 要操作的资源范围
Operator 的权限必须严格按它实际要访问的资源来定,不能“全集群开个 ClusterRole 就完事”:
- 如果只管理自己命名空间下的自定义资源(如
MyDatabase),用Role+RoleBinding,作用域清晰,最小权限原则落地更稳 - 如果要跨 namespace 查 Pod/Secret(比如做依赖检查),或操作 Node/ClusterRole 等集群级资源,必须用
ClusterRole+ClusterRoleBinding -
ClusterRole可以被RoleBinding绑定到某 namespace 内的 ServiceAccount,实现“集群级权限、命名空间级使用”,但仅限于非 namespace-scoped 资源(如nodes);对pods这类 namespace-scoped 资源,仍需显式指定namespace字段或改用Role
role.yaml 里 rules 怎么写才不漏?三个关键字段必须对齐
RBAC 规则不是“写个资源名就完事”,apiGroups、resources、verbs 必须和你代码里 client.List() / client.Get() 的实际调用完全一致:
-
apiGroups:CRD 的group字段值,比如database.example.com;内置资源如pods填""(空字符串),不是"core"或"v1" -
resources:必须用复数小写形式,"mydatabases"(不是"MyDatabase"或"mydatabase");如果还要操作它的 status 子资源,得额外加"mydatabases/status" -
verbs:至少包含"get"、"list"、"watch"(Reconcile 循环依赖 watch 事件触发);更新 status 需要"update",删除资源需要"delete"
示例(针对 CRD MyDatabase.v1alpha1.database.example.com):
立即学习“go语言免费学习笔记(深入)”;
rules: - apiGroups: ["database.example.com"] resources: ["mydatabases", "mydatabases/status"] verbs: ["get", "list", "watch", "update"] - apiGroups: [""] resources: ["pods", "services", "secrets"] verbs: ["get", "list", "watch", "create", "delete"]
ServiceAccount 和 RoleBinding 怎么关联?别漏 namespace 和 subject 名称
Operator Pod 用的是 ServiceAccount 身份,RBAC 绑定必须精确匹配它的名称和所在 namespace:
-
RoleBinding的metadata.namespace必须和 Operator Pod 所在的 namespace 一致(通常是default或你 deploy 时指定的) -
subjects下的name必须和Deployment中spec.template.spec.serviceAccountName完全相同(默认是default,但 kubebuildermake deploy生成的是controller-manager) - 检查是否生效:运行
kubectl auth can-i list mydatabases --as=system:serviceaccount:<ns>:<sa-name>,替换<ns>和<sa-name>后应返回yes
本地调试和集群部署权限不一致?根源在身份体系切换
本地 make run 用的是你的 kubeconfig 用户身份(如 minikube 或 kind admin),而集群里 Operator Pod 用的是 ServiceAccount token——两套身份,RBAC 规则互不影响:
- 本地跑通但集群 Forbidden,99% 是
config/rbac/role_binding.yaml没 apply,或ServiceAccount名字写错 - 用
kubectl get sa -n <ns>确认 SA 存在;再用kubectl describe sa <sa-name> -n <ns>看它是否挂载了正确的 secret - Operator 日志里出现
failed to acquire lease,往往是因为 leader election 的leases.coordination.k8s.io权限缺失,需在 rules 中补上:apiGroups: ["coordination.k8s.io"], resources: ["leases"], verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
RBAC 不是“一次配置永久有效”,每次新增 CRD 字段、加子资源、换 namespace 都得同步更新 role.yaml 和 binding —— 最容易被忽略的,是 status 子资源和 leader election 租约权限。


















