从 Sealed Secrets 迁移到 Infisical:分步指南

infisical 发布于 2025-04-17 阅读 121

本文详细介绍了从 Kubernetes 原生方案 Sealed Secrets 迁移到外部密钥管理平台 Infisical 的全过程。文章对比了两者在安全性、审计能力及动态更新方面的差异,并提供了分步迁移指南,包括 Operator 部署、密钥同步策略(同名覆盖或新名切换)以及 OIDC 认证等进阶配置,旨在帮助 DevOps 团队构建更成熟的 GitOps 密钥管理体系。

什么是 Sealed Secrets?

当我们谈到 Sealed Secrets 时,通常指的是通过 SealedSecret 自定义资源定义(CRD),将外部加密的 secrets 引入 Kubernetes 集群的方法。

其核心思路是,开发者使用 kubeseal CLI,借助 controller 的公钥,对嵌入在标准 Kubernetes Secret manifest 中的 secrets 进行加密。这些 SealedSecrets 只能由运行在目标集群中的 controller 解密。即使是执行封装的人,或者任何有权访问 Git 仓库的人,也无法在没有集群私钥的情况下获取明文 secret。这意味着即使 Git 仓库被攻破,secrets 仍然是安全的。下面是 Sealed Secrets 的 GitOps 工作流概览:

sealed secrets architecture

它的主要优势在于,开发者只需要使用一个 CLI(kubeseal)来加密敏感值,然后就可以安全地将 manifest 提交到 Git。虽然他们需要访问集群来获取公钥,但不需要管理任何外部 secrets 管理系统。当 SealedSecret 被应用到集群时,controller 会负责将其解密为普通的 Kubernetes Secret,而且这个解密过程对用户是透明的。

在 Argo CD 或 Flux 的 GitOps 场景中,SealedSecrets 可以像其他 manifest 一样处理。Argo CD 只需应用 SealedSecret manifest,这意味着 CI/CD pipeline 或 Argo CD 无需访问明文 secrets——解密会在部署时于集群内完成。

最后,controller 还负责加密密钥的轮换,因此无需管理外部的加密密钥系统。对于将 secrets 存储在 Git 中的场景来说,这在开发者体验方面是一个重要优势,因为它让开发者可以专注于编写代码,而不是担心 secrets 管理。

然而,随着 secrets 数量增长或环境复杂度增加,团队通常会发现 Sealed Secrets 已经不再足够。

Sealed Secrets 的局限性

以下是 Sealed Secrets 的一些关键缺点:

  • 安全责任:你需要对 Sealed Secrets controller 及其私钥承担全部责任。如果其中任意一个被攻破,所有 secrets 都会变得脆弱。使用 Sealed Secrets 时,最重要的安全实践之一就是备份 controller 的私钥,最好存放在像 KMS 这样的外部系统中。这就产生了 Git 之外的 secret 管理需求,这与“纯 GitOps”的优势相矛盾,因为包括 secrets 在内的一切都存储在 Git 中。

  • 访问控制有限:Sealed Secrets 是集群级资源,可能会让所有集群用户都能查看所有 secrets。对于多集群环境(dev/staging/prod),你必须为每个集群分别加密 secrets,或者在多个集群之间复用加密密钥。你无法同时兼顾便利性和安全隔离。

  • 审计限制:使用 Sealed Secrets 时,Git 提交只能显示某个 secret 发生了变化,却不能显示具体改了什么。这种方式缺乏全面的审计能力,而命名约定或 commit message 也无法替代这一点。

  • Secret 轮换:虽然 Sealed Secrets 可以轮换自身的加密密钥,但你的应用 secrets 在轮换时仍需要手动重新封装并更新。随着规模扩大,这个过程会变得越来越复杂。

  • 复杂度增长:随着 secrets 数量增多,你最终可能会得到许多大型加密文件,使得跟踪变更和管理访问都变得困难。

