如何加密 Git 仓库中的数据库密码并使用 SealedSecret?
解读
在国内云原生落地场景中,CouchDB 的 数据库密码 往往以明文形式写在 Deployment 或 ConfigMap 里,一旦推送到公司自建的 GitLab 或 Gitee 仓库,就会触发 安全合规红线。SealedSecret 是 Bitnami 开源的 Kubernetes 原生解决方案,它用 非对称加密 把 Secret 变成可安全存 Git 的“密封”对象,只有集群内的 Controller 能解密。面试官问这道题,想确认你是否具备 “代码即基础设施” 的安全意识,能否在 离线优先、多主复制 的 CouchDB 场景下,把密码安全地随应用版本一起交付。
知识点
- SealedSecret 架构:由 kubeseal CLI 与集群内 Controller 组成,Controller 持有 TLS 私钥(唯一解密钥匙),CLI 用对应的 公钥 加密。
- 加密范围:可整包加密 Secret 的 data 与 stringData,也支持 模板化 只加密指定字段,方便 CouchDB 镜像拉取时通过 envFrom 注入。
- 密钥轮换:国内金融级客户要求 90 天轮换,SealedSecret 支持 重新密封(re-encrypt)而不重启 CouchDB Pod。
- 离线场景:CouchDB 常在 边缘机房 运行,kubeseal 允许 离线密封——提前把公钥导出到 CI 机器,无需直连集群。
- 多租户隔离:同一仓库不同目录放置 sealed-secret.yaml,配合 GitLab CI 的 rules:if 与 Namespace 级 RBAC,实现 “谁合并、谁部署、谁解密” 的权限链。
答案
步骤一:在本地拿到集群公钥
kubeseal --fetch-cert --controller-name=sealed-secrets-controller --controller-namespace=kube-system > pub-cert.pem
步骤二:创建包含 CouchDB 密码的常规 Secret
kubectl create secret generic couchdb-auth --from-literal=password=**ProdCouch@2024** --dry-run=client -o yaml > couchdb-auth.yaml
步骤三:密封并生成可存 Git 的文件
kubeseal --cert=pub-cert.pem --format=yaml < couchdb-auth.yaml > couchdb-auth-sealed.yaml
步骤四:把 sealed 文件提交到仓库,并在 CouchDB 的 Deployment 中引用
envFrom:
- secretRef:
name: couchdb-auth # 与 SealedSecret 的 metadata.name 保持一致
步骤五:集群侧由 SealedSecret Controller 自动解密为同名 Secret,CouchDB Pod 启动时通过 Downward API 注入环境变量,完成 零明文 交付。
注意:若使用 Helm + GitOps(如 ArgoCD),可把 kubeseal 命令写进 GitLab CI 的 before_script,实现 MR 即密封、合并即部署 的闭环。
拓展思考
- 灾难恢复:若 SealedSecret Controller 的 TLS 私钥 随 etcd 一起丢失,需提前把 master.key 备份到 国密硬件加密机(HSM),并通过 Kubernetes 的 encryption-provider-config 实现 双层加密。
- 密钥分级:CouchDB 的 集群管理员密码 与 应用级数据库密码 应拆分为两个 SealedSecret,配合 OPA Gatekeeper 策略,禁止同一 Namespace 下同时引用两级密码,降低 横向移动 风险。
- 边缘自治:在 “离线优先” 的边缘 K3s 集群,可预先生成 有效期 1 年 的密封证书,随 ISO 镜像 下发;当边缘节点重新连中心云时,通过 SealedSecret 的 annotation 触发 增量轮换,保证 多主复制 场景下的密码一致性。