您可以选择存储Atlas Kubernetes Operator管理的组件敏感信息的位置,但Atlas Kubernetes Operator必须找到它所需的Kubernetes 密钥 。您可以通过多种方式存储Atlas Kubernetes Operator的密钥,包括以下方法:
将敏感信息直接放入Kubernetes secrets 中。 Atlas Kubernetes Operator文档中的所有教程默认使用Kubernetes密钥。要使用Kubernetes密钥,请按照教程中的步骤操作。
按照 GitOps 流程将敏感信息放入Github存储库。要在 git 中安全地存储敏感数据,您可以使用密封密钥等工具,它可以对预期目标集群的密钥进行加密。
将敏感信息放入外部密钥存储工具中,例如 HashiCorp Vault 或 Hyperscalers原生密钥管理解决方案。中间密钥预配工具从外部密钥存储工具获取敏感信息,并根据敏感信息创建Kubernetes密钥。要学习;了解有关密钥预配工具的更多信息,请参阅注意事项。
本教程设置一个与 Atlas Kubernetes Operator 一起使用的外部密钥存储工具。 本教程重点介绍“无密钥”设置,即不需要 Atlas Kubernetes Operator 创建和存储密钥来向 Kubernetes 集群预配密钥。
Considerations
以下教程将安装或配置以下工具和选项:
一种密钥预配工具。密钥预配工具使用一种或多种身份验证机制从密钥管理服务中检索凭证,并创建Atlas Kubernetes Operator可以使用的密钥。本教程将安装以下开源密钥预配工具之一:
访问权限密钥的身份验证。您可以使用不同的方法对可以访问权限HashiCorp Vault 中密钥的服务帐户和命名空间进行身份验证:
对于外部密钥操作符,本教程使用 OIDC JWT身份验证。要学习;了解更多信息,请参阅 JWT/OIDC身份验证。
或者,云提供商的KMS可以使用原生IAM系统来提供此身份验证,本教程不介绍此内容。 要了解如何配置云提供商的KMS以进行身份验证,请参阅External Secrets 操作符 文档中的以下资源:
先决条件
在完成本教程之前,您需要以下工具和配置:
运行 Kubernetes、Atlas Kubernetes Operator 和 Atlas 的服务帐户,并有足够的权限来配置它们。
您需要一个正在运行的 Kubernetes 集群,其节点运行的处理器采用 x86-64、AMD64 或 ARM64 架构。 在本教程中,Kubernetes 集群
https://kube01.internal.io
侦听默认端口 (443)。您可以访问 GitHub 上的 Atlas Kubernetes Operator 项目:
要使用 Atlas CLI 安装 Atlas Kubernetes Operator, 请运行以下命令:
atlas kubernetes operator install [options] 要了解有关命令语法和参数的更多信息,请参阅Atlas CLI Atlas Kubernetes Operator安装 的 文档。
要部署Atlas Kubernetes Operator,请运行以下命令。 将
<version>
替换为最新的发布号。kubectl apply -f https://raw.githubusercontent.com/mongodb/mongodb-atlas-kubernetes/<version>/deploy/all-in-one.yaml 要注册 Atlas 帐户,请参阅创建 Atlas 帐户。
API 密钥。 您必须创建 API 密钥并配置 API Access List 。
您需要以下公共 API 密钥、私有 API 密钥和组织 ID 信息, 配置 Atlas Kubernetes Operator 对 Atlas 的访问权限。
如果您希望Atlas Kubernetes Operator创建新的Atlas项目,请为组织授予编程访问权限。如果您的组织需要Atlas Administration API的IP访问列表,您还必须配置API访问权限列表。
重要
您必须为 API 密钥分配 Organization Project Creator 或更高级别的组织角色。
如果要使用现有Atlas项目,请从项目添加项目访问权限。如果您的组织需要Atlas Administration API的IP访问列表,您还必须配置API访问权限列表。
重要
您必须为 API 密钥分配 Project Owner 项目角色。
一个秘密存储。本教程使用 HashiCorp Vault,这是一项用于密钥存储的第三方服务,在
https://vault.internal.io
上运行。您可以根据需要将其他密钥存储库与 Atlas Kubernetes Operator 结合使用,包括 AWS、Azure 和 Google 的 Cloud KMS。
仅限内部访问。 为防止通过公共互联网暴露敏感信息,密钥存储解决方案的以下组件仅允许内部访问:
HashiCorp Vault 或KMS服务。
Kubernetes 集群 API 服务。
内部网络。 本教程使用
internal.io
。
虽然以前的组件只允许内部访问,但它们允许相互访问,并允许团队或组织内的任何人访问。 这是确保安全的最佳实践。
公共证书颁发机构 (CA) 。 您可以使用公共 CA 来避免管理和分发自定义 CA 根证书。
您可以使用以下任何工具自动执行 CA 证书管理和续订:
在本教程中:
所有
internal.io
HTTPs 服务都是内部地址,但其 HTTPS 站点保存由公共 CA 签名的自动续订证书。此集成不需要双向 TLS (mTLS),因为它仅执行服务器端 HTTPS 验证。
客户端可以信任这些服务证书,而无需额外的证书预配。
步骤
请按照以下步骤为 Atlas Kubernetes Operator 配置密钥存储。
在目标集群中安装密钥配置工具。
选择一个密钥预配工具进行安装。
运行以下命令以安装带有 Helm Charts 的外部 Secrets Operator 并启动该服务:
helm repo add external-secrets https://charts.external-secrets.io helm upgrade -i --atomic \ -n external-secrets --create-namespace --set extraArgs.loglevel=debug \ external-secrets external-secrets/external-secrets` 确保外部密钥成功运行:
kubectl get pod -n external-secrets -l app.kubernetes.io/name=external-secrets NAME READY STATUS RESTARTS AGE external-secrets-5779d5d6f6-2lhgd 1/1 Running 0 70s
要将密钥存储 CSI驱动程序用作密钥预配工具,请执行以下步骤:
运行以下命令,安装带有 Helm Charts的密钥存储 CSI驱动程序并启动该服务:
helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts helm upgrade -i --atomic --set syncSecret.enabled=true \ -n kube-system csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver 运行以下命令以安装带有 Helm Charts的密钥存储 CSI HashiCorp Vault 插件。您无需安装 HashiCorp Vault服务器或密钥注入器。
helm install vault hashicorp/vault \ --set "server.enabled=false" --set "injector.enabled=false" \ --set "csi.enabled=true" 确保密钥存储 CSI 成功运行:
kubectl get pod -n kube-system -l app.kubernetes.io/name=secrets-store-csi-driver NAME READY STATUS RESTARTS AGE csi-secrets-store-secrets-store-csi-driver-6dcm8 3/3 Running 0 2m2s 确保 HashiCorp Vault CSI提供商成功运行:
kubectl get pods -l app.kubernetes.io/name=vault-csi-provider NAME READY STATUS RESTARTS AGE vault-csi-provider-j7xbr 2/2 Running 0 5m39s
设置身份验证以访问密钥。
要设立OIDC JSON web token和Kubernetes身份验证:
运行以下命令,为挂载路径启用OIDC JSON web token身份验证。 如果设置了多个Kubernetes集群,则必须为每个集群的挂载路径启用OIDC JSON web token身份验证。
vault auth enable -path=jwt-kube01 jwt 运行以下命令以允许对
kube01.internal.io
集群上的OIDC发现 URL 进行未经身份验证的访问:$ kubectl create clusterrolebinding oidc-reviewer \ --clusterrole=system:service-account-issuer-discovery \ --group=system:unauthenticated 运行以下命令以指示 HashiCorp Vault 信任该集群。
https://kube01.internal.io/
集群的颁发者必须与 的 OIDC 发现文档中的URL匹配。.well-known/openid-configuration
curl https://kube01.internal.io/.well-known/openid-configuration | jq .issuer https://kube01.internal.io/ vault write auth/jwt-kube01/config jwks_url="https://kube01.internal.io/openid/v1/jwks" 创建策略,允许访问要向集群公开的密钥。
以下示例创建您在后续步骤中指定的
external-secrets
策略。echo external-secrets-policy.hcl path "secret/data/kube01/external-secrets/*" { capabilities = ["read"] } 运行以下命令创建 HashiCorp Vault角色,并将Kubernetes服务帐户绑定到该角色,从而限制该服务帐户在 HashiCorp Vault 中的访问权限。
以下命令为
jwt-kube01-system
vault
受众创建 JWT ( OIDC ) 类型的 角色。该命令指定sub
用户声明和 命名空间中的default
Kubernetes服务帐户作为绑定主题。此命令将角色与mongodb-atlas-system
external-secrets
HashiCorp Vault 中的 策略权限设立绑定。vault write auth/jwt-kube01/role/jwt-kube01-system role_type="jwt" bound_audiences=vault \ user_claim="sub" bound_subject="system:serviceaccount:mongodb-atlas-system:default" \ policies="external-secrets" 运行命令为外部密钥操作符创建另一个角色,以访问
default
命名空间。以下命令为
jwt-kube01-default
vault
受众创建 JWT ( OIDC ) 类型的 角色。此命令指定sub
用户声明和 命名空间中的default
Kubernetes服务帐户作为绑定主题。此命令将角色与default
external-secrets
HashiCorp Vault 中的 策略权限设立绑定。vault write auth/jwt-kube01/role/jwt-kube01-default role_type="jwt" bound_audiences=vault \ user_claim="sub" bound_subject="system:serviceaccount:default:default" \ policies="external-secrets" 确保系统服务帐户成功运行OIDC身份验证:
export TEST_JWT_TOKEN=$(kubectl -n mongodb-atlas-system create token default --audience "vault") vault write auth/jwt-kube01/login role=jwt-kube01-system jwt=$(TEST_JWT_TOKEN) Atlas Kubernetes Operator返回系统服务帐户的OIDC JSON web token凭证。
确保为默认服务帐户成功运行OIDC身份验证:
export TEST_JWT_TOKEN=$(kubectl -n default create token default --audience "vault") vault write auth/jwt-kube01/login role=jwt-kube01-default jwt=$(TEST_JWT_TOKEN) Atlas Kubernetes Operator返回默认服务帐户的OIDC JSON web token凭证。
要设立Kubernetes身份验证,请执行以下操作:
运行以下命令,为挂载路径启用Kubernetes身份验证。 如果设立了多个Kubernetes集群,则必须为每个集群的挂载路径启用Kubernetes身份验证。
vault auth enable -path=jwt-kube01 kubernetes 与 Helm 一起安装时,它会自动配置集群角色绑定。
创建策略,允许访问权限要公开给集群的密钥。
以下示例创建了在后续步骤中使用的策略
vault-secret
。它使用vault
,这是一个绑定到 Helm Chart CSI提供商设置的 HashiCorp Vault 服务帐户的Kubernetes密钥。echo vault-secret.yaml apiVersion: v1 kind: Secret metadata: name: vault annotations: kubernetes.io/service-account.name: vault type: kubernetes.io/service-account-token $ kubectl apply -f vault-secret.yaml 运行以下命令以信任Kubernetes集群并使用Kubernetes身份验证:
export VAULT_JWT ?= $(shell kubectl get secret/vault -o jsonpath='{.data.token}' |base64 -d) vault write auth/k8s-kube01/config kubernetes_host="kube01.internal.io" token_reviewer_jwt=$(VAULT_JWT) 运行以下命令创建 HashiCorp Vault角色,并将Kubernetes服务帐户绑定到该角色,从而限制该服务帐户在 HashiCorp Vault 中的访问权限。
以下命令在
k8s-kube01
上创建绑定到auth/k8s-kube01
或 命名空间中Kubernetes服务帐户的default
mongodb-atlas-system
角色。此角色与secrets-store
HashiCorp Vault 中的 权限策略相关联。vault write auth/k8s-kube01/role/k8s-kube01-role \ bound_service_account_names=default,mongodb-atlas-operator \ bound_service_account_namespaces=default,mongodb-atlas-system \ policies=secrets-store 策略必须存在并允许访问权限密钥。 以下示例策略允许访问权限
kube01/secrets-store
路径下的 KV v 2密钥:path "secret/data/kube01/secrets-store/*" { capabilities = ["read"] } 确保系统服务帐户成功运行Kubernetes身份验证:
export TEST_JWT_TOKEN=$( kubectl create -n mongodb-atlas-system token mongodb-atlas-operator) vault write auth/jwt-kube01/login role=jwt-kube01-system jwt=$(TEST_JWT_TOKEN) 确保默认帐户的Kubernetes身份验证成功运行:
export TEST_JWT_TOKEN=$(kubectl -n default create token default) vault write auth/jwt-kube01/login role=jwt-kube01-default jwt=$(TEST_JWT_TOKEN)
设置自动密钥预配。
要使用外部密钥操作符预配密钥,请执行以下操作:
在
mongodb-atlas-system
命名空间中为default
服务帐户部署SecretStore
自定义资源:$ cat external-secrets/vault-system.yaml apiVersion: external-secrets.io/v1beta1 kind: SecretStore metadata: name: vault-store namespace: mongodb-atlas-system spec: provider: vault: server: "https://vault.internal.io" path: "secret" version: "v2" auth: jwt: path: "jwt-kube01" role: "jwt-kube01-system" kubernetesServiceAccountToken: expirationSeconds: 600 serviceAccountRef: name: "default" audiences: - vault $ kubectl apply -f external-secrets/vault-system.yaml 在
default
命名空间中为default
服务帐户部署SecretStore
自定义资源:$ cat external-secrets/vault-default.yaml apiVersion: external-secrets.io/v1beta1 kind: SecretStore metadata: name: vault-store namespace: default spec: provider: vault: server: "https://vault.internal.io" path: "secret" version: "v2" auth: jwt: path: "jwt-kube01" role: "jwt-role" kubernetesServiceAccountToken: expirationSeconds: 600 serviceAccountRef: name: "default" audiences: - vault $ kubectl apply -f external-secrets/vault-default.yaml 部署引用包含 API 密钥的密钥的
ExternalSecret
自定义资源。 您必须将spec.target.template.metadata.labels
设置为atlas.mongodb.com/type
,值为credentials
,Atlas Kubernetes Operator 才能找到外部密钥 操作符 创建的密钥。在运行以下命令之前,请确保 HashiCorp Vault 已在 Kv V2 路径
secret/data/kube01/external-secrets/atlas-account
中填充具有以下属性的密钥:orgId
publicApiKey
privateApiKey
$ cat external-secrets/atlas.yaml apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: name: atlas namespace: mongodb-atlas-system spec: refreshInterval: "15s" secretStoreRef: name: vault-store kind: SecretStore target: name: mongodb-atlas-operator-api-key template: metadata: labels: atlas.mongodb.com/type: credentials data: - secretKey: orgId remoteRef: key: secret/data/kube01/external-secrets/atlas-account property: orgId - secretKey: publicApiKey remoteRef: key: secret/data/kube01/external-secrets/atlas-account property: publicApiKey - secretKey: privateApiKey remoteRef: key: secret/data/kube01/external-secrets/atlas-account property: privateApiKey $ kubectl apply -f external-secrets/atlas.yaml 此命令在 命名空间中创建Kubernetes密钥
mongodb-atlas-operator-api-key
mongodb-atlas-system
。部署引用包含数据库用户档案的密钥的
ExternalSecret
自定义资源。 您必须将spec.target.template.metadata.labels
设置为atlas.mongodb.com/type
,值为credentials
,Atlas Kubernetes Operator 才能找到外部密钥 Operator 创建的密钥。在运行以下命令之前,请确保 HashiCorp Vault 已在 Kv V 路径 中使用2
secret/data/kube01/external-secrets/db-user
password
属性填充密钥。$ cat external-secrets/dbuser.yaml apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: name: dbuser namespace: default spec: refreshInterval: "15s" secretStoreRef: name: vault-store kind: SecretStore target: name: dbuser-password template: metadata: labels: atlas.mongodb.com/type: credentials data: - secretKey: password remoteRef: key: secret/data/kube01/external-secrets/db-user property: password $ kubectl apply -f external-secrets/atlas.yaml 确保运行以下命令时按预期返回密钥:
$ kubectl get -n mongodb-atlas-system secrets/mongodb-atlas-operator-api-key $ kubectl get -n default secrets/dbuser-password
要使用密钥存储 CSI 预配密钥,请执行以下操作:
在
mongodb-atlas-system
命名空间中部署SecretProviderClass
自定义资源。 您必须设立spec.secretObjects.labels
设置为atlas.mongodb.com/type
,值为credentials
, Atlas Kubernetes Operator才能找到密钥存储 CSI 创建的密钥。在运行以下命令之前,请确保 HashiCorp Vault 已在 Kv V2 路径
secret/data/kube01/external-secrets/atlas-account
中填充具有以下属性的密钥:orgId
publicApiKey
privateApiKey
$ cat secrets-store/atlas.yaml apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: atlas namespace: mongodb-atlas-system spec: provider: vault secretObjects: - data: - key: orgId objectName: atlas-org - key: publicApiKey objectName: atlas-pub-key - key: privateApiKey objectName: atlas-secret-key secretName: mongodb-atlas-operator-api-key type: Opaque labels: atlas.mongodb.com/type: credentials parameters: vaultAddress: https://vault.internal.io vaultKubernetesMountPath: k8s-kube01 roleName: k8s-kube01-role objects: | - objectName: atlas-org secretPath: secret/data/kube01/secrets-store/atlas-account secretKey: orgId - objectName: atlas-pub-key secretPath: secret/data/kube01/secrets-store/atlas-account secretKey: publicApiKey - objectName: atlas-secret-key secretPath: secret/data/kube01/secrets-store/atlas-account secretKey: privateApiKey $ kubectl apply -f secrets-store/atlas.yaml 此命令在 命名空间中创建Kubernetes密钥
mongodb-atlas-operator-api-key
mongodb-atlas-system
。运行以下命令,添加挂载所需密钥的 Pod:
$ cat secrets-store/ako-patch.yaml template: spec: containers: - name: system-secret-placeholder image: mongodb/atlas command: ["sleep", "infinity"] volumeMounts: - name: secrets-store-mount mountPath: "/mnt/secrets-store" readOnly: true volumes: - name: secrets-store-mount csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: atlas $ kubectl apply -f secrets-store/ako-patch.yaml 部署引用包含数据库用户凭证的密钥的
SecretProviderClass
自定义资源。 您必须设立spec.target.template.metadata.labels
设置为atlas.mongodb.com/type
(值为credentials
, Atlas Kubernetes Operator才能找到密钥存储 CSI 创建的密钥。在运行以下命令之前,请确保 HashiCorp Vault 已在 Kv V 路径 中使用2
secret/data/kube01/external-secrets/db-user
password
属性填充密钥。$ cat external-secrets/dbuser.yaml apiVersion: external-secrets.io/v1beta1 kind: SecretProviderClass metadata: name: dbuser namespace: default spec: provider: vault secretObjects: - data: - key: password objectName: dbuser secretName: dbuser-password type: Opaque labels: atlas.mongodb.com/type: credentials parameters: vaultAddress: https://vault.internal.io vaultKubernetesMountPath: k8s-kube01 roleName: k8s-kube01-role objects: | - objectName: "dbuser" secretPath: "secret/data/kube01/secrets-store/db-user" secretKey: "password" $ kubectl apply -f secrets-store/dbuser.yaml 运行以下命令以创建
secret-placeholder
Sentinel Pod,确保密钥存储 CSI驾驶员获取dbuser
Kubernetes并将其同步到凭证 :$ cat secrets-store/placeholder.yaml kind: Pod apiVersion: v1 metadata: name: secret-placeholder spec: containers: - image: mongodb/atlas command: ["sleep", "infinity"] name: secret-placeholder volumeMounts: - name: secrets-store-mount mountPath: "/mnt/secrets-store" readOnly: true volumes: - name: secrets-store-mount csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: dbuser $ kubectl apply -f secrets-store/placeholder.yaml 确保运行以下命令时按预期返回密钥:
$ kubectl get -n mongodb-atlas-system secrets/mongodb-atlas-operator-api-key $ kubectl get -n default secrets/dbuser-password
部署 Atlas Kubernetes Operator 自定义资源。
现在,您可以部署Atlas Kubernetes Operator自定义资源。 Atlas Kubernetes Operator引用 HashiCorp Vault 的Kubernetes密钥进行身份验证。根据部署需要调整timeout
值。
kubectl apply -f ako/project.yaml kubectl apply -f ako/deployment.yaml kubectl apply -f ako/user.yaml kubectl wait --for=condition=ready atlasdeployment/serverless-deployment --timeout=10m kubectl wait --for=condition=ready atlasdatabaseuser/user --timeout=10m
要了解有关这些自定义资源的更多信息,请参阅自定义资源。
测试 Atlas Kubernetes Operator 部署。
要测试 Atlas Kubernetes Operator 部署,请运行以下命令:
export ATLAS_DEPLOYMENT_CONN_STR=$(kubectl get secrets/test-atlas-operator-project-test-serverless-deployment-dbuser -o jsonpath='{.data.connectionStringStandardSrv}' |base64 -d) mongosh $(ATLAS_DEPLOYMENT_CONN_STR) --apiVersion 1 --eval "show dbs"
Atlas Kubernetes Operator 返回您的数据库部署列表。