全解:密钥备份、离线解密、kubeseal 实战与控制器多命名空间配置)
Sealed Secrets 技术参考与常见问题FAQ全解密钥备份、离线解密、kubeseal 实战与控制器多命名空间配置【免费下载链接】sealed-secretsA Kubernetes controller and tool for one-way encrypted Secrets项目地址: https://gitcode.com/GitHub_Trending/se/sealed-secrets本文以 Sealed Secrets 官方 Reference 章节即 reference 目录 下汇总的 FAQ为骨架系统讲解 Sealed Secrets 在密钥持久化、灾难恢复、kubeseal 命令行使用、证书自管与控制器命名空间规划等生产场景中的关键问题。读完本文你将掌握如何安全备份与恢复控制器私钥、如何离线解密 SealedSecret、如何用--additional-namespaces扩展控制器管辖范围并理解这些能力背后对应的源码实现路径。参考文档体系导读在 Sealed Secrets 的官方文档站点中Reference 章节由 README.md 作为入口_index.md通过readfile短代码直接引用它它本身是技术资料导航页唯一的实质内容是 FAQ 页面其余资源按用途被组织为Tutorials教程面向第一次接触 Sealed Secrets 的读者见 tutorials 目录以分步方式展示能做什么How-to guides操作指南面向已有经验、目标明确的用户见 howto 目录提供更深度的细节Background背景帮助理解 Sealed Secrets 的架构与加密原理见 background 目录。因此本文后续内容将围绕 faq.md 中列出的九类高频问题逐一展开并结合仓库源码给出实现层面的佐证。数据安全与密钥管理失去集群访问权后还能解密吗不能。Sealed Secrets 的私钥只存放在由控制器管理的 Secret 中除非你对 Kubernetes 对象做了其他备份。项目设计上不存在任何后门——没有用于加密某个 SealedSecret 的私钥就无法解密密文。如果你既无法访问存放加密密钥的 Secret也无法访问集群中已解密的 Secret 明文那么唯一的选择是为所有应用重新生成密码并用新的密封密钥重新 seal。这一结论可以从源码得到印证密钥对由控制器动态生成并以 Secret 形式落盘。在 pkg/controller/keys.go 中定义了定位活动密钥的标签// SealedSecretsKeyLabel is that label used to locate active key pairs used to decrypt sealed secrets. const SealedSecretsKeyLabel sealedsecrets.bitnami.com/sealed-secrets-key而 writeKey 会把生成的 RSA 私钥与证书写入一个GenerateName前缀为sealed-secrets-key、类型为kubernetes.io/tls的 Secret其中tls.key保存 PEM 编码的 PKCS#1 私钥、tls.crt保存证书链并打上sealedsecrets.bitnami.com/sealed-secrets-key: active标签。这些 Secret 就是解密能力的唯一载体因此它们是备份与灾难恢复的核心对象。如何备份 SealedSecrets私钥备份私钥只需在一个拥有足够权限的账号下执行两条命令将标签命中的密钥 Secret 与旧的默认密钥 Secret 一并导出kubectl get secret -n kube-system -l sealedsecrets.bitnami.com/sealed-secrets-key -o yaml main.key echo --- main.key kubectl get secret -n kube-system sealed-secrets-key -o yaml main.key注意事项第二条命令仅在你的集群上安装过0.9.x 之前的旧版本 Sealed Secrets 时才需要旧版本密钥 Secret 不带上述标签需按固定名称导出导出的main.key文件包含控制器的公钥 私钥必须像对待密码本一样妥善保管原文称其为 omg-safe即绝对机密级别。从源码看标签sealedsecrets.bitnami.com/sealed-secrets-key正是 KeyRegistry 管理密钥时使用的keyLabel控制器按该标签从 Secret 列表中筛选并加载密钥对因此按标签导出即可完整覆盖所有代际的密钥。灾后如何恢复将备份的 Secret 放回集群再重启控制器即可标准流程如下kubectl apply -f main.key kubectl delete pod -n kube-system -l namesealed-secrets-controller如果控制器尚未启动可在启动前直接kubectl apply恢复如果控制器已经运行则先 apply 恢复备份的 Secret再删除控制器 Pod 强制其重启让控制器重新加载这些密钥。能用备份密钥离线解密吗虽然官方不推荐把 Sealed Secrets 当作长期密钥存储系统但确实存在合法场景需要“集群宕机 无法快速恢复控制器部署”时的应急恢复能力。此时可以使用 kubeseal 的恢复模式kubeseal --recovery-unseal --recovery-private-key file1.key,file2.key,...其中--recovery-private-key可传入多个文件支持两种格式PEM 编码的私钥文件按本文“如何备份”一节导出的、JSON/YAML 编码的 Kubernetes 控制器密钥 Secret以及v1.List形式的备份。这两个标志在 cmd/kubeseal/main.go 中注册fs.BoolVar(f.unseal, recovery-unseal, false, Decrypt a sealed secrets file obtained from stdin, using the private key passed with --recovery-private-key. Intended to be used in disaster recovery mode.) fs.StringSliceVar(f.privKeys, recovery-private-key, nil, Private key filename used by the --recovery-unseal command. Multiple files accepted either via comma separated list or by repetition of the flag. Either PEM encoded private keys or a backup of a json/yaml encoded k8s sealed-secret controller secret (and v1.List) are accepted. )底层调用链为runCLI检测到--recovery-unseal后调用 kubeseal.UnsealSealedSecret其内部先通过 readPrivKeys 逐个读取私钥文件并按公钥指纹建立映射再解码输入的 SealedSecret 并尝试用这些私钥解开最后以指定的 JSON/YAML 格式输出明文 Secret。在 readPrivKeysFromFile 中可以看到解析顺序先尝试直接按 PEM 私钥解析失败后再依次尝试按v1.List、单个 Secret 的 JSON/YAML 备份格式解析并读取其中的tls.key数据项。这意味着上一节导出的main.key备份文件可以直接喂给--recovery-private-key无需额外转换。kubeseal 命令行与使用场景kubeseal 都有哪些可用参数直接运行以下命令查看完整帮助kubeseal --help结合 cmd/kubeseal/main.go 中的标志注册代码常用参数包括参数默认值说明--cert空指定用于加密的证书/公钥文件或 URL设置后覆盖--controller-*系列参数--controller-namesealed-secrets-controller控制器 Deployment/Service 的名称--controller-namespacekube-system控制器所在命名空间-o, --formatjson输出格式json或yaml-w, --sealed-secret-file空输出文件代替 stdout-f, --secret-file空输入 Secret 文件代替 stdin--fetch-certfalse将控制器证书输出到 stdout便于配合--cert复用--allow-empty-datafalse允许 Secret 对象存在空 data--validatefalse校验密封后的 SealedSecret 可被解密--merge-into空将 items 合并进已有 SealedSecret 文件并原地更新--rawfalse用--from-*系列标志加密裸值而非整个 Secret 对象--name空SealedSecret 名称--raw与默认 strict 作用域下必填--from-file空仅--raw时可用从文件读取 Secret items支持/dev/stdin管道输入--scopestrict密封作用域strict、namespace-wide、cluster-wide--rotate/--re-encryptfalse用最新集群密钥重新加密给定 SealedSecret--rotate已废弃--recovery-unsealfalse从 stdin 读取 SealedSecret 并用--recovery-private-key私钥解密用于灾难恢复--recovery-private-key空恢复模式使用的私钥文件可逗号分隔或重复传参--kubeconfig空kubeconfig 路径集群外使用时需要--helpfalse打印帮助另外kubeseal 还支持通过环境变量注入命令行参数源码中flagEnvPrefix SEALED_SECRETS见 cmd/kubeseal/main.go并通过 flagenv.SetFlagsFromEnv 将SEALED_SECRETS_*形式的环境变量映射为对应标志下划线转连字符这正是下一节“控制器不在 kube-system 命名空间”中SEALED_SECRETS_CONTROLLER_NAMESPACE的由来。如何更新 JSON/YAML/TOML 文件中被密封的部分Kubernetes 的Secret资源本质是扁平的键值对映射Sealed Secrets 只在这一层工作不关心value 里存放的是什么内容——也就是说它无法理解你塞进 Secret 的结构化配置文件因此也不能帮你更新其中某个字段。针对这个处理遗留应用时的高频痛点仓库提供了一个可行变通方案的示例见 docs/examples/config-template思路是把“需要保持密封的敏感字段”与“可以明文修改的结构”分离用一个模板化的配置sealedsecret.yaml与配套的 deployment.yaml 组合使用由应用启动时用真实 Secret 渲染模板从而在保留密封价值的同时获得可编辑性。证书与部署拓扑可以自带预生成证书吗可以。控制器会直接消费你提供的证书而不一定使用自签发的密钥对。具体做法自备证书的完整操作流程见 docs/bring-your-own-certificates.md该文档给出了将自备证书放入控制器、并让 kubeseal 使用对应公钥的完整变通方案。从源码角度控制器加载证书/私钥的入口在 readKey它从 Secret 的tls.key解析私钥必须是 RSA 类型否则返回ErrPrivateKeyNotRSA从tls.crt解析证书链。因此只要你的自备证书以标准的 TLS Secret 形式提供控制器即可直接读取使用。控制器不在 kube-system 命名空间时怎么用 kubeseal如果控制器安装在默认的kube-system之外的其他命名空间必须把该命名空间告诉 kubeseal有两种等价方式命令行参数kubeseal --controller-namespace sealed-secrets mysecret.json mysealedsecret.json环境变量export SEALED_SECRETS_CONTROLLER_NAMESPACEsealed-secrets kubeseal mysecret.json mysealedsecret.json实现上--controller-namespace的默认值是metav1.NamespaceSystem即kube-system见 cmd/kubeseal/main.go而环境变量方式依赖 flagenv 的SEALED_SECRETS_前缀映射机制。kubeseal 会基于该命名空间与控制器 Service 名默认sealed-secrets-controller可由--controller-name覆盖通过 Kubernetes API 代理获取密封证书见 kubeseal.OpenCert 与 getServicePortName——如果 Service 查找失败错误信息会明确提示使用--controller-name和--controller-namespace修正。--cert参数则提供了完全绕过集群、直接用本地证书/URL 加密的路径。如何验证镜像签名Sealed Secrets 的镜像使用 [cosign] 签名签名保存在 GitHub Container Registry路径为ghcr.io/bitnami/sealed-secrets-controller/signs。注意版本差异v0.20.2 及之前的镜像使用 Cosign v1 签名更新的镜像使用 Cosign v2 签名。验证步骤如下# 导出环境变量指定 GHCR 上的签名存放路径 $ export COSIGN_REPOSITORYghcr.io/bitnami/sealed-secrets-controller/signs # 验证 GHCR 上推送的镜像 $ cosign verify --key .github/workflows/cosign.pub ghcr.io/bitnami/sealed-secrets-controller:latest Verification for ghcr.io/bitnami/sealed-secrets-controller:latest -- The following checks were performed on each of these signatures: - The cosign claims were validated - Existence of the claims in the transparency log was verified offline - The signatures were verified against the specified public key ... # 验证 Docker Hub 上推送的镜像 $ cosign verify --key .github/workflows/cosign.pub docker.io/bitnami/sealed-secrets-controller:latest Verification for index.docker.io/bitnami/sealed-secrets-controller:latest -- The following checks were performed on each of these signatures: - The cosign claims were validated - Existence of the claims in the transparency log was verified offline - The signatures were verified against the specified public key ...签名所用的公钥文件位于仓库的.github/workflows/cosign.pub注该路径属于仓库 CI 工作流目录可按需在仓库中查看。如何让一个控制器只管理部分命名空间控制器默认扫描所有命名空间--all-namespaces默认值为true见 cmd/controller/main.go。如果你希望一个控制器管理多个但不是全部命名空间可用--additional-namespaces指定--additional-namespacesnamespace1,namespace2,...前提是必须在目标命名空间中配置好相应的 Role 与 RoleBinding使控制器具备管理其中 Secret 的权限。从实现看该标志在 cmd/controller/main.go 注册处理逻辑位于 pkg/controller/main.go当--all-namespaces为 false 或设置了--additional-namespaces时主 informer 只监听控制器自身所在命名空间myNamespace()随后对列表中的每个额外命名空间逐一校验其存在性不存在的命名空间会记录错误并跳过并为每个命名空间启动一个独立的控制器实例informer reconciler最终由--all-namespaces与--additional-namespaces共同决定控制器的整体覆盖范围。注意列表会被去重removeDuplicates且若某命名空间与主命名空间相同则不会重复启动。总结围绕 Reference 章节 FAQ 所涉及的生产场景可以提炼出四条关键结论私钥即一切控制器私钥只存在于带sealedsecrets.bitnami.com/sealed-secrets-key标签的 TLS Secret 中备份它就是备份整个解密能力务必离线妥善保存恢复有两条路集群可用时用kubectl apply 重启控制器恢复集群不可用时用kubeseal --recovery-unseal --recovery-private-key离线解密且备份文件可直接复用密封边界是键值对SealedSecret 无法感知结构化配置文件内部结构需要模板化变通方案配合拓扑可裁剪通过--controller-namespace/SEALED_SECRETS_CONTROLLER_NAMESPACE定位非默认命名空间的控制器通过--additional-namespaces让单个控制器覆盖指定命名空间子集并配好相应 RBAC。需要深入底层细节时可继续阅读 background 章节 了解加密架构或参考 howto 章节 获取更多操作层面的进阶指南。【免费下载链接】sealed-secretsA Kubernetes controller and tool for one-way encrypted Secrets项目地址: https://gitcode.com/GitHub_Trending/se/sealed-secrets创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考