sops 加密 K8s Secret 管理
bash
macOS
brew install sops
Linux (Debian/Ubuntu)
wget https://github.com/getsops/sops/releases/download/v3.8.1/sops_3.8.1_amd64.deb sudo dpkg -i sops_3.8.1_amd64.deb
### 使用 go install
```bash
go install github.com/getsops/sops/v3/cmd/sops@latest
验证安装:
sops --version
配置加密后端
选择一种加密后端,以下以 PGP 和 age 两种本地端为例。
使用 PGP 密钥
如果没有 GPG 密钥,先生成一个:
gpg --full-generate-key
按提示操作,记住你输入的邮箱,例如 your-email@example.com。
查看密钥指纹:
gpg --list-secret-keys --keyid-format LONG
输出示例:
sec rsa4096/DEADBEEF12345678 2025-01-01 [SC]
uid Your Name <your-email@example.com>
这里的 DEADBEEF12345678 是密钥 ID,可用于 sops 配置,也可以使用邮箱。
使用 age 密钥(更轻量)
安装 age:
# macOS
brew install age
# Linux
wget https://github.com/FiloSottile/age/releases/download/v1.1.1/age-v1.1.1-linux-amd64.tar.gz
tar xzf age-v1.1.1-linux-amd64.tar.gz
sudo mv age/age-keygen /usr/local/bin
sudo mv age/age /usr/local/bin
生成密钥对:
age-keygen -o key.txt
公钥会输出到终端,类似:
# created: 2025-01-01T00:00:00+00:00
# public key: age1ql3z7hjy54pw3hyww5jay63c0q3jdw97sq5y4p4vw7ll6p6qtscqk6k5j
记下公钥字符串 age1...。
创建第一个加密文件
创建一个示例 Kubernetes Secret 明文文件 secret-plain.yaml:
apiVersion: v1
kind: Secret
metadata:
name: my-secret
namespace: default
type: Opaque
data:
username: YWRtaW4= # base64 的 admin
password: cGFzc3dvcmQ= # base64 的 password
使用 PGP 加密
sops --encrypt --pgp YOUR_GPG_FINGERPRINT_OR_EMAIL secret-plain.yaml > secret-encrypted.yaml
使用 age 加密
sops --encrypt --age YOUR_AGE_PUBLIC_KEY secret-plain.yaml > secret-encrypted.yaml
查看加密后的文件:
cat secret-encrypted.yaml
你会发现结构完整,但 data 下面的值已被加密为类似:
data:
username: ENC[AES256_GCM,data:...==,iv:...,tag:...,type:str]
password: ENC[AES256_GCM,data:...==,iv:...,tag:...,type:str]
顶部新增了 sops 元数据:
sops:
kms: []
gcp_kms: []
azure_kv: []
pgp:
- created_at: ...
enc: ...
fp: DEADBEEF12345678
...
解密与查看原始内容
解密文件:
sops --decrypt secret-encrypted.yaml
输出原始明文 YAML。
直接编辑加密文件(自动解密打开、重新加密保存):
sops secret-encrypted.yaml
sops 会调用你默认的编辑器(如 vim),编辑完成后自动加密。
如果只是想修改某个值而不打开编辑器,可以使用 --set 选项:
sops --set 'data.password "newbase64password"' secret-encrypted.yaml
在 Kubernetes 中应用加密的 Secret
由于 kubectl apply 无法直接识别 sops 加密文件,你需要先解密再通过管道应用:
sops --decrypt secret-encrypted.yaml | kubectl apply -f -
若配合 GitOps 工具(如 Flux 或 ArgoCD),通常需要在工具层面集成 sops 解密。
与 Kustomize 集成
推荐使用 kustomize-sops 插件或通过 ksops 来实现。
安装 ksops
# 下载 ksops
export KSOPS_VERSION=v4.2.6
wget https://github.com/viaduct-ai/kustomize-sops/releases/download/${KSOPS_VERSION}/ksops_${KSOPS_VERSION}_Linux_x86_64.tar.gz
tar xzf ksops_${KSOPS_VERSION}_Linux_x86_64.tar.gz
chmod +x ksops
sudo mv ksops /usr/local/bin/
使用 ksops 生成器
创建 kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
generators:
- secrets-generator.yaml
编辑 secrets-generator.yaml:
apiVersion: viaduct.ai/v1
kind: ksops
metadata:
name: secret-generator
files:
- secret-encrypted.yaml
然后运行:
kustomize build --enable-alpha-plugins . | kubectl apply -f -
ksops 会在构建过程中解密 sops 文件。
与 Helm 集成
使用 helm-secrets 插件。
安装:
helm plugin install https://github.com/jkroepke/helm-secrets
加密 values 文件:
helm secrets enc values.yaml
会生成 values.yaml.dec 存放明文,values.yaml 被加密(需同时存在 .sops.yaml 配置或命令行指定)。
安装 chart 时解密:
helm secrets upgrade --install my-release ./chart -f values.yaml
需要在部署环境配置解密密钥(如导入 GPG 私钥或设置 age 密钥),CI/CD 中务必保护私钥安全。
配置 .sops.yaml 文件(推荐)
为了团队统一加密规则,建议在仓库根目录创建 .sops.yaml 配置:
PGP 示例:
creation_rules:
- pgp: "YOUR_GPG_FINGERPRINT_OR_EMAIL"
age 示例:
creation_rules:
- age: "age1ql3z7hjy54pw3hyww5jay63c0q3jdw97sq5y4p4vw7ll6p6qtscqk6k5j"
多环境支持:
creation_rules:
- path_regex: .*staging.*
pgp: "FINGERPRINT_STAGING"
- path_regex: .*prod.*
pgp: "FINGERPRINT_PROD"
- pgp: "FINGERPRINT_DEFAULT"
配置后,加密时只需:
sops -e secret.yaml > secret.enc.yaml