Bitnami Sealed Secrets:K8s 加密 Secret 管理实战(Git 安全存储 Kubernetes 密钥)
在 Kubernetes 集群中管理 Secret 是一个长期困扰运维团队的难题。原生的 Secret 资源仅经过 Base64 编码,本质上是明文存储,直接提交到 Git 仓库存在极大的安全隐患。Bitnami 开源的 Sealed Secrets 项目正是为解决这一问题而生——它允许你将加密后的 Secret 安全地存储在版本控制系统中,真正实现 GitOps 安全闭环。
Sealed Secrets 的工作原理是将敏感数据使用集群中控制器持有的非对称密钥加密,生成 SealedSecret 自定义资源。只有对应集群的 controller 才能解密,攻击者即便拿到 Git 仓库中的 YAML 文件也无法还原原始数据。配合 ArgoCD 或 Flux 等 GitOps 工具,可以构建从代码提交到集群部署的完整自动化链路,且全程不暴露任何敏感信息。
本教程将覆盖 Sealed Secrets 的完整实战流程:从集群安装、kubeseal CLI 使用,到密钥轮换策略和 GitOps 集成实践,帮助团队建立一套可靠的 K8s Secret 管理规范。
环境要求
本教程推荐在雨云服务器 rainyun-com 上搭建实验环境,注册填优惠码 2026off 领 5 折优惠券。推荐配置为 K3s 集群控制节点,选择 2 核 4GB 内存机型,该配置完全满足 K3s 单节点集群及 Sealed Secrets controller 的运行需求。
软件要求:
- K3s v1.28+ 或任意 Kubernetes v1.20+ 集群
- kubectl 已配置好集群访问权限
- Helm v3.12+
- kubeseal CLI(与服务端版本匹配)
- Git 仓库(GitHub/Gitea 均可)
系统要求:
- Ubuntu 22.04 LTS(推荐)
- 磁盘剩余空间 ≥ 20GB
安装
安装 K3s(若尚未安装)
curl -sfL https://get.k3s.io | sh -
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
kubectl get nodes
通过 Helm 安装 Sealed Secrets Controller
helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets
helm repo update
helm install sealed-secrets sealed-secrets/sealed-secrets \
--namespace kube-system \
--set fullnameOverride=sealed-secrets-controller
验证 controller 是否正常运行:
kubectl get pods -n kube-system -l app.kubernetes.io/name=sealed-secrets
# 输出示例:
# NAME READY STATUS RESTARTS AGE
# sealed-secrets-controller-6b9f4d8c9b-xk2p9 1/1 Running 0 2m
安装 kubeseal CLI
# 获取最新版本号
KUBESEAL_VERSION=$(curl -s https://api.github.com/repos/bitnami-labs/sealed-secrets/releases/latest \
| grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
# 下载并安装
curl -OL "https://github.com/bitnami-labs/sealed-secrets/releases/download/${KUBESEAL_VERSION}/kubeseal-${KUBESEAL_VERSION#v}-linux-amd64.tar.gz"
tar -xvzf kubeseal-*.tar.gz kubeseal
sudo install -m 755 kubeseal /usr/local/bin/kubeseal
# 验证
kubeseal --version
核心配置
创建并加密第一个 Secret
首先创建一个普通的 Kubernetes Secret(不要直接提交到 Git!):
kubectl create secret generic my-app-secret \
--from-literal=db-password='S3cur3P@ssw0rd!' \
--from-literal=api-key='abc123xyz456' \
--dry-run=client \
-o yaml > my-secret.yaml
使用 kubeseal 加密:
kubeseal --format yaml \
--controller-name=sealed-secrets-controller \
--controller-namespace=kube-system \
< my-secret.yaml > my-sealed-secret.yaml
生成的 my-sealed-secret.yaml 内容示例:
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: my-app-secret
namespace: default
spec:
encryptedData:
api-key: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq...
db-password: AgAKAAMCAQIwggFiAgEAMIIBWzANBgkq...
template:
metadata:
name: my-app-secret
namespace: default
此文件可以安全地提交到 Git 仓库:
git add my-sealed-secret.yaml
git commit -m "feat: add encrypted app secret"
应用加密后的 Secret
kubectl apply -f my-sealed-secret.yaml
# 验证 Secret 是否被自动解密创建
kubectl get secret my-app-secret -o jsonpath='{.data.db-password}' | base64 -d
作用域控制
kubeseal 支持三种作用域,控制 Secret 的可移植性:
# strict(默认):绑定到特定 namespace 和 name
kubeseal --scope strict < my-secret.yaml > sealed.yaml
# namespace-wide:可在同一 namespace 下任意 name 使用
kubeseal --scope namespace-wide < my-secret.yaml > sealed.yaml
# cluster-wide:集群范围内任意 namespace/name 可用(慎用)
kubeseal --scope cluster-wide < my-secret.yaml > sealed.yaml
实战演练
场景一:数据库连接串管理
# 创建包含多个字段的数据库 Secret
kubectl create secret generic postgres-credentials \
--from-literal=host='db.internal.example.com' \
--from-literal=port='5432' \
--from-literal=username='appuser' \
--from-literal=password='Pg@ssw0rd2026!' \
--from-literal=database='production_db' \
--namespace=production \
--dry-run=client -o yaml | \
kubeseal --format yaml \
--controller-namespace=kube-system \
--controller-name=sealed-secrets-controller \
> postgres-sealed-secret.yaml
场景二:TLS 证书存储
# 加密已有的 TLS Secret
kubectl create secret tls my-tls-secret \
--cert=./tls.crt \
--key=./tls.key \
--dry-run=client -o yaml | \
kubeseal --format yaml > my-tls-sealed-secret.yaml
场景三:从文件加密
# 直接从文件内容加密(不经过 Secret 对象)
kubeseal --raw \
--name my-app-secret \
--namespace default \
--from-file=config.json \
--controller-namespace kube-system
进阶用法
密钥轮换(Key Rotation)
Sealed Secrets controller 默认每 30 天自动生成新的加密密钥对,旧密钥仍会保留用于解密已有的 SealedSecret。如需手动触发轮换:
# 查看当前所有密钥
kubectl get secret -n kube-system \
-l sealedsecrets.bitnami.com/sealed-secrets-key \
-o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.creationTimestamp}{"\n"}{end}'
# 手动触发密钥轮换(重启 controller)
kubectl rollout restart deployment/sealed-secrets-controller -n kube-system
# 轮换后,旧 SealedSecret 仍可正常解密
# 建议在轮换后用新密钥重新加密所有 SealedSecret
备份密钥(极其重要,迁移集群时需要):
kubectl get secret -n kube-system \
-l sealedsecrets.bitnami.com/sealed-secrets-key \
-o yaml > sealed-secrets-keys-backup.yaml
# 在新集群恢复
kubectl apply -f sealed-secrets-keys-backup.yaml
kubectl rollout restart deployment/sealed-secrets-controller -n kube-system
GitOps 集成(ArgoCD)
创建 ArgoCD Application 自动同步 SealedSecret:
# argocd-app-secrets.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: app-secrets
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/your-org/k8s-secrets-repo
targetRevision: main
path: secrets/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
获取公钥用于离线加密
团队成员可以在不访问集群的情况下加密 Secret:
# 导出公钥
kubeseal --fetch-cert \
--controller-name=sealed-secrets-controller \
--controller-namespace=kube-system \
> sealed-secrets-pub.pem
# 离线加密(使用公钥文件)
kubeseal --cert sealed-secrets-pub.pem \
--format yaml < my-secret.yaml > my-sealed-secret.yaml
常见问题
Q:提示 “cannot get sealed secret service” 错误
检查 controller 是否运行,以及 kubeseal 连接的 controller 名称和 namespace 是否正确:
kubectl get svc -n kube-system | grep sealed
kubeseal --controller-name=sealed-secrets-controller \
--controller-namespace=kube-system \
--fetch-cert
Q:解密失败,Secret 一直处于 Error 状态
# 查看 controller 日志
kubectl logs -n kube-system \
-l app.kubernetes.io/name=sealed-secrets --tail=50
# 常见原因:SealedSecret 的 namespace/name 与创建时不匹配(strict 模式)
Q:如何更新已加密的 Secret 中的某个字段
重新生成整个 SealedSecret,kubeseal 不支持增量更新单个字段,必须重新加密完整的 Secret 对象。
Q:迁移到新集群后 SealedSecret 无法解密
需要先将旧集群的密钥备份恢复到新集群,再重启 controller。若旧集群密钥丢失,则必须重新加密所有 SealedSecret。
Q:kubeseal 版本与 controller 版本不匹配
# 查看 controller 版本
kubectl get deployment sealed-secrets-controller \
-n kube-system -o jsonpath='{.spec.template.spec.containers[0].image}'
# 下载对应版本的 kubeseal CLI
Bitnami Sealed Secrets 是 Kubernetes 生态中最成熟的 GitOps Secret 管理方案之一,轻量、无依赖、原生集成。如果你正在寻找一台稳定的服务器来搭建 K3s 集群并实践上述教程,推荐选择雨云服务器 rainyun-com 的 2 核 4GB 机型,注册时填入优惠码 2026off 可领取 5 折优惠券,以极低的成本拥有一台高性能的 K3s 控制节点,让你的 GitOps 安全实践从零开始。
&spm=1001.2101.3001.5002&articleId=162118193&d=1&t=3&u=c890576741204068bcaf5c92789fae80)
1022

被折叠的 条评论
为什么被折叠?



