news 2026/9/17 5:31:30

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用 External Secrets Operator 对接 Segura® DevOps Secret Manager(DSM)同步 Kubernetes Secrets

使用 External Secrets Operator 对接 Segura® DevOps Secret Manager(DSM)同步 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 Operator(ESO)中通过 senhasegura provider 对接 Segura® 的 DevOps Secret Manager(DSM)模块,将 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 Manager(DSM)模块中的密钥。

对接链路的核心流程如下:

  1. ESO 控制器读取SecretStore/ClusterSecretStorespec.provider.senhasegura的配置;
  2. 控制器通过NewClient创建 senhasegura 客户端(providers/v1/senhasegura/provider.go):先用auth.Authenticate完成 OAuth2 认证拿到访问令牌,再根据provider.Module判断目标模块;当module: DSM时返回dsm.New(isoSession)创建的 DSM 客户端;
  3. ExternalSecret控制器调用客户端的GetSecret(单键同步)或GetSecretMap(多键同步)拉取 DSM 数据并写入目标 Kubernetes Secret。

需要说明的是,从 dsm.go 的源码结构看,senhasegura provider 当前只实现了只读能力:Capabilities()返回SecretStoreReadOnly(provider.go),PushSecretDeleteSecretSecretExists等写操作接口均返回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.yaml:

apiVersion: 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_type=client_credentialsclient_idclient_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.yaml:

apiVersion: 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 # Optional

ClusterSecretStore(集群级)

示例来自 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:

字段类型必填说明
urlstringSegura® 实例的地址。根据 provider.go 的校验逻辑,URL 必须为 HTTPS 且必须包含 Host,否则 Store 校验失败
modulestring目标模块,当前唯一合法值为DSM(kubebuilder 枚举约束见 secretstore_senhasegura_types.go)。若配置其他值,NewClient会返回unknown senhasegura Provider Service错误
auth.clientIdstringDSM 应用的 Client ID,缺失时校验报错missing senhasegura authentication Client ID
auth.clientSecretSecretRefSecretKeySelector存放 Client Secret 的 Kubernetes Secret 引用,ClusterSecretStore需额外指定namespace
ignoreSslCertificatebool是否跳过 TLS 证书校验,默认false。仅用于测试或内网自签名证书场景,生产环境应保持关闭

值得注意的细节是,Store 在创建时就会经过 Validating Webhook 校验(ValidateStore,见 provider.go):URL 必须是 HTTPS、Host 非空、Client ID 非空。也就是说,非法配置的 Store 根本不会被创建出来,这能把认证错误提前到配置阶段暴露。

四、同步前准备:DSM 中的示例密钥

本文后续示例假设 Segura® DSM 中已存在三个密钥,均通过应用授权关联到 ESO 使用的 DSM 应用:

  • Secret Identifier:api-settings
URL=https://example.com/api/example TOKEN=example-token-value
  • Secret Identifier:db-settings
DB_HOST='db.example' DB_PORT='5432' DB_USERNAME='example' DB_PASSWORD='example'
  • Secret Identifier:hsm-settings
HSM_ADDRESS='hsm.example' HSM_PORT='9223'

这里的“Secret Identifier”对应 DSM API 响应中每个密钥的identity字段,也是 ExternalSecret 中remoteRef.key的取值。

五、按 Secret Identifier 同步单个 ExternalSecret

当只需要同步指定标识符下的全部或部分 key/value 时,使用ExternalSecretdata字段。

行为说明

  • remoteRef.property为空,则返回该标识符下全部 key/value 的 JSON 编码值(对应源码 dsm.go 中GetSecretref.Property == ""分支,会对v.Datajson.Marshal);
  • 若指定了remoteRef.property,则只返回该 key 对应的原始字符串值
  • 此模式下,Kubernetes Secret 的数据键名(.data.X)由secretKey显式指定,可以自由覆盖命名,例如API_SETTINGSAPI_SETTINGS_TOKEN

配置示例