迁移到外部 Secrets 管理解决方案的好处

  • Git 中没有 Secrets:你不再需要在仓库中存储哪怕是加密后的 secrets。取而代之的是,你只需要存储一个 stub/reference(例如一个 ExternalSecret 资源)。这消除了有人误提交明文 secret 的风险,也减少了仓库中大型加密 blob 带来的杂乱。

  • 动态更新:在 Sealed Secrets 中,任何 secret 变更都与 Git commit(以及 Argo/Flux CD 同步)绑定。而使用外部 secrets manager 时,你会部署一个指向 secret 的静态引用(如 ExternalSecret CR),然后在外部存储中更新实际的 secret 值。External Secrets 机制会检测到变化,并在不需要新的 Git commit 的情况下更新集群内的 Secret。这将 secret 值与 Git commit 过程解耦。

  • 集中管理与审计:secrets manager 提供一个统一的 UI/CLI,能够管理跨项目和跨环境的所有 secrets。它带有审计日志、基于角色的访问控制和使用跟踪。例如,使用 Infisical 时,你可以看到是谁在什么时候更新了某个 secret,并可以强制执行诸如需要特定审批,或确保 secrets 满足复杂度规则之类的策略。这种中心化管理,比起将 secrets 分散在许多使用不同密钥加密的 Git 仓库中,更容易管理。

  • 灵活性:外部 secrets manager 不局限于 Kubernetes,还可以集成到 DevOps 生命周期的其他环节,从而在一个平台中统一处理基础设施和应用部署所需的 secrets。例如,Infisical 可用于管理运行在 Kubernetes 之外的应用(如 VM 或 serverless functions)的 secrets,也可以通过其 CLI 或 action 集成到 CI/CD(GitHub Actions、GitLab CI 等)中,让你能够通过短期 token、OIDC auth 等方式安全地将 secrets 注入 pipeline。

  • 更多安全选项:相较于所有操作都依赖一个私钥,拥有更多 authentication 安全选项显然更有优势。大多数 secrets management 解决方案都支持现代实践,如短期凭证(通过 OIDC)和 dynamic secrets。例如,你可以配置 Kubernetes service account 或 CI job 通过 OIDC 向 Infisical 进行身份验证,而无需使用长期有效的 API token。这意味着,即使是集群用来获取 secrets 的凭证,也可以自动轮换或被严格限定范围。此外,Infisical 的 Kubernetes Operator 还具备 dynamic secrets 功能(自动生成按计划轮换或过期的 secrets),这超出了静态 SealedSecrets 所能做到的范围。

  • 双向同步与 Secret 推送:Infisical 自身的 operator 独特之处在于,它不仅支持将 secrets 拉取到 Kubernetes,还支持将它们推送回去。例如,如果应用在运行时生成了一个新 key,而你希望把它存回 Infisical,那么一个 InfisicalPushSecret CRD 就可以捕获该 secret 并将其发送到 Infisical。这种双向同步意味着,即使某些 secrets 起源于集群内部,你的外部存储仍然可以保持单一事实来源。

迁移到外部 Secrets 管理解决方案时的关键考虑

在做出迁移之前,评估那些会影响你环境的架构和运维因素非常重要:

  • 你正在为架构引入一个外部服务。这会带来新的依赖,可能需要在你的集群与该服务之间建立可靠连接,无论它是云托管还是自托管。虽然这会为架构增加一个组件,但它也引入了一个专门用于 secrets 管理、且具备增强安全特性的专用系统。

  • 在 SealedSecrets 中,解密 secrets 所需的一切都包含在 Git 仓库和集群里。现在你的工作流将依赖于一个外部系统的可用性。这为你提供了一个实施健壮高可用实践的机会,以保障 secrets 基础设施。大多数解决方案都提供缓存机制,secret 在同步后会保存在本地,确保即使在临时连接问题期间,应用仍能访问已有 secrets。可以把这看作是为你的 secrets 管理基础设施定义明确 SLA 的机会。

  • 与任何第三方服务一样,你需要进行适当的安全审查。这应当推动定期的安全审查,并为基础设施中的所有组件建立正式的评估标准。使用短期凭证、实施严格的 RBAC 策略,以及利用 machine identity token,实际上都可能比手动管理加密密钥更能提升整体安全态势。

  • 你的团队需要将新的 secrets 管理工具纳入现有 GitOps 流程。虽然这意味着变化,但通常也会带来更直观的 secret 处理界面,相比命令行加密工具更易于使用。这一转变也提供了一个理想机会,去在整个组织范围内记录并完善 secrets 管理实践。

  • 外部 secrets 管理解决方案需要额外资源,尤其是在自托管时。云托管版本通常提供分层定价模型,并为小型团队提供免费选项。在评估成本时,也要考虑由专门的 secrets 管理工具带来的运营开销降低、安全性提升和生产力增强等抵消收益。

