ARTICLE DETAIL

资讯详情

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

External Secrets Operator Controller Classes 实战指南:用控制器类隔离 SecretStore 与多控制器调度

External Secrets Operator Controller Classes 实战指南:用控制器类隔离 SecretStore 与多控制器调度 External Secrets Operator Controller Classes 实战指南用控制器类隔离 SecretStore 与多控制器调度【免费下载链接】external-secretsExternal Secrets Operator reads information from a third-party service like AWS Secrets Manager and automatically injects the values as Kubernetes Secrets.项目地址: https://gitcode.com/GitHub_Trending/ex/external-secretsExternal Secrets OperatorESO的 Controller Classes控制器类特性允许在集群中同时运行多个 controller 实例并通过SecretStore上的spec.controller字段将不同的 SecretStore 划分给不同的 controller 处理。本文将以官方指南 docs/guides/controller-class.md 为核心结合仓库中的 Helm Chart、控制器源码与测试用例完整讲解 Controller Classes 的配置方法、匹配原理与实战注意事项读完即可上手搭建多控制器 多租户的密钥同步架构。Controller Classes 是什么Controller Classes 是 ESO 在部署阶段设置的一个属性property它允许多个 controller 在同一组工作负载中协同工作。其核心思路是通过一个类名class name把集群中的 SecretStore 划分成不同集合每个 controller 只处理归属于自己那一类的 SecretStore。⚠️ 官方提示该特性目前处于experimental实验性状态测试覆盖尚不充分not highly tested。在生产环境大规模使用前请先进行充分验证。对于单个 controller的部署形态Controller Classes 不需要任何额外配置所有 SecretStore 都会由这一个 controller 处理行为与未启用该特性时完全一致。适用场景从特性设计看Controller Classes 主要解决以下问题多租户/多团队隔离不同团队或租户使用不同的 controller 实例各自只处理自己名下的 SecretStore互不干扰渐进式升级让新版本的 controller 只接管一部分 SecretStore验证稳定后再逐步迁移能力分组不同 controller 可以携带不同的 provider 注册集合、不同的 RBAC 权限按组分配工作负载。工作匹配原理从源码看判定逻辑Controller Classes 的归属判定逻辑非常简洁定义在 pkg/controllers/secretstore/common.go#L214-L221 的ShouldProcessStore函数中// ShouldProcessStore returns true if the store should be processed. func ShouldProcessStore(store esapi.GenericStore, class string) bool { if store nil || store.GetSpec().Controller || store.GetSpec().Controller class { return true } return false }这段代码揭示了三条关键规则未设置spec.controller的 SecretStore 对所有 controller 都有效。只要Controller 任何 controller 都会处理它——这正是原文档末尾特别强调的那条 Notespec.controller与 controller 的类名完全相等时该 store 归这个 controller 处理spec.controller非空且不相等时该 store 被跳过skipcontroller 不会触碰它。controller 的类名来自启动参数--controller-class。在 cmd/controller/root.go#L356 中可以看到该参数的默认值与说明rootCmd.Flags().StringVar(controllerClass, controller-class, default, The controller is instantiated with a specific controller name and filters ES based on this property)也就是说直接以二进制方式启动的 controller 默认类名是default。如果通过 Helm 部署并设置了controllerClass则该值会覆盖默认值。校验路径中的双重过滤ShouldProcessStore不仅在 reconcile 入口被调用见 pkg/controllers/secretstore/common.go#L72在validateStore创建 provider client 时也会再次校验见 pkg/controllers/secretstore/client_manager.go#L129确保 controller 不会为不属于自己的 store 建立 provider 连接。这一点很重要不匹配的 SecretStore 连验证状态status conditions都不会被写入测试用例也印证了这一点见下文如何验证一节。配置 Controller ClassHelm 安装官方推荐的部署方式是使用 Helm Chart。核心参数定义在 deploy/charts/external-secrets/values.yaml#L119# -- If set external secrets will filter matching # Secret Stores with the appropriate controller values. controllerClass: 默认值为空字符串表示不启用类过滤所有 store 都处理。安装命令helm install custom-external-secrets external-secrets/external-secrets --set controllerClasscustom当controllerClass非空时Chart 模板会在 deployment 中追加--controller-class启动参数。具体实现在 deploy/charts/external-secrets/templates/deployment.yaml#L115-L116{{- if .Values.controllerClass }} - --controller-class{{ .Values.controllerClass }} {{- end }}关于该参数的完整说明可参见 Chart 文档 deploy/charts/external-secrets/README.md#L124controllerClass(string, default)如果设置external secrets 将过滤匹配的 SecretStore带相应 controller 值的。不通过 Helm 时的等价配置如果你直接以二进制或自定义清单方式运行 controller等价做法是在启动参数中显式指定./external-secrets --controller-classcustom或者直接使用默认类名default不传该参数即为default。创建带 controller 的 SecretStore安装好 controller 后创建SecretStore时在spec中设置controller字段值必须与 Helm 安装时的controllerClass一致。完整示例见仓库片段文件 docs/snippets/controller-class-store.yamlapiVersion: external-secrets.io/v1 kind: SecretStore metadata: name: controller-custom-example spec: #define the controller label to the matching value of the deployment controller: custom #configure provider the same way provider: vault: server: http://vault.default:8200 path: secret version: v2 auth: kubernetes: mountPath: kubernetes role: demo-role要点说明spec.controller: custom与 Helm 的--set controllerClasscustom必须完全匹配区分大小写的字符串相等比较provider部分此处为 Vault与普通 SecretStore 的配置方式完全一致controller字段不影响 provider 的认证与读取逻辑该字段同样适用于ClusterSecretStore其spec.controller判定逻辑与 SecretStore 相同ShouldProcessStore通过esapi.GenericStore接口统一处理两种 store见 pkg/controllers/secretstore/common.go#L71-L75。部署完成后任何绑定到这个 SecretStore 的ExternalSecret都将由 controllerClass 为custom的那个 operator 实例负责评估和同步。未设置 controller 的 SecretStore 会怎样再次强调原文档末尾的这条重要 Note任何没有设置spec.controller的 SecretStore无论各个 operator 的 controllerClass 是什么都会被它们视为有效valid并处理。这意味着 Controller Classes 提供的是一种白名单式的按需隔离想纳入某个 controller 专属管辖的 store必须显式写spec.controller不带该字段的 store 处于公共状态会被集群中所有controller 同时处理。因此在多 controller 部署时请务必明确区分公共 store与专属 store避免同一个 SecretStore 被多个 controller 重复处理造成非预期行为。多控制器协同的完整形态结合以上配置一个典型的多 controller 部署形态如下组件配置说明Controller Ahelm install ... --set controllerClassteam-a只处理spec.controller: team-a与未设置 controller 的 storeController Bhelm install ... --set controllerClassteam-b只处理spec.controller: team-b与未设置 controller 的 storeStore 1spec.controller: team-a仅 Controller A 处理Store 2spec.controller: team-b仅 Controller B 处理Store 3不设置spec.controllerController A 和 B 都会处理从源码结构看类过滤逻辑在多个 reconciler 中均有体现除 SecretStore 控制器外pkg/controllers/externalsecret/externalsecret_controller.go#L158 的Reconciler持有ControllerClass字段pkg/controllers/pushsecret/pushsecret_controller.go#L858 对 PushSecret 也做了同类过滤class ! class ! r.ControllerClass时跳过。也就是说ExternalSecret 同步、PushSecret 推送、SecretStore 验证三条链路都遵循同一套 controller 类过滤规则可以推断这是 ESO 整体的统一调度策略。如何验证配置生效从测试用例看预期行为仓库的集成测试 pkg/controllers/secretstore/common_test.go#L86-L105 专门覆盖了controllerClass 不匹配的场景测试名即ignoreControllerClass忽略不匹配 controller class 的 storeignoreControllerClass : func(tc *testCase) { spc : tc.store.GetSpec() spc.Controller something-else tc.assert func() { Eventually(func() bool { ... return ss.GetObjectMeta().GetResourceVersion() ! ss.GetSpec().Controller something-else len(ss.GetStatus().Conditions) 0 }). WithTimeout(time.Second*10). WithPolling(time.Millisecond*250). Should(BeTrue(), cache should reflect the new store with no conditions) ... } }这个测试揭示了两个可用于人工验证的行为特征即使 store 的spec.controller与 controller 类不匹配store 对象本身仍会被正常缓存ResourceVersion 存在该 store 的status.conditions保持为空——controller 完全无视它不会写入任何 Ready 条件。测试中还定义了默认 controller 类defaultControllerClass test-ctrl见 pkg/controllers/secretstore/common_test.go#L43并通过两条用例分别覆盖了命名空间级 SecretStore 与集群级 ClusterSecretStore 的忽略行为见 pkg/controllers/secretstore/common_test.go#L242-L249。人工验证步骤部署两个不同controllerClass的 controller 实例创建spec.controller与其中一个匹配的 SecretStore观察两个 controller 的日志匹配的那个会输出 store 校验/同步相关日志不匹配的那个会以V(1)级别输出skip store见 pkg/controllers/secretstore/common.go#L73检查 SecretStore 的status.conditions只有匹配的 controller 会为其写入SecretStoreReady条件。注意事项与已知限制基于原文档的说明与仓库现状使用 Controller Classes 时需注意以下几点实验性特性文档明确标注 experimental and not highly tested升级 ESO 版本时请回归验证字符串完全匹配spec.controller与--controller-class是精确字符串比较拼写、大小写不一致都会导致 store 无人认领所有 controller 都跳过单值约束从 CRD 与ShouldProcessStore的实现看一个 SecretStore 只能声明一个controller 类无法同时归属于多个专属 controller公共 store例外即不设置该字段公共 store 的叠加处理不带spec.controller的 store 会被所有 controller 处理若多 controller 都配置了相同的 provider 凭证注意这可能产生重复的 provider 调用默认类名为default直接运行二进制而不传参时类名是default若某 store 的spec.controller恰好设为default则只有默认类名的 controller 会处理它。总结Controller Classes 为 External Secrets Operator 提供了轻量、易用的多控制器调度能力通过 Helm 的controllerClass参数或--controller-class启动参数声明 controller 归属通过 SecretStore/ClusterSecretStore 的spec.controller声明 store 归属二者字符串相等即建立绑定关系未声明 controller 的 store 保持公共状态被所有 controller 处理。其判定逻辑集中在ShouldProcessStore一个函数中覆盖 SecretStore、ExternalSecret 与 PushSecret 三条同步链路非常适合需要多租户隔离、渐进式升级或能力分组部署的场景。在完全依赖该特性前请牢记其实验性定位并结合仓库中的测试用例pkg/controllers/secretstore/common_test.go验证你预期的过滤行为。【免费下载链接】external-secretsExternal Secrets Operator reads information from a third-party service like AWS Secrets Manager and automatically injects the values as Kubernetes Secrets.项目地址: https://gitcode.com/GitHub_Trending/ex/external-secrets创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表