Kubernetes 自己提供了 secret 这种方式,但其是一种编码方式,而非加密方式,如果需要用版本控制系统(比如 git)来对所有的文件、内容等进行版本控制时,这种用编码来处理敏感信息的方式就显得很不安全了(即使是采用私有库),这一点在实现 GitOps 时,是一个痛点。

Sealed Secrets

Sealed Secrets 充分利用 kuberntes 的高扩展性,通过 CRD 来创建一个 SealedSecret 对象,通过将加密的内容存储在扩展 SealedSecret 对象中,而 SealedSecret 只能够被运行于目标集群上的 controller 解密,其他人员和方式都无法正确解密原始数据。SealedSecret 对象同时又会生成与其名称相同的 secret 对象,随后就可以按照常规方式使用 secret 对象了。最后将加密后的文件直接推送至版本控制系统即可,而不用担心敏感信息被泄漏.

简单来说就是, 我们需要用 YAML 的形式生成一个 Secret,但是我们希望 YAML 自身的内容是加密的,以保证传输过程中,Secret 自身的内容不会被截获,但是同时这个 YAML 还能用于生成我们需要的 Secret。

安装

安装控制器(SealedSecret 只能被运行于目标集群上的 controller 解密)

1
2
# https://github.com/bitnami-labs/sealed-secrets/releases 获取 controller.yaml
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.17.3/controller.yaml

查看 kube-system 下的 controller Pod

1
2
kubectl -n kube-system get pods | grep seal
# sealed-secrets-controller-64b74f67b-4wtj7 1/1 Running 0 153m

安装客户端工具 kubeseal

  • Helm 安装方式
1
2
3
4
helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets
helm repo update sealed-secrets
helm search repo sealed-secrets/sealed-secrets
helm install kubeseal sealed-secrets/sealed-secrets -n kube-system
  • 二进制文件安装方式(推荐)
1
2
# https://github.com/bitnami-labs/sealed-secrets/releases
wget https://github.com/bitnami-labs/sealed-secrets/releases/download/<版本>/kubeseal-<版本>-linux-amd64.tar.gz

使用

  • secret.yaml 示例:
1
2
3
4
5
6
7
8
9
10
apiVersion: v1
data:
username: eGlhb21hZ2U=
password: cGFzc3cwcmQ=
token: MWU0ZGdyNWZncmgzcmZmZ3JodG9ubmhyaHI=
kind: Secret
metadata:
name: seal-test-secret
namespace: test
type: Opaque

将上述内容写入 test-secret.yaml,然后执行如下命令加密(原始 YAML 文件中不允许有 --- 分割线):

1
2
# https://github.com/bitnami-labs/sealed-secrets#sealing-key-renewal
kubeseal --format=yaml < test-secret.yaml > test-seal-secret.yaml
  • 新生成的 test-seal-secret.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