总而言之,迁移到外部 secrets manager 确实意味着你需要考虑一些新因素,但这些其实并不是问题——它们是改进 secrets 处理方式的机会。这个变化能帮助你制定清晰的 secrets 管理规则,使系统更安全,团队在长期内也更高效。从整体来看,这些工具的目标是让你的工作更轻松,而不是更困难。

从 Sealed Secrets 迁移到 Infisical

既然我们已经讨论了这些考量,现在来深入看看,如何实际切换到像 Infisical 这样的外部 secrets 管理解决方案。好消息是,这个过程出奇地直接,尤其是对于已经熟悉 Kubernetes 的平台工程师来说。该集成可以很好地融入现有 GitOps 工作流,而且只会带来最小的干扰,让你在保持声明式配置方式的同时,获得外部 secrets 管理的所有好处。

从 Sealed Secrets 迁移到 Infisical 涉及两个高层步骤:

  1. 采用 Infisical 进行 secret 存储和分发(部署 Infisical 本身,并集成一种让 Kubernetes 从中获取 secrets 的方法)。
  2. 用指向 Infisical 的引用替换 GitOps 仓库中的 SealedSecrets manifests(并确保所有 secret 数据都已转移到 Infisical)。

第 1 步:设置 Infisical(Cloud 或自托管)

首先,决定你将使用 Infisical Cloud 还是自托管 Infisical。云版本开箱即用——你只需注册并为你的 secrets 创建一个 organization/project。自托管则需要部署 Infisical 的 server(你可以在 Kubernetes 集群中或 VM 上运行它——Infisical 提供了 Helm chart 以便更轻松安装)。

无论哪种方式,你都需要在 Infisical 中创建一个 Project 并定义 Environments(例如 dev、staging、prod)来组织你的 secrets。还要确保根据团队需求在 Infisical 中配置用户访问控制(谁可以查看或编辑 secrets)。

对于自托管版本,部署完成后,请记录 API endpoint URL(它可能是你设置的内部 URL 或自定义域名)。对于 cloud,API endpoint 默认为 https://app.infisical.com/api。这些 endpoint 将被 K8s 集成使用。另外,在 Infisical 中创建一个 Machine Identity——这是供 Kubernetes 集群用于认证的 service account。Infisical 支持一种 “universal” machine identity,它提供 Client ID 和 Client Secret 凭证;它也支持 Kubernetes Auth,其中集群可以使用其 service account token,而不是固定 secret 来进行身份验证。为了简单起见,你可以先使用 Client ID/Secret 方式(尤其是在使用 External Secrets Operator 时),然后再考虑使用 OIDC 以获得更高的安全性。

第 2 步:部署 Kubernetes 集成(Infisical Operator 或 External Secrets Operator)

设置好 Infisical 之后,你需要在两个 Kubernetes operator 中选择一个,来帮助将 secrets 拉入集群。它们各自具有不同的优势,具体取决于你的需求:

该选择哪种集成? 如果你重视完全声明式 GitOps 方法,并希望利用 Infisical 特定的功能,如 push 或 dynamic secrets,那么 Infisical Operator 是理想选择。对于已经在其他 secret provider 上使用 ESO,或者偏好标准化多后端方式的人来说,External Secrets Operator 是自然之选。两种方案都可以通过它们的 CRD(InfisicalSecretExternalSecret + SecretStore)与 Argo CD 无缝集成。

阅读更多:Secure GitOps Workflows: A Practical Guide to Secrets Management

Infisical Operator 方案

通过 其 Helm chart 在你的集群中安装 Infisical Operator。这个 operator 会引入诸如 InfisicalSecret 之类的 CRD,然后你可以把它们添加到 GitOps 仓库中,用于你想同步的每组 secrets。例如,一个 InfisicalSecret CR 可能会指定:“从 Infisical project X、environment Y 拉取 secrets,并可能根据 path 或 labels 进行过滤,然后使用这些值创建一个名为 Z 的 Kubernetes Secret。”

下面是一个 InfisicalSecret 定义示例:

