配置密钥存储
在此页面上
您可以选择存储 Atlas Kubernetes Operator 管理的组件的敏感信息的位置,但 Atlas Kubernetes Operator 必须找到 Kubernetes 密钥 它期望。您可以通过多种方式存储 Atlas Kubernetes Operator 的密钥,包括以下方法:
将敏感信息直接放入 Kubernetes 密钥 中 。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 JSON web token 身份验证。要了解更多信息,请参阅 JSON web token/OIDC 身份验证。
对于 密钥存储 CSI 驱动程序 ,本教程使用 Kubernetes 身份验证。
或者,云提供商的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 运行以下命令以安装密钥存储 CSI HashiCorp Vault 带有 Helm Charts的插件。您无需安装 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/
集群的颁发者必须与.well-known/openid-configuration
的OIDC发现文档中的 URL 匹配。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 中的访问权限。
以下命令为
vault
受众创建JSON web token ( OIDC ) 类型的jwt-kube01-system
角色。 该命令指定sub
用户声明和mongodb-atlas-system
命名空间中的default
Kubernetes 服务帐户作为绑定主题。 此命令将角色与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
命名空间。以下命令为
vault
受众创建JSON web token ( OIDC ) 类型的jwt-kube01-default
角色。 此命令指定sub
用户声明和default
命名空间中的default
Kubernetes 服务帐户作为绑定主题。 此命令将角色与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
它使用Kubernetes 密钥 绑定到 HashiCorp Vault Helm Chart CSI提供商设置的服务帐户。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 中的访问权限。
以下命令在
auth/k8s-kube01
上创建绑定到default
或mongodb-atlas-system
命名空间中Kubernetes服务帐户的k8s-kube01
角色。 此角色与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 使用 Kubernetes 密钥 进行身份验证 引用您的 HashiCorp Vault 。根据部署需要调整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 返回您的数据库部署列表。