在GitOps中管理Secrets一直是一个麻烦的事情,因为GitOps需要用Git仓库来管理一切部署文件,而Secrets又不是能公开的东西,所以我们需要找一些方法来管理。
常用方法
由于GitOps一般是采取Kubernetes来进行部署的,所以本质就是需要把Secrets放进Kubernetes的Secrets里面,一般有一下几种方式
- 本地执行部署
- 本地保存Secrets的
manifest文件
,Git库里不保存 - 本地保存
.env
文件,利用插件或者脚本生成Secrets的manifest文件
- 本地保存Secrets的
- 加密
- Git库里保存加密的Secrets文件,使用key来解密文件
- CD部署
- 利用环境变量,在CD里注入Secrets
- 云服务商
- 利用类似
HashiCorp’s Vault
的服务,动态获取
- 利用类似
以上方法都有些优点和缺点
- 本地执行部署
- 优点:简单方便
- 缺点:需要人工管理Secrets
- 加密
- 优点:不用到处传Secrets文件,全文件Git库管理
- 缺点:配置麻烦,需要管理key,加密文件公开
- CD
- 优点:不用到处传Secrets文件
- 缺点:只能通过CD进行部署,操作
- 云服务商
- 优点:Secrets中心化管理,获取灵活
- 缺点:还是要管理身份认证的Secrets,可能要交钱
本质就是,要么加密放在Git库里,要么从云动态获取
工具
现在一般有以下的工具来管理(Secret Management)
- Bitnami Sealed Secrets
- GoDaddy Kubernetes External Secrets
- External Secrets Operator
- Hashicorp Vault
- Banzai Cloud Bank-Vaults
- Helm Secrets
- Kustomize secret generator plugins
- aws-secret-operator
- KSOPS
- argocd-vault-plugin
例子
我现在遇到的场景是,我们使用ArgoCD进行部署,同时使用kustomize进行manifest文件的管理,如果使用ArgoCD的话,因为ArgoCD是一直监视着manifest文件的库的,而如果manifest文件的库里面没有Secrets文件的话,那么ArgoCD自然就会执行失败,所以需要采取下面的方式
- 加密放库里
- 云服务商动态获取
对于pull方式的secrets管理,不能限定获取secrets的使用场景,比如只能在CD执行,且需要能够动态获取到secrets。
本次采取加密的方式进行管理,使用sops来加密文件(.env
),sops可以使用多种方式来加密文件,例如
- AWS KMS
- PGP key
- GCP KMS
- Azure Key Vault
- Hashicorp Vault
- …
假设我们采取AWS KMS,且我们ArgoCD也部署在AWS上的话,我们就不需要处理ArgoCD访问KMS的验证。然后对于加密的文件,由于我们采取的是kustomize管理manifest文件,所以使用kustomize-sopssecretgenerator来生成Secret的yaml文件。
通过这样的方式,我们既可以本地执行(如果有KMS权限的话),也可以在CD里执行,同样也可以在ArgoCD里执行。只要能获取到KMS
具体实现
安装
kustomize-sopssecretgenerator需要安装路径安装,kustomize对插件路径有要求,具体可以自己查看官方文档
文件结构
1 | . |
步骤
首先需要准备我们的Secrets文件
application/overlay/prod/.env
1 | FOO=BOO |
创建KMS
记录下KMS的arn,下面写为<aws-kms-arn>
,注意自己设置权限。
设置AWS CLI
设置默认profile或者自己自定义名字,用来访问KMS
加密文件
其实就是使用sops来加密文件,sops需要key才能加密文件,由于我们采取了KMS,有2种方式来指定key,一种是:通过终端,另外一种是:使用.sops.yaml
文件
- 终端
1 | sops --aws-profile <aws-profile> --kms <aws-kms-arn> -e -i application/overlays/prod/.env |
- yaml文件
1 | creation_rules: |
加密过后,加密文件自身会储存加密使用的信息,解密的时候就不需要指定参数了
1 | # 解密 |
设置kustomize-sopssecretgenerator
application/overlay/prod/generator.yaml
1 | apiVersion: goabout.com/v1beta1 |
application/overlay/prod/kustiomization.yaml
1 | apiVersion: kustomize.config.k8s.io/v1beta1 |
生成manifest文件
1 | kustomize build --enable-alpha-plugins application/overlays/prod |
--enable-alpha-plugins
用于允许使用插件,注意kustomize的版本,以前的版本可能是--enable_alpha_plugins
或者是其他的flag
到这一步,如果只需要本地执行,则已经可以kustomize build --enable-alpha-plugins application/overlays/prod | kubectl apply -f -
了,对于ArgoCD,我们还需要设置一些东西
设置ArgoCD
需要对ArgoCD的kustomize设置上flag,通过官方文档 Declarative Setup,我们对argocd-cm.yaml
进行配置
对于ArgoCD本身的部署,我们也采用kustomize的文件进行部署。而不是执行指令,这样可以通过ArgoCD来管理自己(Manage Argo CD Using Argo CD)
1 |
|
这样ArgoCD就知道使用插件了
在ArgoCD里安装kustomize-sopssecretgenerator
更详细参见:Using SopsSecretsGenerator with ArgoCD
application/overlay/sopsSecretsGenerator.yaml
1 | apiVersion: apps/v1 |
awsServiceAccount.yaml
虽然上面说了EKS可以通过role等来访问kms,不过似乎sops不是很支持(或者没设置对)
因为sops会按照加密的方式来解密,所以这里还是用上iam用户来解密
所以加密时不能使用aws_profile,否则解密也会用aws_profile,需要手动把aws_profile清空
1 | apiVersion: apps/v1 |
然后ArgoCD也可以正常获取KMS了
总结
利用加密放在Git库的方式,只要我们能够获取Key,就能够部署,具备很大的灵活性,同时文件啥的还是集中管理,不会过个一年后忘记CD里面设置的Secret是啥样,然后花1个多小时重新设置一遍。但是加密的文件还是公开的,这或许是不好的地方了,配置也相对其他方法更复杂一些,或许以后还能有更好的方法。