apiVersion: secrets.infisical.com/v1alpha1
kind: InfisicalSecret
metadata:
  name: infisicalsecret-sample
  labels:
    label-to-be-passed-to-managed-secret: sample-value
spec:
  hostAPI: https://app.infisical.com/api
  resyncInterval: 10
  authentication:
    kubernetesAuth:
      identityId: <machine-identity-id>
      serviceAccountRef:
        name: <service-account-name>
        namespace: <service-account-namespace>
  managedKubeSecretReferences:
    - secretName: managed-secret
      secretNamespace: default
      creationPolicy: "Orphan"
      template:
        includeAllSecrets: true
        data:
          NEW_KEY_NAME: "{{ .KEY.SecretPath }} {{ .KEY.Value }}"

这个示例使用 Kubernetes authentication,结合 service account token 和 machine identity。该 CRD 会在 default namespace 中创建一个名为 managed-secret 的 Secret,并包含所连接的 Infisical project/environment 中的所有 secrets。

Infisical Operator 还可以管理 dynamic secretspush secrets 回 Infisical,如果你只是需要只读同步,这可能有些过度。该 operator 需要凭证:在其 Helm values 中,你会配置 Infisical API host(cloud 或 self-host URL)以及认证方式。它支持一种 Kubernetes 原生认证,使用 service account token 和预配置的 Machine Identity(OIDC),这意味着你不一定需要为凭证创建静态 secret。如果使用 OIDC,你会通过 machine identity 的 ID 授予 service account 在 Infisical 中的权限。或者,你也可以将 Client ID/Secret 作为 Kubernetes Secret 提供给 operator,由它用来向 Infisical 的 API 进行身份验证。

阅读关于 如何为你的应用在 Kubernetes 中创建和使用 identities

External Secrets Operator 方案

ESO 是一个被广泛采用的多后端 operator,支持包括 Infisical 在内的许多 secret provider。要实现这种方式:

  1. 在你的集群中安装 ESO(0.6.0+ 版本)
  2. 创建一个 SecretStore 资源,将 Infisical 配置为 provider
  3. 创建引用特定 secrets 或整个路径的 ExternalSecret 资源

SecretStore 定义了你的 authentication 方法,以及要从哪个 Infisical project/environment 拉取。然后你再创建 ExternalSecret 资源,指定要同步哪些 secrets,以及它们在 Kubernetes 中的存储位置。ESO 可以使用模式匹配拉取单个 secret 或整个集合,因此在各种迁移场景中都很灵活。

请参考 ESO 文档 以获取详细的配置示例和最佳实践。

第 3 步:将现有 secrets 从 SealedSecrets 转移到 Infisical

这是一个关键的迁移步骤——你需要确保当前存储在 Git 中(以加密形式)的所有 secret 值都被转移到 Infisical,这样切换后你的应用才能继续正常运行。根据你一直以来如何管理 secrets 的“source of truth”,你有几种策略:

  • 如果你的团队一直离线保存实际的 secret 值(例如保存在密码管理器或安全文件中),你可以通过 UI 或 CLI 手动将它们导入 Infisical。Infisical 按 environment 组织 secrets,每个 secret 都有一个 key 和 value(以及 metadata)。请创建与应用预期完全一致的键名的相应 secrets(例如,如果你的应用期望一个名为 my-app-secret 的 Kubernetes Secret,并带有键 DB_PASSWORD,那么请确保在 Infisical 中为该应用的 project/environment 下创建一条 DB_PASSWORD 条目)。

  • 如果你没有可直接使用的明文值列表,你可以从集群中检索它们(因为 Sealed Secrets 已经创建了 Kubernetes Secrets)。对于每个 SealedSecret,确定其最终生成的 Secret 的 namespace 和名称(通常与 metadata 名称相同,除非被覆盖)。使用 kubectl:例如,kubectl get secret my-app-secret -n <namespace> -o yaml 来获取 secret,并将 base64 值解码为明文。有了这些值之后,再将其填充到 Infisical 中。

  • 如果你有很多 secrets,可以考虑使用 Infisical CLI 或 API 来脚本化导入。Infisical CLI 可以将 secrets 推送到某个 project(例如,你可以使用 infisical secrets set --file="./k8-secrets.yaml")。这个过程可以通过脚本自动化:列出 Git 中所有 SealedSecrets,解析它们的数据键和 secret 名称,然后从集群中获取。但要谨慎:请小心处理这些明文值,并在之后删除任何临时文件。更多内容请阅读 Infisical secrets core command

