_作者选择DISTICATION in Tech Fund]接受捐赠,作为WRITE FOR DONSITIONS计划)的一部分。
在Kubernetes中,您可以在Pod中使用secrets,以避免将连接字符串和其他敏感数据保留在源代码管理中,或者防止您的应用程序直接访问敏感数据。将机密存储在HashiCorp存储库是一种允许访问所需工具的安全方式)中。秘密存储通常提供诸如HTTPAPI之类的功能来安全地与它们交互。像vault这样的工具通常也提供了与Kubernetes集成的方法,例如通过使用sidecars.然而,这种方法和这些工具与Kubernetes集成的其他方式的一个缺点是,它们通常是特定于应用程序的,并创建了与工具的紧密耦合,您可能希望避免这种情况,以便在需要时可以轻松地切换机密提供程序。
External Secrets Operator(ESO)是一个Kubernetes操作符,它添加了几个自定义资源定义(CRD),并允许您使用原生Kubernetes secrets资源。它通过创建Kubernetes秘密并将其与位于秘密提供商中的指定秘密保持同步来实现这一点,无论是HashiCorp Vault,AWS Secrets Manager,GCP Secrets Manager还是任何其他受支持的提供商。该系统的主要好处是,通过引用本地Kubernetes秘密,任何使用Kubernetes中秘密的服务都与这些工具解耦。这种分离使您可以更轻松地更改支持提供程序,而无需更改任何其他内容。
在本教程中,您将在DigitalOcean管理的Kubernetes集群中安装Extra Secrets运算符,并设置一个SecretStore
和一个ExternalSecres
来从HashiCorp Vault实例取值。
最后,您将拥有一个可以工作的设置,在该设置中,您可以从外部Secrets操作符支持的任何提供者获取要在Kubernetes集群内部使用的秘密。
与任何管理敏感信息的服务一样,在类似生产的环境中使用之前,您应该考虑阅读有关Vault展开最佳做法的其他文档。例如,文件库的生产强化guide涵盖了策略、根令牌和审计等主题。
如果您正在寻找托管Kubernetes托管服务,查看我们为growth.构建的简单托管Kubernetes服务
前提条件
要完成本教程,您需要:
- 一个DigitalOcean帐户。如果您没有,请注册新的account.
- 使用DigitalOcean控制面板设置的Kubernetes群集。要开始,请参阅DigitalOcean Kubernetes指南以创建clusters. +其他设置集群的方法,例如教程如何在Ubuntu 20.04,上使用Kubeadm创建Kubernetes集群]也可以使用,但本教程使用的是控制面板方法。
- 安装了Doctl,您可以按照我们关于如何安装和配置doctl.》的指南进行操作
- 安装在本地机器上的
kubectl
命令行工具,配置为连接到您的集群。您可以在官方documentation](https://kubernetes.io/docs/tasks/tools/install-kubectl/).中阅读更多关于安装kubectl
的内容 - 已安装舵面。有关安装,请参阅我们教程的步骤1如何使用Helm3包Manager.在Kubernetes集群上安装软件
- 安装在您的计算机上的电子仓库,以及您已创建的密钥。要安装保险库并安全地创建机密,请按照我们的教程如何在Ubuntu 20.04.上使用HashiCorp保险库安全管理机密保存在本教程中创建的访问令牌,以便在以后的步骤中使用。 -您可以使用外部机密操作符支持的任何其他提供程序,但本教程将使用HashiCorp Vault。您可以在存储库产品documentation.]中找到提供商列表
第一步-安装外部秘密操作器(ESO)
在本步骤中,您将通过Helm将外部Secrets操作符安装到您的Kubernetes集群中。由于您将使用Helm安装External Secrets操作符,因此需要确保正确设置了Kubernetes上下文。
要进行此设置,首先从您的Kubernetes集群的DigitalOcean Cloud控制面板下载您的Kubeconfig文件。在概述 选项卡中,找到** 配置** 部分,选择** 下载配置文件** 按钮。文件名为<clustername>-kubeconfig.yaml
。您可以将该文件放在任何位置,但建议的位置是~/.kube
文件夹。然后,使用以下命令之一将环境变量KUBECONFIG
设置为等于文件的路径。
在Linux或Mac上,您可以运行以下命令:
1export KUBECONFIG=/home/sammy/.kube/clustername-kubeconfig.yaml
在Windows的PowerShell中,您可以使用以下命令:
1$env:KUBECONFIG = "C:\Users\sammy\.kube\clustername-kubeconfig.yaml"
接下来,通过运行以下命令确认您的当前上下文:
1kubectl config current-context
您的输出将如下所示:
1[label Output]
2my-k8s-cluster
设置好当前上下文后,您可以向Helm添加外部秘密
存储库:
1helm repo add external-secrets https://charts.external-secrets.io
输出将如下所示:
1[label Output]
2"external-secrets" has been added to your repositories
接下来,确保你有最新的回购:
1helm repo update
您的输出将类似于以下内容:
1[label Output]
2...Successfully got an update from the "external-secrets" chart repository
添加完repo后,您可以使用Helm安装您添加的外部机密存储库
:
1helm install external-secrets \
2 external-secrets/external-secrets \
3 -n external-secrets \
4 --create-namespace \
5 --set installCRDs=true
通过-n外部秘密库
选项,可以指定外部秘密库
应该安装在外部秘密库
命名空间中。如果使用--create-nampace
,如果命名空间不存在,则会创建该命名空间。最后,将--set installCRDS
设置为true
,以确保外部秘密的自定义资源定义操作符与其一起安装。
您的输出将如下所示:
1[label Output]
2NAME: external-secrets
3LAST DEPLOYED: {Date goes here}
4NAMESPACE: external-secrets
5STATUS: deployed
6REVISION: 1
7TEST SUITE: None
8NOTES:
9external-secrets has been deployed successfully!
10
11In order to begin using ExternalSecrets, you will need to set up a SecretStore
12or ClusterSecretStore resource (for example, by creating a 'vault' SecretStore).
13
14More information on the different types of SecretStores and how to configure them
15can be found in our Github: https://github.com/external-secrets/external-secrets
在本步骤中,您通过Helm将External Secrets运算符安装到您的Kubernetes集群中,这将允许您创建一个SecretStore
和一个ExternalSecret
。在下一步中,您将创建一个SecretStore
。
Step 2 -创建Secret Store
在本步骤中,您将创建一个SecretStore
,它是外部Secrets运算符用来存储有关如何与给定的秘密提供者通信的信息。但在您使用外部秘密操作符之前,您需要在Kubernetes中添加您的保险库令牌,以便外部秘密操作员可以与秘密提供者通信。
作为先决条件的一部分,您可能已经学习了教程How to Secure Management Secrets with HashiCorp Vault on Ubuntu 20.04,》,该教程生成了一个用于身份验证的存储库令牌。在此步骤中,您可以使用通过解封Vault获得的根令牌(不建议用于生产),也可以使用本教程步骤5中的令牌,该步骤介绍如何在Vault中创建授权策略。
<$>[警告] 警告: 出于本教程的目的,您可以使用初始化Vault时提供的令牌,但不建议将其用于生产。最佳做法是设置更安全的外部机密操作符以供实际使用。您可以阅读存储库产品documentation.]中支持的不同身份验证方法 <$>
您将把这个令牌作为秘密放在Kubernetes中,以便外部Secrets操作员可以使用它与Vault进行通信。您可以通过运行以下命令来执行此操作,并将突出显示的部分替换为您的存储区令牌:
1kubectl create secret generic vault-token --from-literal=token=YOUR_VAULT_TOKEN
您的输出如下所示:
1[label Output]
2secret/vault-token created
您可以通过运行以下命令来验证这一点,该命令将获取default
命名空间中的所有机密(除非您在前面的命令中添加了命名空间,否则您的命名空间将位于该命名空间中):
1kubectl get secrets
输出将如下所示:
1NAME TYPE DATA AGE
2vault-token Opaque 1 2m
创建了此秘密后,您可以开始使用外部秘密操作符。第一步是建立一个SecretStore
,它保存联系秘密提供者的信息,并标识要使用哪个提供者。同一命名空间中的任何外部机密都可以访问机密存储,因此请确保根据需要对您的命名空间进行分段。在本教程中,您将把所有内容都放在default
命名空间中,但对于生产集群,不建议这样做。
使用Nan
或您喜欢的文本编辑器,创建一个ret-store.yaml
文件,并在其中粘贴以下内容。请务必填写特定于您的设置的数据,例如server
字段,这是可以访问您的Vault服务器的端点:
1[label secret-store.yaml]
2apiVersion: external-secrets.io/v1beta1
3kind: SecretStore
4metadata:
5 name: vault-backend
6spec:
7 provider:
8 vault:
9 server: "https://your-domain:8200"
10 path: "kv"
11 version: "v1"
12 auth:
13 tokenSecretRef:
14 name: "vault-token"
15 key: "token"
在Provider
字段下,您可以使用server
字段指定avult
作为提供者,以及在哪里可以找到它。您还可以指定路径kv
,这是您的密钥所在的根路径。如果您按照《存储库先决条件》教程操作,但将您的SecretStore
命名为kv
以外的其他名称,请确保相应地更改该字段。
KV引擎的v1
默认开启。如果您在开启kv
引擎时更改了其在文件库中的版本,您也可以指定版本为v2
。
最后一个字段是auth
部分,您可以通过提供秘密的名称和令牌所在的秘密内部的密钥来指定您之前创建的秘密。要了解有关电子仓库的其他身份验证方法的详细信息,请查看产品documentation.
如果您有兴趣了解更多关于SecretStores
提供的其他配置选项,您可以在外部秘密产品documentation,中找到CRD规范,它包含了所有可以提供的字段,以及Kubernetes添加的其他一些可以在添加后获取的字段。
保存并关闭该文件。
通过运行以下命令创建SecretStore
:
1kubectl apply -f ./secret-store.yaml
此命令将此CRD应用于您的集群并创建对象。您可以通过运行以下命令来查看该对象,该命令将显示Kubernetes内部有关该对象的所有信息:
1kubectl get SecretStore vault-backend -o yaml
您的输出将如下所示:
1[label Output]
2apiVersion: external-secrets.io/v1alpha1
3kind: SecretStore
4metadata:
5 annotations:
6 # Some kubernetes annotations
7 creationTimestamp: # Timestamp of the creation time
8 generation: 1
9 name: vault-backend
10 namespace: default
11 resourceVersion: "12345"
12 uid: # a UID for the resource
13spec:
14 provider:
15 vault:
16 auth:
17 tokenSecretRef:
18 key: token
19 name: vault-token
20 namespace: default
21 path: kv
22 server: https://your-domain:8200
23 version: v1
24status:
25 conditions:
26 - type: Ready
27 status: "False"
28 reason: "ConfigError"
29 message: "SecretStore validation failed"
30 lastTransitionTime: "0000-00-00T00:00:00Z"
如果您成功创建了SecretStore
,您将不会看到status
字段,但如果您看到type:Ready
和Status:
False``,则asones
和Message
字段将提供有关错误的更多信息。一个非常常见的问题是无法创建客户端
。这通常意味着您的客户端的身份验证方法失败了,因为SecretStore
会尝试为您的提供商创建一个客户端来验证一切是否正常。对于本教程中的令牌身份验证方法,请务必检查您的SecretStore
资源是否具有正确的密钥命名空间,以及名称和密钥是否与您创建的内容完全匹配。
疑难解答
根据文件库的设置方式,您在创建SecretStore
时可能会遇到一些错误。其中最常见的是Message:Unable to Valify Store
。这可能是几件事,但有几件事您可以检查,特别是如果您使用必备教程安装了Vault并安全地创建了一个秘密。
首先,您将告诉Vault侦听所有传入的请求,以便您可以通过更改Vault配置文件来远程访问它。如果您遵循了必备的库教程,那么您将更改/etc/vault.d/vault.hcl
文件。
使用Nan
或您喜欢的文本编辑器,打开/etc/vault.d/vault.hcl
进行编辑。在listener
tcp``部分下的配置文件中,检查地址。如果地址为127.0.0.1:8200
,则改为0.0.0.0:8200
,如图:
1[label /etc/vault.d/vault.hcl]
2...
3listener "tcp" {
4 address = "0.0.0.0:8200"
5...
6}
此更改告诉Vault侦听外部连接,以便您可以从外部机密操作符访问它。重新启动Vault(确保再次解封),现在它应该接受外部连接。
第二个问题可能是防火墙阻止端口8200
上的连接,该问题可以通过更新防火墙来修复:
1ufw allow 8200
<$>[警告]
警告: 这将在端口8200
上向全世界开放文件库,如果没有安全防范措施,建议不要生产。请务必阅读文件库生产Hardening],以确保文件库实例已针对不良行为进行了加固。
<$>
在本节中,您在Kubernetes中创建了一个密钥,以保存有关如何向密钥提供者进行身份验证的信息。然后,您创建了一个SecretStore
资源,告诉外部秘密操作员如何联系您的提供商。在下一步中,您将创建一个ExternalSecret
。
第三步-创建外部密钥
在本步骤中,您将创建一个ExternalSecret
,它是External Secrets运算符中的主要资源。ExternalSecret
资源告诉ESO从特定的SecretStore
中获取特定的秘密,以及将信息放在哪里。此资源非常重要,因为它定义了您希望从外部密钥提供程序获取什么密钥、将其放置在何处、使用哪个密钥存储以及同步密钥的频率,以及其他几个选项。
要创建一个ExternalSecret
,首先创建一个名为external-secret.yaml
的文件,并添加以下代码:
1[label external-secret.yaml]
2apiVersion: external-secrets.io/v1alpha1
3kind: ExternalSecret
4metadata:
5 name: my-cool-secret
6spec:
7 refreshInterval: "15s" # How often this secret is synchronized
8 secretStoreRef:
9 name: vault-backend
10 kind: SecretStore
11 target: # Our target Kubernetes Secret
12 name: my-cool-new-secret # If not present, then the secretKey field under data will be used
13 creationPolicy: Owner # This will create the secret if it doesn't exist
14 data:
15 - secretKey: my-cool-new-secret-key
16 remoteRef:
17 key: message # This is the remote key in the secret provider (might change in meaning based on your provider)
18 property: value # The property inside of the secret inside your secret provider
在这里,您创建了一个ExternalSecret
,它引用了上一步中的SecretStore
。在"target)中的位置,包含以下属性:
askKey
:这是您要填充的Kubernetes密钥中的密钥。emoteRef.key
:这是密钥提供者内部的密钥。例如,在Vault中,您可以将机密放置在不同路径中。在这里,您可以使用类似于my文件夹/Coolsecrets/mysecu
这样的值作为值。emoteRef.Property
:这是emoteRef.key
中指定的路径所在秘密中的属性,您想要放在askKey
中指定的key中。
data
字段是YAML中的一个数组,因此您可以指定多个要放入单个Kubernetes密钥中的密钥。外部机密操作符还提供了一些高级模板逻辑,您可以使用它们来构建连接字符串之类的东西,您可以在Products documentation](https://external-secrets.io/v0.4.4/guides-templating/).的[高级模板]部分阅读更多关于这些内容的内容您也可以通过接口外部秘密引用docs.]来阅读ExternalSecres
周围的所有字段和选项
完成后保存并关闭文件。
接下来,使用以下命令创建此资源:
1kubectl apply -f ./external-secret.yaml
在应用它之后,您可以通过运行以下命令来确保一切正常:
1kubectl get ExternalSecret my-cool-secret
您的输出将如下所示:
1[label Output]
2NAME STORE REFRESH INTERVAL STATUS
3my-cool-secret vault-backend 15s SecretSynced
输出确认ExternalSecret
资源创建成功。
疑难解答
如果之前的输出在STATUS
下有`Sync Error‘,请确保您的SecretStore设置正确。您可以通过运行以下命令来查看实际错误:
1kubectl get ExternalSecret my-cool-secret -o yaml
您的输出将类似于以下内容,它将提供有关错误的更多信息:
1[label Output]
2apiVersion: external-secrets.io/v1alpha1
3kind: ExternalSecret
4metadata:
5 name: my-cool-secret
6spec:
7 refreshInterval: "15s"
8 secretStoreRef:
9 name: vault-backend
10 kind: SecretStore
11 target:
12 name: my-cool-new-secret
13 creationPolicy: Owner
14 data:
15 - secretKey: my-cool-new-secret-key
16 remoteRef:
17 key: test-secret
18 property: my-cool
19status:
20 # refreshTime is the time and date the external secret was fetched and
21 # the target secret updated
22 refreshTime: "2019-08-12T12:33:02Z"
23 # Standard condition schema
24 conditions:
25 # ExternalSecret ready condition indicates the secret is ready for use.
26 # This is defined as:
27 # - The target secret exists
28 # - The target secret has been refreshed within the last refreshInterval
29 # - The target secret content is up-to-date based on any target templates
30 - type: Ready
31 status: "True" # False if last refresh was not successful
32 reason: "SecretSynced"
33 message: "Secret was synced"
34 lastTransitionTime: "2019-08-12T12:33:02Z"
在此输出中,您将看到status
字段,可能还会看到一些额外的注释(您可以忽略这些注释,因为它们通常是关于资源的元数据)。在status
部分,您可以看到ExternalSecret
是否已经正确同步,或者是否出了问题。
在本步骤中,您创建了一个ExternalSecret
资源。ExternalSecret资源允许您在您的Secret提供程序中指定要获取的值,以及将它们放在Kubernetes中的位置。有关更多高级功能,您可以查看外部秘密产品documentation.
结论
现在您已经成功地在您的Kubernetes集群中设置了External Secrets运算符,并部署了SecretStore
和ExternalSecret
,您可以部署任何其他您想要的秘密了。
外部秘密操作员还有许多其他功能和自定义资源,允许您以最适合您的需要的方式设置您的Kubernetes集群。此外,HashiCorp Vault不是唯一的提供商,其设置类似于本教程中介绍的内容。您可以从外部机密文档.)了解更多信息
Kubernetes中的这种秘密方法是强大的和可扩展的,因为operator是开源的,并且允许您为秘密使用各种提供者,而不必担心任何使用秘密的特定提供者。
最后,还有其他资源可以探索。其中一个是ExterExternalSecret
,这是External Secrets Operator 0.5.0
版本中新增的。此资源允许您定义一个ExternalSecret
,然后让操作员在与您定义的选择器匹配的每个命名空间中创建此ExternalSecret
。您可以阅读更多关于此功能的信息在产品文档中。另一个资源是SecretterSecretStore
,它允许来自任何命名空间的ExternalSecret
访问它(而普通的SecretStore
只能在它所在的同一命名空间中访问)。