ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

External Secrets Operator v1beta1 CRD 设计解析:dataFrom 批量拉取与模板引擎演进

External Secrets Operator v1beta1 CRD 设计解析:dataFrom 批量拉取与模板引擎演进 External Secrets Operator v1beta1 CRD 设计解析dataFrom 批量拉取与模板引擎演进【免费下载链接】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本文基于仓库中的设计文档 design/001-design-crd-v1beta1.md 展开。该文档记录了 External Secrets OperatorESO在迈向 GA 过程中将核心 CRD 从v1alpha1提升为v1beta1的设计提案核心围绕三件事定义一份可正式发布的 beta CRD、为一次拉取多个 Provider 密钥设计统一的dataFrom结构、以及引入新的模板引擎。读完本文你将掌握 v1beta1ExternalSecret的完整字段语义、dataFrom.extract/dataFrom.find的用法与底层执行路径以及 SecretStore 在 v1beta1 中的定位与升级注意事项。设计背景与目标该设计文档标题为External Secrets CRD promotion创建于 2022-02-08状态implemented指出项目在用户数量与成熟度上已经达到一个节点因此开始推动其走向 GAGeneral Availability将 ExternalSecrets CRD 提升到 beta 就是其中一项工作。这份设计文档旨在捕获 ExternalSecrets CRD 在 beta 阶段的最终变更。Goals目标定义一份 beta 版本的 CRD定义获取 Provider 全部密钥get all provider secrets的结构定义新模板引擎templating engine的结构。Non-Goals非目标该 KEPKubernetes Enhancement Proposal只提出 CRD Spec 并记录用例不涉及实现技术的选型或向 CRD 落地的迁移路径——技术选型与迁移属于实现阶段的工作。核心术语与用户模型文档定义了整套领域术语后续所有 YAML 字段都建立在这些概念之上External Secrets OperatorESO运行控制循环control loop并同步密钥的应用程序ESO instance运行单个控制循环的独立实体Provider密钥的来源source位于 ESO 外部例如 AWS Secrets Manager、AWS Systems Manager、Azure Key Vault 等托管服务SecretStoreST用于在 ESO 实例与 Provider 之间完成认证并配置连接的自定义资源ExternalSecretES声明应该同步哪些密钥的自定义资源Frontend已同步密钥的汇sink通常是 Kubernetes 的Secret资源Secret作为敏感信息访问凭据的数据。由此衍生出两类角色与两条用户故事operator :我管理一个或多个 ESO 实例user :我只创建ExternalSecretESO 由他人管理。对应需求User Stories作为 ESO operator我希望从给定 Provider 的给定路径下获取全部密钥在 Provider 支持的前提下作为 ESO operator我希望模板处理像自然语言一样自然而不需要关心底层实现细节。ExternalSecretv1beta1 核心提案设计文档给出了一份带完整注释的 v1beta1ExternalSecret示例以下为原文完整继承并补充了当前仓库源码中的字段语义#only changed fields are commented out. apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: name: hello-world labels: acme.org/owned-by: q-team annotations: acme.org/sha: 1234 spec: secretStoreRef: name: secret-store-name kind: SecretStore refreshInterval: 1h target: name: my-secret creationPolicy: Merge deletionPolicy: None #Possible values are None, Merge, Delete - TBC during implementation. template: engineVersion: v2 #Defaults to v2 in v1beta1 type: kubernetes.io/dockerconfigjson metadata: annotations: {} labels: {} data: config.yml: | endpoints: - https://{{ .data.user }}:{{ .data.password }}api.example.com templateFrom: - configMap: name: alertmanager items: - key: alertmanager.yaml data: - secretKey: secret-key-to-be-managed remoteRef: key: provider-key version: provider-key-version property: provider-key-property dataFrom: - extract: #extract all the keys from one given secret key: provider-key version: provider-key-version property: provider-key-property - find: name: #find secrets that match a particular pattern regexp: .*pattern.* tags: #find secrets that match the following labels/tags provider-label: provider-value status: refreshTime: 2019-08-12T12:33:02Z conditions: - type: Ready status: True reason: SecretSynced message: Secret was synced lastTransitionTime: 2019-08-12T12:33:02ZdataFrom 的新行为Behavior设计文档明确指出v1beta1 的ExternalSecret对dataFrom采用了全新的结构使得只用一份 ExternalSecret 定义即可拉取多个 Provider 密钥并且支持基于正则表达式或标签/标签选择器来查找密钥。若用户需要重命名密钥例如 Provider 中的键名/foo/bar不是合法的 Secret 键名应使用template函数生成映射。在 apis/externalsecrets/v1beta1/externalsecret_types.go 中ExternalSecretDataFromRemoteRef结构体与设计文档完全对应并在此基础上演进出更多能力Extract *ExternalSecretDataRemoteRef从一个 Provider 密钥中取出多个 key/value 对等价于 v1alpha1 中dataFrom[].key的行为注意注释明确说明Extract 不支持sourceRef.Generator/GeneratorRefFind *ExternalSecretFind基于标签或正则查找密钥同样不支持 Generator 类 sourceRefRewrite []ExternalSecretRewrite对 Provider 返回的密钥键名进行重写多个 Rewrite 操作按从第一个到最后一个分层依次应用SourceRef *StoreGeneratorSourceRef指向某个 SecretStore 或 Generator 作为取值来源当指向 Generator 时 Extract/Find 不可用Generator 返回的是静态键值映射。ExternalSecretFind同文件 L366-L389在设计的name.regexp与tags基础上增加了path查找操作的根路径起点以及conversionStrategy默认Default、decodingStrategy默认None。单键同步与批量同步的对照设计文档同时展示了data与dataFrom两种模式二者在 ExternalSecretSpec 中并存spec.data[]显式地把单个 Provider 键映射到单个 Kubernetes Secret 键。每个条目由secretKeyKubernetes 侧键名需匹配^[-._a-zA-Z0-9]$与remoteRefkey必填version、property可选另有metadataPolicy默认None、conversionStrategy默认Default、decodingStrategy默认None组成spec.dataFrom[]批量地从 Provider 拉取。多个条目按书写顺序合并进同一个 Secret后续条目会覆盖同名键源码注释明确Secret keys are merged in the specified order。从控制器实现看pkg/controllers/externalsecret/externalsecret_controller_secret.go 的 reconcile 流程正是按dataFrom优先、data其次的顺序执行先遍历Spec.DataFrom对每个条目依次判定FindhandleFindAllSecrets、ExtracthandleExtractSecrets、GeneratorRefhandleGenerateSecrets三种分支最后用esutils.MergeByteMap合并结果再遍历Spec.Data逐键调用handleSecretData。handleExtractSecretsL213 起内部依次执行client.GetSecretMap、键名 Rewrite/Convert、ValidateKeys、decoding.DecodeMap与空字节校验一条链路上即可验证批量拉取 → 键名规范化 → 解码的完整语义。target 与模板引擎 v2设计文档在spec.target.template中引入了engineVersion: v2并声明v1beta1 默认即 v2。这在 ExternalSecretTemplate 中得到落实EngineVersion通过kubebuilder:defaultv2默认取v2且当前枚举仅允许v2模板数据既可以写在data内联字段也可以通过templateFrom引用ConfigMap或Secret中的模板片段并支持mergePolicy默认Replace控制模板合并行为。模板中通过{{ .data.user }}、{{ .data.password }}这类自然语言式的引用访问已拉取的密钥值——这正是设计文档第二条用户故事像自然语言一样处理模板的直接体现。相关模板引擎实现位于 runtime/template 目录v1/v2 两套引擎及配套测试。creationPolicy 与 deletionPolicy 的最终枚举设计文档示例中注明creationPolicy: Merge、deletionPolicy: None且Possible values are None, Merge, Delete - TBC during implementation实现期间待定。在最终落地的源码中枚举被明确为ExternalSecretCreationPolicyL39-L56Owner创建 Secret 并设置 ownerReference默认值、Orphan不设置 ownerReferenceExternalSecret 删除后 Secret 成为孤儿、Merge不创建 Secret仅合并 data 字段、None不创建 Secret预留给未来的注入器ExternalSecretDeletionPolicyL58-L79DeleteProvider 侧密钥全部删除后删除 Secret、Merge仅移除对应键不删除 Secret 本身、Retain保留 Secret默认值Provider 密钥不存在时进入SecretSyncedError状态。设计文档示例中的deletionPolicy: None在正式实现中并未采用——这正是文档标注 TBC during implementation 的用意最终以源码枚举为准。SecretStorev1beta1 保持兼容设计文档明确写道SecretStore 与 ClusterSecretStore 相比 v1alpha1 没有任何变更并给出了一份多 Provider 的 SecretStore 示例以下完整继承原文apiVersion: external-secrets.io/v1beta1 kind: SecretStore metadata: name: example namespace: example-ns spec: controller: dev retrySettings: maxRetries: 5 retryInterval: 10s provider: aws: service: SecretsManager role: iam-role region: eu-central-1 auth: secretRef: accessKeyID: name: awssm-secret key: access-key secretAccessKey: name: awssm-secret key: secret-access-key vault: server: https://vault.acme.org path: secret version: v2 namespace: a-team caBundle: ... caProvider: type: Secret name: my-cert-secret key: cert-key auth: tokenSecretRef: name: my-secret namespace: secret-admin key: vault-token appRole: path: approle roleId: db02de05-fa39-4855-059b-67221c5c2f63 secretRef: name: my-secret namespace: secret-admin key: vault-token kubernetes: mountPath: kubernetes role: demo serviceAccountRef: name: my-sa namespace: secret-admin secretRef: name: my-secret namespace: secret-admin key: vault gcpsm: auth: secretRef: secretAccessKeySecretRef: name: gcpsm-secret key: secret-access-credentials projectID: myproject status: conditions: - type: Ready status: False reason: ConfigError message: SecretStore validation failed lastTransitionTime: 2019-08-12T12:33:02Z对照 apis/externalsecrets/v1beta1/secretstore_types.go 的SecretStoreSpec可以确认controller字段用于选择正确的 ESO 控制器实例类比ingress.ingressClassNameprovider一次只能配置一个MinProperties1/MaxProperties1retrySettings配置失败时的 HTTP 重试。Provider 类型在SecretStoreProvider中持续扩充当前仓库已支持 AWS、AzureKV、Vault、GCPSM、Webhook、Kubernetes、Fake 等数十种见 secretstore_types.go但 SecretStore 的框架结构自 v1alpha1 起保持稳定。spec.controller的机制细节可参考 docs/guides/controller-class.md。v1beta1 的落地、升级与验证与 v1alpha1 的差异设计文档提出的结构差异在 docs/guides/v1beta1.md 中有明确说明v1alpha1 与 v1beta1 对 SecretStore、ClusterSecretStore完全兼容唯一差异在ExternalSecret的dataFrom。v1alpha1 中dataFrom直接写keyspec: dataFrom: - key: my-key - key: my-other-keyv1beta1 中拆分为两种方法Extract与 v1alpha1 行为完全一致Find则支持按正则或标签查找并合并进单个 Kubernetes Secretspec: dataFrom: - find: name: #matches any secret name ending in foo-bar regexp: .*foo-bar$ - find: tags: #matches any secrets with the following metadata. env: dev app: web升级路径官方升级指引docs/guides/v1beta1.md建议未使用dataFrom或通过官方 Helm Chart 部署 CRD 的用户可无风险升级手工安装 CRD 时需部署deploy/crds/bundle.yaml注意文档中deploys/crds/bundle.yaml的路径在仓库中实际为 deploy/crds/bundle.yaml该 bundle 同时包含 v1beta1 定义与转换 Webhook 配置确保升级未完成前新的 CRD 请求不会生效从而避免数据丢失。升级完成后每次 reconcile 时存储为 v1alpha1 的 ExternalSecret、SecretStore、ClusterSecretStore 会被自动转换为 v1beta1。实测样例与端到端验证仓库自带的测试清单 tests/externalsecrets_test.yaml 覆盖了 v1beta1 ExternalSecret 的完整字段组合可直接作为合法样例参考批量拉取的实战配置见 docs/snippets/getallsecrets-find-by-name.yaml 与 docs/snippets/getallsecrets-find-by-tags.yaml其行为说明记录在 docs/guides/getallsecrets.mdfind会把不合法的 Secret 键名字符自动替换为_如/path/key1变为_path_key1若出现命名冲突可通过rewrite块以正则重写或用find.conversionStrategy: Unicode将非法字符编码为_UXXXX_形式降低冲突概率CRD 定义本身位于 config/crds/bases26 个 YAML设计文档中的status.conditionsReady/SecretSynced/ConfigError等可在 CRD 的 status 子结构中验证。结语design/001-design-crd-v1beta1.md是 ESO 走向 GA 的关键里程碑设计它锁定了 v1beta1 CRD 的形态将批量获取 Provider 密钥固化为dataFrom.extract与dataFrom.find两种语义并把模板引擎统一到 v2。该设计已在当前仓库完整落地——从 apis/externalsecrets/v1beta1/externalsecret_types.go 的类型定义到 pkg/controllers/externalsecret/externalsecret_controller_secret.go 的控制器实现再到 docs/guides/getallsecrets.md、docs/guides/v1beta1.md 等使用与升级文档均与设计初衷一一对应。对使用者而言理解本文的data/dataFrom双模式与模板引擎语义即可安全地在 v1beta1 上构建一份 ExternalSecret 同步全部所需密钥的实战方案。【免费下载链接】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),仅供参考
返回列表