示例来自 docs/snippets/senhasegura-dsm-external-secret-single.yaml:

apiVersion: 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_TOKEN='example-token-value'

其中API_SETTINGSapi-settings全部键值的 JSON 编码(注意它是数组形式,对应源码中v.Data的类型为[]map[string]string),API_SETTINGS_TOKEN则是TOKEN键的原始字符串。

六、按 Secret Identifier 自动展开多个 key/value

如果应用需要多个密钥,且希望 DSM 中的每个 key/value 自动成为 Kubernetes Secret 的独立.data字段,无需为每个密钥单独编写data条目,可以使用dataFromextract方式,把多个 Secret Identifier 聚合到同一个 ExternalSecret 中。

配置示例

示例来自 docs/snippets/senhasegura-dsm-external-secret-multiple.yaml:

apiVersion: 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为:

URL='https://example.com/api/example' TOKEN='example-token-value' DB_HOST='db.example' DB_PORT='5432' DB_USERNAME='example' DB_PASSWORD='example'

这种模式的优势在于:一个 ExternalSecret 即可聚合多个 Secret Identifier 的所有键值,应用侧无需关心键的重新命名,直接使用原始键名即可。

七、同步模式与底层实现对照

下表汇总了两种同步模式与 senhasegura DSM 客户端源码实现的对应关系,便于排查与理解行为差异:

ExternalSecret 写法底层调用行为源码位置
data+remoteRef.property为空GetSecret返回该 Identifier 全部键值的 JSON 编码dsm/dsm.go
data+remoteRef.property指定键GetSecret返回指定键的原始字符串dsm/dsm.go
dataFrom.extractGetSecretMap该 Identifier 下每个 key/value 展开为独立.data字段dsm/dsm.go
dataFrom.findGetAllSecrets尚未实现(返回errNotImplementeddsm/dsm.go

关于“同步授权下全部密钥”的说明

原文档中注释掉了一段“Sync all secrets from DSM authorization”的示例(使用dataFrom.find: {})。从源码确认,GetAllSecrets目前返回errNotImplemented(dsm/dsm.go),源码注释中也有 TODO 说明该功能未来计划支持按名称正则匹配或标签匹配。因此当前版本请不要使用find方式同步全部密钥,应使用上文基于 Secret Identifier 的data/dataFrom.extract方式。

八、底层 API 与常见问题排查

DSM 数据获取流程

无论是单键还是多键同步,最终都会调用 dsm.go 中的FetchSecrets(),其行为如下:

  1. https://<senhasegura-url>/iso/dapp/application发起GET请求;
  2. 请求头携带Authorization: Bearer <iso token>(Token 来自第二步认证);
  3. 响应体为IsoDappResponse结构(dsm.go),包含application.secrets数组,每个密钥含secret_idsecret_nameidentityversionexpiration_dateengine以及data[]map[string]string);
  4. 非 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.go;
  • SecretStore 状态为 Error:检查 DSM 应用的clientId/clientSecret是否匹配,授权是否正确关联了密钥,以及 ESO 运行环境能否访问 Segura® 地址;
  • 报错cannot do request in senhasegura, SSL certificate is valid ?:通常是 TLS 证书问题。生产环境应确保证书有效;仅在测试环境可临时开启ignoreSslCertificate: true
  • find方式不生效GetAllSecrets尚未实现(见上文),请改用 Secret Identifier 方式;
  • 同步到集群的 Secret 数据与 DSM 不一致:注意refreshInterval决定重新拉取周期(示例中为30s),DSM 侧密钥更新后需等待下一个刷新周期。

九、测试与验证

