使用 SOPS 和 age 在 Git 中管理密钥
在提交之前加密 Kubernetes Secret,并让 Flux 在集群中解密它们。
GitOps 将集群的配置放进 Git,其中也包括 Secret。提交一个普通的 Kubernetes Secret 会把它的值暴露给任何能读取该仓库的人,因为 Secret 数据只是经过了 base64 编码。Flux 的 kustomize-controller 可以解密用 Mozilla SOPS 加密的文件,所以你可以提交加密后的 Secret,并让整个系统都保留在 Git 中。本指南使用 age 密钥,这是最简单的选项。
安装工具并创建密钥
安装 age 和 sops(例如 brew install age sops),然后生成一个密钥对:
age-keygen -o age.agekey
输出文件保存私钥,同时命令会打印公钥(以 age1 开头)。不要把私钥放进 Git。请把它备份到安全的地方,因为一旦丢失,你就无法解密你的密钥了。Flux 2.9 还增加了对 age 后量子密码的支持,如果你的策略有此要求的话。
把私钥交给集群
将私钥作为 Secret 存放在使用它的 Flux Kustomization 所在的同一个命名空间中:
kubectl create secret generic sops-age \
--namespace=flux-system \
--from-file=age.agekey=/dev/stdin < age.agekey
Secret 中的键必须以 .agekey 结尾。在它被安全地存储到别处之后,删除本地的 age.agekey 文件,或将它移到密码管理器中。
在仓库中配置 SOPS
在仓库根目录创建 .sops.yaml,让每个人都以同样的方式加密。把其中的密钥替换为你的公钥:
creation_rules:
- path_regex: .*\.yaml
encrypted_regex: ^(data|stringData)$
age: age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
encrypted_regex 只加密 data 和 stringData 字段,所以清单的其余部分保持可读,以便审查和让 Flux 处理。你可以列出多个 age 接收者(以逗号分隔),这样团队成员和集群密钥都能解密。
加密 Secret
在本地编写 Secret 清单,例如 apps/webapp/db-credentials.yaml:
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
namespace: webapp
stringData:
username: webapp
password: s3cr3t-value
就地加密:
sops --encrypt --in-place apps/webapp/db-credentials.yaml
打开该文件:username 和 password 的值现在是密文,并且添加了一个带有元数据的 sops: 块。现在可以安全地提交它了。之后若要编辑,请运行 sops apps/webapp/db-credentials.yaml,它会在你的编辑器中解密,并在保存时重新加密。要检查你即将提交的内容,请确认其中的值已不再可读。
告诉 Flux 解密
在应用该文件夹的 Flux Kustomization 中添加 decryption 块:
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: webapp
namespace: flux-system
spec:
interval: 10m
sourceRef:
kind: GitRepository
name: flux-system
path: ./apps/webapp
prune: true
decryption:
provider: sops
secretRef:
name: sops-age
提交并推送。在协调期间,kustomize-controller 会在内存中解密该文件,并将一个普通的 Secret 应用到集群。验证:
flux reconcile kustomization webapp --with-source
kubectl get secret db-credentials -n webapp
排查与良好实践
如果 Kustomization 报告解密错误,请检查 sops-age Secret 是否存在于与该 Kustomization 相同的命名空间中,它的键名是否以 .agekey 结尾,以及文件是否是针对匹配的公钥加密的。kubectl describe kustomization webapp -n flux-system 会显示错误。
- 每个环境使用不同的密钥,这样 dev 密钥就无法读取 production 的 Secret。
- 轮换密钥的方法是添加新的接收者,重新加密(
sops updatekeys),然后移除旧的。 - 云 KMS 密钥(AWS KMS、Azure Key Vault、Google Cloud KMS)以及 HashiCorp Vault 或 OpenBao 同样可用,并且避免了分发密钥文件。请通过工作负载身份来配置它们,在平台提供凭据的地方省略
secretRef。 - 如果你更愿意让密钥完全不进入 Git,请使用 External Secrets Operator 从保管库同步它们,让 Flux 只管理
ExternalSecret对象。
热门指南
-
推送与拉取:Flux 如何向 Kubernetes 交付 为什么基于拉取、由 Git 驱动的交付会改变你部署、保障安全和恢复集群的方式。 -
使用 GitRepository 与 Kustomization 部署你的第一个应用 通过 Kustomization 资源将 Flux 指向 Git 中的清单,并观察同步。 -
控制同步行为:间隔、Prune、漂移修正与回滚 决定 Flux 何时应用变更、删除什么、如何暂停它,以及如何撤销一次有问题的部署。 -
使用 Flux 镜像自动化实现镜像更新自动化 让 Flux 检测新的容器镜像标签,并将其提交回 Git。 -
使用 Flux 配置多集群 从一个仓库管理多个集群,包含共享基础设施和每个集群各自的差异。 -
Flux CD 与 Argo CD:如何选择 GitOps 工具 比较架构、UI、Helm、密钥、租户和镜像自动化,以选出合适的工具。