在这一步结束时,你的应用所需的所有 secret 数据都应该已经存在于 Infisical 中,并按 environment 组织。请再次检查以下问题:你是否在 Infisical 中正确区分了环境(dev vs prod secrets)?SealedSecrets 中的每个 secret key 是否都已在 Infisical 中存在且值正确?这也许是一个好机会,可以清理未使用的 secrets,或者统一命名以保持一致性。

第 4 步:将 Infisical 引用 manifest 添加到 Git,并与 Sealed Secrets 一起部署

在移除 SealedSecrets 之前,你应该先将新的基于 Infisical 的资源添加到 GitOps 配置中并部署它们。这意味着创建第 2 步中所述的 InfisicalSecret manifest 并提交。对于每个之前有 SealedSecret 的应用或组件,都创建一个引用 Infisical 的 InfisicalSecret。你可以让它们指向相同的 Kubernetes Secret 名称,也可以使用新的名称。

  • 选项 A:使用相同的 Secret 名称: 这种方式旨在实现无缝切换。将 InfisicalSecret 配置为写入与现有 Secret 相同的 metadata.name。由于该 Secret 已经存在(来自 SealedSecrets),Infisical Operator 会接管这个现有 secret。InfisicalSecret 会使用 Infisical 中的值更新 Secret 的数据。如果一切设置正确,它本质上会进行同步,并且可能用相同的值覆盖该 Secret(因为这些值是你从集群中取出的,应该一致)。这意味着实际上这个 secret 现在由 Infisical Operator 管理,但你的应用感受不到任何差异。

重要: 请确保在移除 SealedSecret 之前,InfisicalSecret 已经就位,这样 secret 的提供就不会出现空档。Infisical Operator 会创建或更新目标 Secret。

  • 选项 B:使用新的 Secret 名称: 如果你想避免任何潜在冲突,这是一个更安全的方法。你可以创建写入新 Secret 的 InfisicalSecrets(例如 my-app-secret-infisical)。然后你需要更新 Deployment 或 Pod 规范以引用这个新的 secret(更新 envFrom 或 volume 引用)。通过 Argo CD 部署这些应用更改,使应用开始使用新 secret。一旦一切运行正常,你就可以删除旧的 SealedSecret 和旧的 Secret。这种方式没有 operator 与现有 secret 争用的风险,但它确实要求你修改应用 manifest 以使用不同的 secret 名称,这可能更复杂,并且可以按环境逐步完成。

鉴于 Sealed Secrets 和 Infisical Operator 可以共存(它们相互独立运行),一种常见策略是先并行部署 Infisical 集成。在一段时间内,你的集群中会同时存在 SealedSecret 和 InfisicalSecret,可能二者都在生成同一个 Secret(或者生成两个 Secret)。你可以验证 Infisical 同步的 Secret 是否具有正确的数据。方法是在 Infisical Operator 同步后检查 Kubernetes 中的 Secret:kubectl describe secret my-app-secret,查看它是否具有预期的键。还要检查 Infisical Operator 日志中是否有错误。一旦确认无误,如果你选择了新名称,就更新应用以使用 Infisical 管理的 secrets;如果使用相同名称,则可以直接继续。

第 5 步:移除 Sealed Secrets

在确认 Infisical 集成正常工作后,删除 Git 仓库中的 SealedSecret manifest,并卸载 controller。移除过程中要留意潜在问题——由于 owner references,controller 可能会在 SealedSecret 资源被移除时删除底层的 Kubernetes Secrets。如果你的 InfisicalSecret 目标是相同的 Secret 名称,请先在 staging 环境中测试这个流程。

在卸载之前,导出并保存 controller 的私钥,作为以后若发现任何旧 SealedSecrets 时可用于解密的预防措施。

为了增强安全性,可以考虑使用 Kubernetes service account tokens 进行 Infisical 的 OIDC authentication,而不是使用静态凭证。