senhasegura provider 的单元测试位于 providers/v1/senhasegura/provider_test.go,端到端测试用例位于 e2e/suites/provider/senhasegura_dsm_test.go(若该文件不存在,可查看 e2e/suites/provider 目录下以senhasegura命名的用例)。此外,仓库中还提供了可直接用于演练的清单文件:

  • 认证 Secret:docs/snippets/senhasegura-dsm-secret.yaml
  • SecretStore:docs/snippets/senhasegura-dsm-secretstore.yaml
  • ClusterSecretStore:docs/snippets/senhasegura-dsm-clustersecretstore.yaml
  • 单键同步 ExternalSecret:docs/snippets/senhasegura-dsm-external-secret-single.yaml
  • 多键展开 ExternalSecret:docs/snippets/senhasegura-dsm-external-secret-multiple.yaml

建议的验证流程:

  1. 依次应用认证 Secret、SecretStore / ClusterSecretStore;
  2. 检查 Store 的status是否为 Ready(Validate()已连通测试);
  3. 应用 ExternalSecret 后,用kubectl get secret <target-name> -o yaml检查.data字段是否符合预期;
  4. 修改 DSM 中的密钥值,等待refreshInterval后确认 Kubernetes Secret 是否同步更新。

十、总结

通过 senhasegura provider,External Secrets Operator 可以安全、自动地将 Segura® DSM 模块中的密钥同步为 Kubernetes Secret:

  • 认证采用 DSM 应用的 OAuth2client_credentials流程,Client Secret 存放于 Kubernetes Secret 中,避免明文泄漏;
  • 存储支持命名空间级SecretStore与集群级ClusterSecretStore,Store 创建即校验 URL、HTTPS、Client ID 等关键配置;
  • 同步支持按 Secret Identifier 单键取值(data+property)、整份 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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 5:30:21

Agent五层架构落地实操:MCP、A2A与LangGraph工程指南

1. 这不是一张“技术海报”&#xff0c;而是一份Agent产业落地的实操地图如果你最近翻过技术社区、刷过招聘JD、或者参加过几场AI方向的闭门会&#xff0c;大概率已经反复看到这几个词&#xff1a;Agent、MCP、A2A、LangGraph。它们不再只是论文里的概念或Demo中的炫技模块&…

作者头像 李华
网站建设 2026/9/17 5:29:43

Vue3+Node.js构建高性能宠物电商系统实战

1. 项目背景与核心价值作为一名长期从事电商系统开发的全栈工程师&#xff0c;我注意到近年来宠物经济呈现爆发式增长。根据行业调研数据&#xff0c;2022年中国宠物市场规模已突破3000亿元&#xff0c;其中线上宠物用品消费占比超过40%。这个基于Vue的线上宠物商品购物系统正是…

作者头像 李华
网站建设 2026/9/17 5:29:26

一人工作室微信小游戏开发实战:Vibe Coding+原生框架闭环指南

1. 项目概述&#xff1a;为什么一个“一人工作室”能靠微信小游戏跑通从0到1的闭环&#xff1f;“Vibe Gaming 一人工作室微信小游戏开发实战”这个标题里藏着三个关键信号&#xff1a;轻量启动、平台限定、真实交付。它不是“用AI生成100个游戏创意”的概念演示&#xff0c;也…

作者头像 李华
网站建设 2026/9/17 5:29:23

iFly固定翼低空遥感方案:航线规划与相机触发参数设置详解

简介&#xff1a;面向低空经济与无人机测绘应用场景的固定翼低空遥感平台系统应用推荐方案&#xff0c;聚焦iFly U3、U5两款电动固定翼无人机在低空遥感中的工程化落地。方案从项目背景、目的与意义入手&#xff0c;详细介绍了U3的轻便高效、腹部开伞设计以及U5全碳纤维机身、厘…

作者头像 李华
网站建设 2026/9/17 5:29:13

星上路由交换与处理技术解析:从协议栈到FPGA实现

简介&#xff1a;这是一份聚焦星上路由交换与处理技术的专业课件&#xff0c;面向卫星通信、航天信息网络方向的学生、研究者和工程技术人员&#xff0c;用于解决星上信息高效传输与交换体制选择等核心问题。课件系统梳理了星上交换的关键概念、实现方法及典型交换体制&#xf…

作者头像 李华