ARTICLE DETAIL

资讯详情

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

使用 External Secrets Operator 对接 Segura® DevOps Secret Manager(DSM)同步 Kubernetes Secrets

使用 External Secrets Operator 对接 Segura® DevOps Secret Manager(DSM)同步 Kubernetes Secrets 使用 External Secrets Operator 对接 Segura® DevOps Secret ManagerDSM同步 Kubernetes Secrets【免费下载链接】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本篇技术指南讲解如何在 External Secrets OperatorESO中通过 senhasegura provider 对接 Segura® 的 DevOps Secret ManagerDSM模块将 DSM 中由应用授权Authorization关联的密钥自动同步为 Kubernetes Secret。你将掌握 DSM 应用的 OAuth2 认证配置、SecretStore 与 ClusterSecretStore 两种存储的定义方式以及按 Secret Identifier 精确同步、按 key/value 自动展开等多种 ExternalSecret 同步模式并了解其底层 API 调用与校验逻辑。一、整体原理ESO 与 Segura® DSM 的对接方式External Secrets Operator 支持通过 provider 插件读取第三方密钥管理系统的数据并将数据以 Kubernetes Secret 的形式注入集群。senhasegura provider 是其官方维护的 provider 之一维护状态见 providers/v1/senhasegura/provider.go 中的MaintenanceStatus()返回MaintenanceStatusMaintained专门用于同步 Segura® DevOps Secret ManagerDSM模块中的密钥。对接链路的核心流程如下ESO 控制器读取SecretStore/ClusterSecretStore中spec.provider.senhasegura的配置控制器通过NewClient创建 senhasegura 客户端providers/v1/senhasegura/provider.go先用auth.Authenticate完成 OAuth2 认证拿到访问令牌再根据provider.Module判断目标模块当module: DSM时返回dsm.New(isoSession)创建的 DSM 客户端ExternalSecret控制器调用客户端的GetSecret单键同步或GetSecretMap多键同步拉取 DSM 数据并写入目标 Kubernetes Secret。需要说明的是从 dsm.go 的源码结构看senhasegura provider 当前只实现了只读能力Capabilities()返回SecretStoreReadOnlyprovider.goPushSecret、DeleteSecret、SecretExists等写操作接口均返回errNotImplemented因此它目前只用于“拉取并同步”不支持 PushSecret 回写 DSM。二、认证在 Segura® DSM 中为应用配置授权Segura® DSM 采用“应用授权”机制管理员在 DSM 中创建应用Application为应用配置授权Authorization并把需要分发的密钥关联到该授权上。ESO 侧通过 DSM 应用授权模式完成认证。在 Segura® 侧创建授权与密钥的具体步骤请参考 Segura® 官方的 DSM 授权管理文档。ESO 侧需要准备一个 Kubernetes Secret 存放认证参数即 DSM 应用的 Client Secret示例见 docs/snippets/senhasegura-dsm-secret.yamlapiVersion: v1 kind: Secret metadata: name: senhasegura-dsm-auth stringData: CLIENT_SECRET: CHANGEME将该 Secret 创建到集群后把CHANGEME替换为 DSM 应用中真实的 Client Secret 值。从认证实现看providers/v1/senhasegura/auth/iso.go 中的GetIsoToken会向https://senhasegura-url/iso/oauth2/token发送POST请求携带grant_typeclient_credentials、client_id和client_secret参数application/x-www-form-urlencoded返回 JSON 中的access_token即作为后续访问 DSM API 的 Bearer Token。认证参数clientId直接写在 Store 中而clientSecretSecretRef引用上文创建的 Kubernetes Secret密钥不会明文暴露在 Store 资源里。三、配置 SecretStore / ClusterSecretStore要开始同步密钥需要定义一个SecretStore命名空间级或ClusterSecretStore集群级资源指定 senhasegura provider 并在 DSM 模块中完成认证配置。SecretStore命名空间级示例来自 docs/snippets/senhasegura-dsm-secretstore.yamlapiVersion: external-secrets.io/v1 kind: SecretStore metadata: name: senhasegura spec: provider: senhasegura: url: https://senhasegura.changeme.com module: DSM # Select senhasegura DSM module to sync secrets auth: clientId: CHANGEME clientSecretSecretRef: name: senhasegura-dsm-auth key: CLIENT_SECRET ignoreSslCertificate: false # OptionalClusterSecretStore集群级示例来自 docs/snippets/senhasegura-dsm-clustersecretstore.yaml。与SecretStore唯一的区别是ClusterSecretStore是集群级资源它引用的认证 Secret 可能位于其他命名空间因此需要显式声明namespace字段apiVersion: external-secrets.io/v1 kind: ClusterSecretStore metadata: name: senhasegura spec: provider: senhasegura: url: https://senhasegura.changeme.com module: DSM # Select senhasegura DSM module to sync secrets auth: clientId: CHANGEME clientSecretSecretRef: name: senhasegura-dsm-auth key: CLIENT_SECRET namespace: senhasegura # Namespace of Secret senhasegura-dsm-auth ignoreSslCertificate: false # Optional字段说明字段定义见 apis/externalsecrets/v1/secretstore_senhasegura_types.go字段类型必填说明urlstring是Segura® 实例的地址。根据 provider.go 的校验逻辑URL 必须为 HTTPS 且必须包含 Host否则 Store 校验失败modulestring是目标模块当前唯一合法值为DSMkubebuilder 枚举约束见 secretstore_senhasegura_types.go。若配置其他值NewClient会返回unknown senhasegura Provider Service错误auth.clientIdstring是DSM 应用的 Client ID缺失时校验报错missing senhasegura authentication Client IDauth.clientSecretSecretRefSecretKeySelector是存放 Client Secret 的 Kubernetes Secret 引用ClusterSecretStore需额外指定namespaceignoreSslCertificatebool否是否跳过 TLS 证书校验默认false。仅用于测试或内网自签名证书场景生产环境应保持关闭值得注意的细节是Store 在创建时就会经过 Validating Webhook 校验ValidateStore见 provider.goURL 必须是 HTTPS、Host 非空、Client ID 非空。也就是说非法配置的 Store 根本不会被创建出来这能把认证错误提前到配置阶段暴露。四、同步前准备DSM 中的示例密钥本文后续示例假设 Segura® DSM 中已存在三个密钥均通过应用授权关联到 ESO 使用的 DSM 应用Secret Identifier:api-settingsURLhttps://example.com/api/example TOKENexample-token-valueSecret Identifier:db-settingsDB_HOSTdb.example DB_PORT5432 DB_USERNAMEexample DB_PASSWORDexampleSecret Identifier:hsm-settingsHSM_ADDRESShsm.example HSM_PORT9223这里的“Secret Identifier”对应 DSM API 响应中每个密钥的identity字段也是 ExternalSecret 中remoteRef.key的取值。五、按 Secret Identifier 同步单个 ExternalSecret当只需要同步指定标识符下的全部或部分 key/value 时使用ExternalSecret的data字段。行为说明若remoteRef.property为空则返回该标识符下全部 key/value 的 JSON 编码值对应源码 dsm.go 中GetSecret的ref.Property 分支会对v.Data做json.Marshal若指定了remoteRef.property则只返回该 key 对应的原始字符串值此模式下Kubernetes Secret 的数据键名.data.X由secretKey显式指定可以自由覆盖命名例如API_SETTINGS和API_SETTINGS_TOKEN。配置示例示例来自 docs/snippets/senhasegura-dsm-external-secret-single.yamlapiVersion: external-secrets.io/v1 kind: ExternalSecret metadata: name: example-secret spec: refreshInterval: 30s secretStoreRef: name: senhasegura kind: SecretStore target: name: example-secret data: # Define API_SETTINGS Kubernetes Secret key, with json-encoded values from senhasegura secret with identifier api-settings - secretKey: API_SETTINGS remoteRef: key: api-settings # Secret Identifier in senhasegura # Define API_SETTINGS_TOKEN Kubernetes Secret key, with single secret key (TOKEN) from senhasegura as string - secretKey: API_SETTINGS_TOKEN remoteRef: key: api-settings # Secret Identifier in senhasegura property: TOKEN # Optional, Key name within secret同步结果应用该 ExternalSecret 后控制器会创建名为example-secret的 Kubernetes Secret其.data内容为API_SETTINGS[{TOKEN:example-token-value,URL:https://example.com/api/example}] API_SETTINGS_TOKENexample-token-value其中API_SETTINGS是api-settings全部键值的 JSON 编码注意它是数组形式对应源码中v.Data的类型为[]map[string]stringAPI_SETTINGS_TOKEN则是TOKEN键的原始字符串。六、按 Secret Identifier 自动展开多个 key/value如果应用需要多个密钥且希望 DSM 中的每个 key/value 自动成为 Kubernetes Secret 的独立.data字段无需为每个密钥单独编写data条目可以使用dataFrom的extract方式把多个 Secret Identifier 聚合到同一个 ExternalSecret 中。配置示例示例来自 docs/snippets/senhasegura-dsm-external-secret-multiple.yamlapiVersion: external-secrets.io/v1 kind: ExternalSecret metadata: name: example-secret spec: refreshInterval: 30s secretStoreRef: name: senhasegura kind: SecretStore target: name: example-secret dataFrom: # Define Kubernetes Secret key with any k/v pair in senhasegura Secret with identifier api-settings or db-settings - extract: key: api-settings - extract: key: db-settings同步结果dataFrom.extract底层调用客户端的GetSecretMap见 dsm.go该方法遍历 DSM 响应中匹配ref.Key的密钥将其data中的每一对 key/value 直接写入secretDatamap。最终生成的 Kubernetes Secret.data为URLhttps://example.com/api/example TOKENexample-token-value DB_HOSTdb.example DB_PORT5432 DB_USERNAMEexample DB_PASSWORDexample这种模式的优势在于一个 ExternalSecret 即可聚合多个 Secret Identifier 的所有键值应用侧无需关心键的重新命名直接使用原始键名即可。七、同步模式与底层实现对照下表汇总了两种同步模式与 senhasegura DSM 客户端源码实现的对应关系便于排查与理解行为差异ExternalSecret 写法底层调用行为源码位置dataremoteRef.property为空GetSecret返回该 Identifier 全部键值的 JSON 编码dsm/dsm.godataremoteRef.property指定键GetSecret返回指定键的原始字符串dsm/dsm.godataFrom.extractGetSecretMap该 Identifier 下每个 key/value 展开为独立.data字段dsm/dsm.godataFrom.findGetAllSecrets尚未实现返回errNotImplementeddsm/dsm.go关于“同步授权下全部密钥”的说明原文档中注释掉了一段“Sync all secrets from DSM authorization”的示例使用dataFrom.find: {}。从源码确认GetAllSecrets目前返回errNotImplementeddsm/dsm.go源码注释中也有 TODO 说明该功能未来计划支持按名称正则匹配或标签匹配。因此当前版本请不要使用find方式同步全部密钥应使用上文基于 Secret Identifier 的data/dataFrom.extract方式。八、底层 API 与常见问题排查DSM 数据获取流程无论是单键还是多键同步最终都会调用 dsm.go 中的FetchSecrets()其行为如下向https://senhasegura-url/iso/dapp/application发起GET请求请求头携带Authorization: Bearer iso tokenToken 来自第二步认证响应体为IsoDappResponse结构dsm.go包含application.secrets数组每个密钥含secret_id、secret_name、identity、version、expiration_date、engine以及data[]map[string]string非 200 状态码返回received invalid HTTP code from senhasegura响应中response.error true时返回received application error from senhasegura。Store 连通性校验Validate()方法dsm.go通过实际调用FetchSecrets()验证连接与凭据是否有效成功返回ValidationResultReady失败返回ValidationResultError。该结果会体现在SecretStore资源的status中是排查认证问题最直接的入口。常见问题排查清单Store 无法创建/被 Webhook 拒绝检查url是否为 HTTPS 且包含主机名、clientId是否填写对应校验逻辑见 provider.goSecretStore 状态为 Error检查 DSM 应用的clientId/clientSecret是否匹配授权是否正确关联了密钥以及 ESO 运行环境能否访问 Segura® 地址报错cannot do request in senhasegura, SSL certificate is valid ?通常是 TLS 证书问题。生产环境应确保证书有效仅在测试环境可临时开启ignoreSslCertificate: truefind方式不生效GetAllSecrets尚未实现见上文请改用 Secret Identifier 方式同步到集群的 Secret 数据与 DSM 不一致注意refreshInterval决定重新拉取周期示例中为30sDSM 侧密钥更新后需等待下一个刷新周期。九、测试与验证senhasegura provider 的单元测试位于 providers/v1/senhasegura/provider_test.go端到端测试用例位于 e2e/suites/provider/senhasegura_dsm_test.go若该文件不存在可查看 e2e/suites/provider 目录下以senhasegura命名的用例。此外仓库中还提供了可直接用于演练的清单文件认证 Secretdocs/snippets/senhasegura-dsm-secret.yamlSecretStoredocs/snippets/senhasegura-dsm-secretstore.yamlClusterSecretStoredocs/snippets/senhasegura-dsm-clustersecretstore.yaml单键同步 ExternalSecretdocs/snippets/senhasegura-dsm-external-secret-single.yaml多键展开 ExternalSecretdocs/snippets/senhasegura-dsm-external-secret-multiple.yaml建议的验证流程依次应用认证 Secret、SecretStore / ClusterSecretStore检查 Store 的status是否为 ReadyValidate()已连通测试应用 ExternalSecret 后用kubectl get secret target-name -o yaml检查.data字段是否符合预期修改 DSM 中的密钥值等待refreshInterval后确认 Kubernetes Secret 是否同步更新。十、总结通过 senhasegura providerExternal Secrets Operator 可以安全、自动地将 Segura® DSM 模块中的密钥同步为 Kubernetes Secret认证采用 DSM 应用的 OAuth2client_credentials流程Client Secret 存放于 Kubernetes Secret 中避免明文泄漏存储支持命名空间级SecretStore与集群级ClusterSecretStoreStore 创建即校验 URL、HTTPS、Client ID 等关键配置同步支持按 Secret Identifier 单键取值dataproperty、整份 JSON 取值property留空以及多键自动展开dataFrom.extract三种方式find全量同步能力尚未实现能力边界当前 provider 为只读不支持 PushSecret 回写。在实施时请始终把ignoreSslCertificate保持为false并严格遵循最小权限原则为 DSM 应用授权确保密钥分发链路的安全。【免费下载链接】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),仅供参考
返回列表