其他考虑事项

  • 测试与回滚: 先在非生产集群中测试迁移步骤。验证应用是否能够从 Infisical 读取 secrets。如果生产环境中出现问题,回滚基本上就是重新应用 SealedSecret(如果你已经删除了它),并可能重新部署 Sealed Secrets controller。在你对新系统有足够信心之前,请保留这些 manifest 的备份。好消息是,从 Infisical 读取 secrets 不会修改你的应用 pod(除非你使用 CSI driver,在那种情况下它会挂载 volume——但在我们描述的方法中,它是普通 Secrets)。因此,切换 secret 来源不应需要更改应用代码,只需要更改配置。

  • 性能与扩展: Infisical 旨在支持扩展,但你应注意 secrets 同步的频率。Infisical Operator 具有基于轮询的同步能力,你可以进行配置。你可以调整 resync interval,以找到合适的平衡——间隔太短可能会给 Infisical server 带来不必要的负载,而间隔太长则可能延迟 secret 更新。中等的同步间隔(例如每几分钟一次)通常效果不错。另外,如果你有很多 secrets(成千上万),可以考虑将它们组织成多个 InfisicalSecret 资源,而不是一个巨大的资源,这样更便于管理,也能避免触及单个 Kubernetes Secret 的大小限制。

  • 还需要提到 Infisical 支持的第三种选项:CSI driver 集成。这允许 pod 直接将 secrets 挂载为 volume(完全绕过 Kubernetes Secrets 对象)。虽然这可以提升安全性(不会将 secret 存储在 etcd 中),但它与 GitOps 模型的契合度没有那么高(因为 secrets 的存在不会作为 Argo CD 管理的 Kubernetes 对象来体现——它更像是一种运行时配置)。如果你有某些特定应用可以从 CSI 中受益(例如,需要持续更新的 secrets 而无需重启 pod,或者不希望任何 secret 进入 etcd),你可以在迁移到 Infisical 之后逐步为这些应用采用 CSI。CSI driver 需要部署 Infisical 的 CSI provider 并创建 SecretProviderClass 资源。这对大多数场景来说超出了本次迁移的范围,但作为一个高级选项,你可以记住这一点。

结论

从 Sealed Secrets 迁移到 Infisical 可以显著简化 GitOps 工作流中的 secret 管理。你将从 Git 中的加密 blob 模式,转向 Git 中保存引用、而 secrets 外部化管理的模式,从而在 secret 轮换和集中监督方面获得更大的灵活性。Argo CD 和 Helm 都可以通过 Kubernetes operator 与 Infisical 顺畅协作,并且 Infisical 的官方文档 提供了全面的说明。

对于 DevOps 和平台工程师来说,关键收获如下:

  • Infisical 让 secrets 远离你的仓库,并在一个中心化服务中利用强加密和访问控制。 这降低了 secret 泄露的概率,并使审计更容易。对于 SealedSecrets 来说,安全性是不错的,但在规模化场景下管理密钥和人工流程容易出错。

  • Infisical 提供审计日志和单一位置来查看 secret 变更,这可以简化合规报告。相比之下,查看加密 secrets 的 Git commit 历史或分散的 KMS 日志要麻烦得多。

  • 迁移之后,开发者可以通过 Infisical 的 UI 或 CLI 添加或更新 secrets,无需处理加密命令。这可以提升效率,尽管也引入了一个需要学习的新工具。同时,Argo CD 继续以声明式方式管理部署——现在它只是同步 InfisicalSecret 资源,而不是 SealedSecret 资源。

  • 许多任务(secret 轮换、同步到新集群)会变得更容易。如果你启动一个新的 Kubernetes 集群,只需将它指向 Infisical 即可——它可以拉取所需的所有 secrets,而无需你重新加密并应用数十个 SealedSecrets。这与 GitOps 自动化原则一致,让集群能够从一个已知来源自行配置其 secrets。

在进行这次迁移时,你是在顺应更广泛的行业趋势:将专门的 secret 管理解决方案与 GitOps 结合使用。像 Infisical 这样的工具正成为 2025 年 Kubernetes secret 管理 及以后场景中的首选。通过遵循上述步骤和最佳实践,组织可以提升其 GitOps 工作流的安全性和可管理性,确保敏感配置以安全、可审计、云原生的方式进行处理。

  • 原文链接: infisical.com/blog/migra...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~

相关文章

0 条评论