ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Kubebuilder Scope 完全指南:Manager Scope 与 CRD Scope 的独立配置、实战迁移与 RBAC 联动

Kubebuilder Scope 完全指南:Manager Scope 与 CRD Scope 的独立配置、实战迁移与 RBAC 联动 开发者工具代码生成CLI云原生后端【免费下载链接】kubebuilderKubebuilder - SDK for building Kubernetes APIs using CRDs项目地址https://gitcode.com/gh_mirrors/ku/kubebuilder点击查看免费下载Kubebuilder 的 scope作用域概念决定了 Operator 中控制器与自定义资源在 Kubernetes 集群内的可见性和操作边界。本指南以 scopes.md 为核心骨架系统梳理 Manager Scope管理器监视哪些命名空间与 CRD Scope自定义资源是命名空间级还是集群级这两套彼此独立的配置体系并结合 Kubebuilder 源码pkg/plugins/golang/v4与仓库自带测试项目testdata/project-v4-with-plugins给出可复制的命令、标记marker、cmd/main.go缓存配置和迁移步骤。读完本文你将能够为 Operator 精确设计谁在哪个命名空间里管理什么资源的权限与可见性模型。什么是 Scope在 Kubernetes 中scope定义了资源或控制器在集群中的运行边界集群级Cluster-scoped跨越整个集群运行可以访问所有命名空间中的资源例如 Node、ClusterRole、Namespace 这类全局资源。命名空间级Namespace-scoped被限制在特定命名空间内用于隔离和安全加固例如 Deployment、Service、ConfigMap。在 Kubebuilder 中构建 Operator 时你会同时接触到两个相互独立的作用域概念它们是本指南的核心Manager Scopemanager-scope.md决定 manager即运行 controller 的进程监视并操作哪些命名空间。它通过 Deployment 的 RBAC 资源和缓存cache配置来设定。CRD Scopecrd-scope.md决定你的自定义资源是命名空间专属还是集群全局。它在 CRD manifest 的spec.scope字段中配置。两者可以自由组合。例如最常见的一种模式集群级 manager 命名空间级 CRD——manager 可以在集群范围内调度但 CRD 实例仍按命名空间隔离。Manager Scope管理器监视哪些命名空间Kubebuilder 支持三种 manager scopeScope描述适用场景集群级默认监视集群中所有命名空间单个 manager 在集群范围内管理资源命名空间级只监视特定命名空间多租户、最小权限部署多命名空间监视多个指定命名空间manager 管理一组命名空间中的资源Manager scope 由三处配置共同决定RBAC 资源使用Role命名空间级还是ClusterRole集群级cmd/main.go中的缓存配置通过cache.Options.DefaultNamespaces限定 informer 监视的命名空间WATCH_NAMESPACE环境变量运行时指定要监视的命名空间列表。集群级默认默认情况下kubebuilder init脚手架生成的是集群级 manager监视集群中所有命名空间kubebuilder init --domain example.com特征RBAC 使用ClusterRole和ClusterRoleBindingmanager 监视所有命名空间无需任何缓存配置。适用场景整个集群只有一个 manager 实例需要管理集群级资源Nodes、ClusterRoles、Namespaces可以接受集群级权限、希望简化 RBAC 模型。命名空间级命名空间级 manager 只监视特定命名空间通过WATCH_NAMESPACE环境变量指定# 新项目直接以命名空间级模式初始化 kubebuilder init --domain example.com --namespaced # 已有项目切换为命名空间级 kubebuilder edit --namespacedtrue特征RBAC 使用命名空间级Role和RoleBindingmanager 只监视指定的命名空间需要在cmd/main.go中配置缓存控制器 RBAC 标记必须带namespace参数。RBAC 标记命名空间级项目中的控制器RBAC 标记需要携带namespace参数controller-gen 据此生成命名空间级Role// kubebuilder:rbac:groupsmyapp.example.com,namespacemyproject-system,resourcesmykinds,verbsget;list;watch;create;update;patch;delete // kubebuilder:rbac:groupsmyapp.example.com,namespacemyproject-system,resourcesmykinds/status,verbsget;update;patch // kubebuilder:rbac:groupsmyapp.example.com,namespacemyproject-system,resourcesmykinds/finalizers,verbsupdate当 controller-gen 检测到namespace参数时会生成kind: Role而不是kind: ClusterRole。Role的namespace字段不写死在源文件中而是在构建时由 kustomize 填充配置在config/default/kustomization.yaml的namespace:字段。缓存配置使用--namespaced标志初始化时Kubebuilder 会在cmd/main.go中自动脚手架出缓存配置。仓库测试项目 testdata/project-v4-with-plugins/cmd/main.go 中就有完整的实际实现// setupCacheNamespaces configures the cache to watch specific namespace(s). // It supports both single namespace (ns1) and multi-namespace (ns1,ns2,ns3) formats. func setupCacheNamespaces(namespaces string) cache.Options { defaultNamespaces : make(map[string]cache.Config) for ns : range strings.SplitSeq(namespaces, ,) { defaultNamespaces[strings.TrimSpace(ns)] cache.Config{} } return cache.Options{ DefaultNamespaces: defaultNamespaces, } } // In main() watchNamespace, err : getWatchNamespace() if err ! nil { setupLog.Error(err, Unable to get WATCH_NAMESPACE) os.Exit(1) } mgrOptions : ctrl.Options{ Scheme: scheme, Metrics: metricsServerOptions, WebhookServer: webhookServer, HealthProbeBindAddress: probeAddr, LeaderElection: enableLeaderElection, LeaderElectionID: your-leader-election-id, } // Configure cache to watch namespace(s) specified in WATCH_NAMESPACE mgrOptions.Cache setupCacheNamespaces(watchNamespace) setupLog.Info(Watching namespace(s), namespaces, watchNamespace) mgr, err : ctrl.NewManager(ctrl.GetConfigOrDie(), mgrOptions)配套的getWatchNamespace函数从WATCH_NAMESPACE环境变量读取监视范围未设置时直接报错退出// getWatchNamespace returns the namespace(s) the manager should watch for changes. func getWatchNamespace() (string, error) { watchNamespaceEnvVar : WATCH_NAMESPACE ns, found : os.LookupEnv(watchNamespaceEnvVar) if !found { return , fmt.Errorf(%s must be set, watchNamespaceEnvVar) } return ns, nil }这段配置对单个命名空间WATCH_NAMESPACEmy-namespace和多命名空间WATCH_NAMESPACEns1,ns2,ns3都适用无需条件分支。多命名空间manager 可以通过WATCH_NAMESPACE中的逗号分隔值同时监视多个命名空间# 部署 manager 监视多个命名空间 export WATCH_NAMESPACEnamespace1,namespace2,namespace3 kubectl apply -f dist/install.yaml特征需要在每个被监视的命名空间中创建Role和RoleBinding复用同一个setupCacheNamespaces辅助函数与单命名空间模式的代码完全相同KISS 原则无需任何条件逻辑。--namespaced标志在源码中的体现kubebuilder create api的--namespaced标志在 pkg/plugins/golang/v4/api.go 中定义默认值为true即 API 资源默认是命名空间级的fs.BoolVar(p.options.Namespaced, namespaced, true, Resource is namespaced by default; use --namespacedfalse to create a cluster-scoped resource)kubebuilder edit的--namespaced标志在 pkg/plugins/golang/v4/edit.go 中定义负责在集群级与命名空间级之间切换部署模式fs.BoolVar(p.namespaced, namespaced, false, Enable or disable namespace-scoped deployment (default: cluster-scoped); use --namespacedfalse to disable)实际切换逻辑在 pkg/plugins/golang/v4/scaffolds/edit.go 中当namespaced开启且此前是集群级时脚手架生成Role/RoleBinding并注入WATCH_NAMESPACE环境变量反向切换时则回退到ClusterRole/ClusterRoleBinding。CRD Scope自定义资源是命名空间级还是集群级CRD scope 决定了自定义资源的可见性与可用范围Scope描述示例资源命名空间级默认资源存在于特定命名空间内Deployment、Service、ConfigMap、Pod集群级资源在整个集群中全局可用Node、ClusterRole、Namespace、PersistentVolumeCRD scope 与 manager scope相互独立CRD 的scope字段决定资源可见性而 manager 的缓存配置决定 manager 监视哪些命名空间。命名空间级 CRD默认Kubebuilder 默认创建命名空间级 CRDkubebuilder create api --group cache --version v1alpha1 --kind Memcached生成的 CRD manifestapiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: memcacheds.cache.example.com spec: scope: Namespaced # Default group: cache.example.com names: kind: Memcached plural: memcacheds versions: - name: v1alpha1 # ...自定义资源在特定命名空间中创建kubectl apply -f memcached.yaml -n my-namespace kubectl get memcacheds -n my-namespace适用场景资源与特定应用、团队或租户绑定多租户环境需要隔离绝大多数应用级资源。注意事项测试新 CRD 版本需要完善的版本化与转换策略转换 webhook 必须考虑命名空间作用域便于在特定命名空间内做受控发布。集群级 CRD集群级 CRD 创建的资源在整个集群内全局可见。创建 API 时使用--namespacedfalse标志kubebuilder create api --group infrastructure --version v1 --kind Database --namespacedfalse生成的 CRD manifestapiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: databases.infrastructure.example.com spec: scope: Cluster # Cluster-scoped group: infrastructure.example.com names: kind: Database plural: databases versions: - name: v1 # ...自定义资源集群级可见无需命名空间kubectl apply -f database.yaml kubectl get databases # No namespace needed适用场景集群全局资源基础设施、配置需要从所有命名空间访问的资源管理集群级关注点的资源。典型示例基础设施配置云厂商设置、集群 DNS全局策略或配额跨命名空间的资源聚合。修改 CRD Scopekubebuilder:resource:scope标记API 创建完成后可以通过kubebuilder:resource:scope标记修改 CRD 的作用域。改为集群级//kubebuilder:object:roottrue //kubebuilder:subresource:status //kubebuilder:resource:scopeCluster // Database is the Schema for the databases API type Database struct { metav1.TypeMeta json:,inline metav1.ObjectMeta json:metadata,omitempty Spec DatabaseSpec json:spec,omitempty Status DatabaseStatus json:status,omitempty }改为命名空间级//kubebuilder:object:roottrue //kubebuilder:subresource:status //kubebuilder:resource:scopeNamespaced // Memcached is the Schema for the memcacheds API type Memcached struct { metav1.TypeMeta json:,inline metav1.ObjectMeta json:metadata,omitempty Spec MemcachedSpec json:spec,omitempty Status MemcachedStatus json:status,omitempty }修改标记后重新生成 manifestmake manifests⚠️ 作用域变更是破坏性操作将 CRD 从 Namespaced 改为 Cluster或反向属于 breaking change——已有的自定义资源将全部失效用户必须手动迁移资源。建议在首次开发阶段、尚未有任何生产使用时再修改 scope否则应创建带不同版本号的新 CRD。RBAC 与 Scope 的联动规则CRD scope 直接决定控制器对该资源所需 RBAC 的粒度。命名空间级 CRD监视命名空间级 CRD 的控制器使用命名空间级 RBAC//kubebuilder:rbac:groupscache.example.com,resourcesmemcacheds,verbsget;list;watch;create;update;patch;delete //kubebuilder:rbac:groupscache.example.com,resourcesmemcacheds/status,verbsget;update;patch //kubebuilder:rbac:groupscache.example.com,resourcesmemcacheds/finalizers,verbsupdate集群级 manager 下生成的是ClusterRoleapiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: manager-role rules: - apiGroups: [cache.example.com] resources: [memcacheds] verbs: [get, list, watch, create, update, patch, delete]命名空间级 manager 下RBAC 标记带namespace生成的是RoleapiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: manager-role namespace: manager-namespace rules: - apiGroups: [cache.example.com] resources: [memcacheds] verbs: [get, list, watch, create, update, patch, delete]集群级 CRD监视集群级 CRD 的控制器必须使用集群级 RBAC//kubebuilder:rbac:groupsinfrastructure.example.com,resourcesdatabases,verbsget;list;watch;create;update;patch;delete //kubebuilder:rbac:groupsinfrastructure.example.com,resourcesdatabases/status,verbsget;update;patch //kubebuilder:rbac:groupsinfrastructure.example.com,resourcesdatabases/finalizers,verbsupdate无论 manager 自身作用域如何集群级 CRD 生成的始终是ClusterRole。核心结论即使 manager 是命名空间级的只监视一个命名空间只要它管理集群级 CRD就仍然需要针对这些资源的ClusterRole权限。Manager scope 与 CRD scope 相互独立Manager scope由缓存配置控制监视哪些命名空间CRD scope由 CRD 的scope字段控制资源可见性。版本转换与 Webhook 的作用域考量对于多版本命名空间级 CRD转换 webhook 必须正确处理任意命名空间中的资源转换//kubebuilder:webhook:path/convert,mutatingfalse,failurePolicyfail,groupscache.example.com,resourcesmemcacheds,verbscreate;update,versionsv1;v1beta1,namecmemcached.kb.io,sideEffectsNone,admissionReviewVersionsv1完整的多版本转换实现可参考多版本教程以及仓库中的转换示例 testdata/project-v4/api/v1/firstmate_conversion.go。实战迁移将已有项目改为命名空间级 Manager默认的 Kubebuilder 项目是集群级 manager。以下是将已有集群级项目迁移为命名空间级部署的完整步骤详细指南见 namespace-scoped.md。快速总览运行kubebuilder edit --namespaced --force——脚手架生成 Role/RoleBinding 并更新 manager.yaml手动更新cmd/main.go配置命名空间级缓存在已有控制器文件中为 RBAC 标记添加namespace参数运行make manifests重新生成 RBAC验证并部署。⚠️ 注意edit命令配合--force会自动脚手架 RBAC 文件并更新 manager.yaml但无法自动更新已有的控制器文件和cmd/main.go——这两部分必须手动完成。迁移后再通过kubebuilder create api创建的新控制器会自动携带namespace参数。第 1 步启用命名空间级模式kubebuilder edit --namespaced --force该命令自动完成在 PROJECT 文件中设置namespaced: true将config/rbac/role.yaml脚手架为kind: Role命名空间级将config/rbac/role_binding.yaml脚手架为kind: RoleBinding重新生成config/manager/manager.yaml注入WATCH_NAMESPACE环境变量为所有已有 API 重新生成命名空间级的 admin/editor/viewer 角色。--force标志会重新生成config/manager/manager.yaml。若不加--force需要手动添加WATCH_NAMESPACEspec: template: spec: containers: - name: manager env: - name: WATCH_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespacefieldRef: metadata.namespace让 manager 自动监视自己所在的命名空间是单命名空间部署的常用技巧。第 2 步更新 cmd/main.go必须手动a. 添加 importimport ( // ... existing imports ... sigs.k8s.io/controller-runtime/pkg/cache )b. 在init()之后、main()之前添加辅助函数// getWatchNamespace returns the namespace(s) the manager should watch for changes. // It reads the value from the WATCH_NAMESPACE environment variable. func getWatchNamespace() (string, error) { watchNamespaceEnvVar : WATCH_NAMESPACE ns, found : os.LookupEnv(watchNamespaceEnvVar) if !found { return , fmt.Errorf(%s must be set, watchNamespaceEnvVar) } return ns, nil } // setupCacheNamespaces configures the cache to watch specific namespace(s). func setupCacheNamespaces(namespaces string) cache.Options { defaultNamespaces : make(map[string]cache.Config) for _, ns : range strings.Split(namespaces, ,) { defaultNamespaces[strings.TrimSpace(ns)] cache.Config{} } return cache.Options{ DefaultNamespaces: defaultNamespaces, } }c. 在main()中、ctrl.NewManager()之前读取环境变量watchNamespace, err : getWatchNamespace() if err ! nil { setupLog.Error(err, Unable to get WATCH_NAMESPACE) os.Exit(1) }d. 将缓存配置挂到 manager 选项上mgrOptions : ctrl.Options{ Scheme: scheme, Metrics: metricsServerOptions, WebhookServer: webhookServer, HealthProbeBindAddress: probeAddr, LeaderElection: enableLeaderElection, LeaderElectionID: your-leader-election-id, // ... other existing options ... } // Configure cache to watch namespace(s) specified in WATCH_NAMESPACE mgrOptions.Cache setupCacheNamespaces(watchNamespace) setupLog.Info(Watching namespace(s), namespaces, watchNamespace) mgr, err : ctrl.NewManager(ctrl.GetConfigOrDie(), mgrOptions) if err ! nil { setupLog.Error(err, Failed to start manager) os.Exit(1) }第 3 步更新已有控制器的 RBAC 标记为每个已有控制器文件包含func (r *SomeReconciler) Reconcile(的文件通常位于internal/controller/*_controller.go中的 RBAC 标记添加namespace参数。以internal/controller/cronjob_controller.go为例迁移前集群级// kubebuilder:rbac:groupsbatch.tutorial.kubebuilder.io,resourcescronjobs,verbsget;list;watch;create;update;patch;delete // kubebuilder:rbac:groupsbatch.tutorial.kubebuilder.io,resourcescronjobs/status,verbsget;update;patch // kubebuilder:rbac:groupsbatch.tutorial.kubebuilder.io,resourcescronjobs/finalizers,verbsupdate迁移后命名空间级// kubebuilder:rbac:groupsbatch.tutorial.kubebuilder.io,namespaceproject-name-system,resourcescronjobs,verbsget;list;watch;create;update;patch;delete // kubebuilder:rbac:groupsbatch.tutorial.kubebuilder.io,namespaceproject-name-system,resourcescronjobs/status,verbsget;update;patch // kubebuilder:rbac:groupsbatch.tutorial.kubebuilder.io,namespaceproject-name-system,resourcescronjobs/finalizers,verbsupdate将project-name-system替换为config/default/kustomization.yaml中namespace:字段的实际值。第 4 步重新生成 RBAC manifestmake manifests验证生成的文件是kind: Role而非kind: ClusterRole。注意config/rbac/role.yaml与config/rbac/*_editor_role.yaml、*_viewer_role.yaml、*_admin_role.yaml中的namespace字段由 kustomize 在构建时填充源文件中不写死config/rbac/metrics_auth_role.yaml保持kind: ClusterRole是正确的——metrics 认证使用集群级 APITokenReview、SubjectAccessReview即使命名空间级项目也必须保持集群级。第 5 步验证与部署make generate # Regenerate code make test # Run tests make deploy IMGyour-image # 验证 RBAC 是命名空间级而非集群级 kubectl get role,rolebinding -n manager-namespace # 在 manager 所在命名空间创建资源——应被调和 kubectl apply -f config/samples/ -n manager-namespace # 在其他命名空间创建资源——不应被调和 kubectl apply -f config/samples/ -n other-namespace多命名空间支持WATCH_NAMESPACE支持逗号分隔值同时监视多个命名空间env: - name: WATCH_NAMESPACE value: namespace-1,namespace-2,namespace-3注意需要在每个命名空间中创建Role/RoleBindingRBAC 才能正常工作。回退到集群级kubebuilder edit --namespacedfalse --force该命令自动将 PROJECT 文件中的namespaced设为false、生成ClusterRole/ClusterRoleBinding并在加--force时从 manager.yaml 移除WATCH_NAMESPACE。手动步骤包括从所有控制器 RBAC 标记中移除namespace参数、运行make manifests、清理cmd/main.go中getWatchNamespace()/setupCacheNamespaces()及相关 import。仓库中的命名空间级参考实现仓库自带测试项目 testdata/project-v4-with-plugins 是一个完整的命名空间级 manager 配置示例可以直接对照学习PROJECT 文件中namespaced: true标记了项目模式cmd/main.go 包含上述getWatchNamespace()与setupCacheNamespaces()的真实实现config/manager/manager.yaml 注入了WATCH_NAMESPACE环境变量config/rbac 目录下的role.yaml、*_admin_role.yaml、*_editor_role.yaml、*_viewer_role.yaml均为kind: Role而metrics_auth_role.yaml保持kind: ClusterRole——与上文描述完全一致。常见陷阱Webhook 与命名空间级模式如果你的项目带有 webhook需要注意一个隐蔽的问题问题manager 缓存被限制在WATCH_NAMESPACE内但 webhook 服务器默认接收来自所有命名空间的准入请求。当 webhook 处理器从缓存中查询被监视命名空间之外的对象时查询会失败。解决方案在 webhook 上配置namespaceSelector或objectSelector使 webhook 的作用域与缓存对齐。目前 controller-gen 尚未提供对应的 markers需要手动使用 Kustomize patch 添加。详细步骤见 webhook-bootstrap-problem.md。关键要点总结两套 scope 相互独立manager scope 由缓存与 RBAC 控制manager 监视哪些命名空间CRD scope 由 CRD manifest 的spec.scope字段控制资源在哪儿可见二者可自由组合默认组合集群级 manager 命名空间级 CRD 是最常见模式RBAC 标记决定角色粒度控制器 RBAC 标记中的namespace参数决定 controller-gen 生成Role还是ClusterRole集群级 CRD 必须使用ClusterRole修改 CRD scope 是破坏性变更只在开发初期、无生产数据时进行WATCH_NAMESPACE支持逗号分隔单命名空间与多命名空间共用同一套缓存配置代码webhook 需要手动对齐作用域namespaceSelector/objectSelector暂无 markers 支持需 Kustomize patch 手工处理。延伸阅读Manager Scope 详解CRD Scope 详解命名空间级迁移指南Project ConfigPROJECT 文件配置CRD 生成与 markers多版本教程版本转换与 conversion webhook赞分享开发者工具代码生成CLI云原生后端【免费下载链接】kubebuilderKubebuilder - SDK for building Kubernetes APIs using CRDs项目地址https://gitcode.com/gh_mirrors/ku/kubebuilder点击查看免费下载相关推荐Kubebuilder Manager Scope 完全指南Cluster / Namespace / Multi-Namespace 三种作用域配置与迁移实战Kubebuilder Manager Scope 完全指南Cluster / Namespace / Multi Namespace 三种作用域配置与迁移实开发者工具代码生成CLI云原生后端Kubebuilder CRD Scope 实战指南Namespace 作用域与 Cluster 作用域自定义资源的定义、切换与 RBAC 配置Kubebuilder CRD Scope 实战指南Namespace 作用域与 Cluster 作用域自定义资源的定义、切换与 RBAC 配置 Custom开发者工具代码生成CLI云原生后端Koin Annotations 作用域实战指南Scope、Scoped、ScopeId 与 Scope Archetype 全解析Koin Annotations 作用域实战指南Scope、Scoped、ScopeId 与 Scope Archetype 全解析 导读 在 Koin后端上一篇Northstar 项目常见问题解决方案下一篇HDiffPatch完整命令行教程从基础到高级用法创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表