creationTimestamp: null
name: seal-test-secret
namespace: test
spec:
encryptedData:
password: AgA34igvQfDbBcJp5MOZscbZ5tRHoOP9p8yDcShsT5vK0gTMZFZTTmD+QoYpzXzoFsE+cxUY4pjiCjoIRG6/38Yr91KcjSaRseA6cYhZi37kbQLOKnh2znMv7Dsmz0EfXbCOoCLrPidb0+w6jHvoDwyy6GG5qGrUzx3kcPOOa+ZUBi2OmEWqsvK1Crsl/ZY5u0wb/5fZ3jG/UEE07lSpFG4KTsYA0kj6nnYxUKgMLB9O1MNVBwNlvbw975Df7i3THV7TTT57vPrQ+MC5PJ2gOPDx6hVdRjmwN/dJfUIJKxL6f8ItjsIDZKNhQlkN5YE336gfCy8prfJ4ulaXYY7BW79+7mcEH9UTq5kD0QGF+BBvyX5WIB5ZrHhDM0VlNzEdIqCLi8LFytoXAOo23sEj+mAnwGVaCJoCqjrm8c4UDXImheLxuH8h3tkn/5rEjgSCCy8LMSZ9K8vNcC1AdWkBl2bCTD1MUBL1o918MExDLZ3wK01yB+5a1FHEE9N/e67xbKvq4UmodibnWhPe+MVIkB6JjTwJhSvOG51JqlaFHmZ5S/A8CQJczm6aWBJbYBKiOOYBFa+6Zs+wO0U/2GU2S7R9f8+mC/c4ASP5qOh4JWJ5wTqV1xuDwBjh5MIs+eTqpkW1q05MWly2nZUqUY2HdIyeLsUXO+ZfttRUnx5LyFq8KSs/eB9xiiXVcHvtE1lNrDeKGmqhSbU=
token: AgAa48YgDOwfR0qFHJ9zcHewAeWaCwppVcZWmlI6Fd+mqC7rmDcZdwKGpf0xeHww02n2sTltPcRpfqUQaBY7Gg3wVc1iNxiZ0U+lVK7SCwgoxZf6gn7XluRIJ42UJ3LDFLY2DyPd6DG9W+cO6inth6sa4F2ccuiL4EroEd8bblseNd5UXtg6c24ZhxZ36LLFv9UoIM//fpp6/K1yr1sxoaxd2iAUdwpJe9c5VBixBYqR3eY+CA+JG40bxfVzdGCbAYvXn/1iJD51tdZ5f1VySRC5jaZVcXD1YbVz3qKeBD1/V9qxwd72zp8xHzapuod/PHPonJ2I0LDUNUGFAK/WGKobGPp1ruPg1VWQSC7FkFiuHeCUJZatognwpKd3RYynz9c/i7+s8eosOsR/HtWkPXSli1v+2hhsjnV5HPvh53nXUn+eICVZIuQ9Mc/fgLTt46jSizDtI6tb+mKkYrUmRBBQiHEohgcuzWLviSjxHd7fZL/Mqivi0dKYnPANDe+QV06ISG9Zpky1Z3CkeTM+FbbOkH9LvLeb9Ecum5KYfUER6gt6TC3cMds1QF4ZKDe/YI3bJJzZo48BW+NOy2jAg9XxePDfnLNT9lAchovrFpYX+2XYtLSAjJ609cLp0giUDHPlgjeoLJM4Ln2MyN6sFW7oWBc4lE5TVb/pj5Fey58AdjMlu1fIqTVtzj0AQNCQvyxdsXx3p5k=
username: AgC2lIS57DKtWAfTgCZ0fd5Z5KCmf4XRCTp5C4ODmyh5jjzGFo3gsrc+pRInenrM7C6NdgjtNeQUaG1bRmewMbITkEhIRmx+ozRX1XCz2xrRiw7H1laOs37SmXtfMJNI0HdFrvTiSZhvLksIPHpa4QszL0r7LlmDULXuOxwC0+VRuP6wpeytI5d9XXTRgTz3bUdEYv0uUvV1Ncti35BNAnFUnQhflVlY1i/flxq3TdxXJCT1flAJ91IkZ7faPxyNcA++xQsFANHakF/ajqoVtzP/ZXCjra+V8nppwket0IlYIb4Lgy/OGs7ILxqGM0LJeeelyk9HnDuLJTlUlAARVUHIZmeb2gKQZGSVeMgGcAaXS5mAx3k3C4a3b79cVHxGfGfAFuraB8OiRQoD/tOKHQjfI0SZYT58+Yby9Vznmq3urQa6bp/ifKNEIvB/t6r/A+TOVqza/zS9ZtSlh34Aw6kylD8DJ4bGVZWqUbDyuCnLYLIwW/refH8uU7ZwRGX8bZDi89BsvEBpg7wWFA6uKXgcxYbQDc9XyDeSb0BiH/rPhUwOL8/aD1c+Sa7uB3nr1Oi5kbCQNOJJy77FemhFInbkjOkU6H3Hq7a+evFEXfGpPG1kLp/zmopOKy3eMZn6TlWDNBsLmdJTXzXt1LBdcojnRxPX/nwh/ZOLd+mP24V1X1GbCWEYAOjS7GNe7fVccCOMnjkJ1w==
template:
data: null
metadata:
creationTimestamp: null
name: seal-test-secret
namespace: test
type: Opaque
  • 创建 SealedSecret 对象:
1
kubectl -n test apply -f test-seal-secret.yaml
  • 查看 SealedSecret 对象和 Secret:
1
kubectl -n test get SealedSecret,secret
  • 在 Pod 或 Deployment 中使用 seal-test-secret 即可。

解密加密后的 YAML

获取密钥:

1
kubectl get secret -n kube-system -l sealedsecrets.bitnami.com/sealed-secrets-key -o yaml > master.key

进行解密:

1
kubeseal --format=yaml < ${加密后的yaml} --recovery-unseal --recovery-private-key master.key > ori.yaml

重新加密

1
2
3
# https://github.com/bitnami-labs/sealed-secrets#re-encryption-advanced
kubeseal --re-encrypt < ${加密后文件.yaml} > tmp.yaml \
&& mv tmp.yaml ${加密后文件.yaml}