您可以选择存储Atlas Kubernetes Operator管理的组件的敏感信息的位置,但Atlas Kubernetes Operator必须找到它期望的Kubernetes密钥。您可以通过多种方式存储Atlas Kubernetes Operator的密钥,包括以下方法:
按照 GitOps 流程将敏感信息放入Github存储库。要在 git 中安全地存储敏感数据,您可以使用密封密钥等工具,它可以对预期目标集群的密钥进行加密。
将敏感信息放入外部密钥存储工具中,例如 HashiCorp Vault 或 Hyperscalers原生密钥管理解决方案。中间密钥预配工具从外部密钥存储工具获取敏感信息,并根据敏感信息创建Kubernetes 密钥。要学习;了解有关密钥预配工具的更多信息,请参阅注意事项。
本教程设置一个与 Atlas Kubernetes Operator 一起使用的外部密钥存储工具。 本教程重点介绍“无密钥”设置,即不需要 Atlas Kubernetes Operator 创建和存储密钥来向 Kubernetes 集群预配密钥。
Considerations
以下教程将安装或配置以下工具和选项:
一种密钥预配工具。密钥预配工具使用一种或多种身份验证机制从密钥管理服务中检索凭证,并创建密钥,Atlas Kubernetes Operator可以使用。本教程将安装以下开源密钥预配工具之一:
访问权限密钥的身份验证。您可以使用不同的方法对可以访问权限HashiCorp Vault:中密钥的服务帐户和命名空间进行身份验证:
对于External Secrets Operator,本教程使用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] To learn more about the command syntax and parameters, see the Atlas CLI documentation for atlas kubernetes operator install.
要部署 Atlas Kubernetes Operator,请运行以下命令。将
<version>替换为最新版本号。kubectl apply -f https://raw.githubusercontent.com/mongodb/mongodb-atlas-kubernetes/<version>/deploy/all-in-one.yaml To register for an Atlas account, see Create an Atlas Account.
API keys. You must create an API key and configure the API Access List.
您需要以下公共 API 密钥、私有 API 密钥和组织 ID 信息, 配置 Atlas Kubernetes Operator 对 Atlas 的访问权限。
If you want Atlas Kubernetes Operator to create a new Atlas project, Grant Programmatic Access to an Organization. If your organization requires an IP access list for the Atlas Administration API, you must also configure the API access list.
重要
您必须为 API 密钥分配 Organization Project Creator 或更高级别的组织角色。
If you want to work with an existing Atlas project, Add Project Access from a Project. If your organization requires an IP access list for the Atlas Administration API, you must also configure the API access list.
重要
您必须为 API 密钥分配 Project Owner 项目角色。
一个秘密存储。本教程使用HashiCorp Vault,这是一项用于密钥存储的第三方服务,在
https://vault.internal.io上运行。您可以根据需要将其他密钥存储库与 Atlas Kubernetes Operator 结合使用,包括 AWS、Azure 和 Google 的 Cloud KMS。
仅供内部访问。为防止在公共 Internet 上暴露敏感信息,秘密存储解决方案的以下组件只允许内部访问:
HashiCorp Vault 或KMS服务。
Kubernetes 集群 API 服务。
内部网络。 本教程使用
internal.io。
虽然以前的组件只允许内部访问,但它们允许相互访问,并允许团队或组织内的任何人访问。 这是确保安全的最佳实践。
公共证书颁发机构 (CA) 。 您可以使用公共 CA 来避免管理和分发自定义 CA 根证书。
您可以使用以下任何工具自动执行 CA 证书管理和续订:
在本教程中:
所有
internal.ioHTTPs 服务都是内部地址,但其 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 JWT和 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 Run the following command to direct HashiCorp Vault to trust the cluster. The issuer for the cluster at
https://kube01.internal.io/must match the URL in the OIDC discovery document at.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中的访问权限。
以下命令为
vault受众创建 JSON web token ( OIDC ) 类型的jwt-kube01-system角色。该命令指定sub用户声明和mongodb-atlas-system命名空间中的defaultKubernetes服务帐户作为绑定主题。此命令将角色与 HashiCorp Vault 中的external-secrets策略权限设立绑定。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命名空间中的defaultKubernetes服务帐户作为绑定主题。此命令将角色与 HashiCorp Vault 中的external-secrets策略权限设立绑定。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中的访问权限。
以下命令在
auth/k8s-kube01上创建绑定到default或mongodb-atlas-system命名空间中Kubernetes服务帐户的k8s-kube01角色。此角色与 HashiCorp Vault 中的secrets-store权限策略相关联。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)
设置自动密钥预配。
要使用外部密钥操作符预配密钥,请执行以下操作:
提示
以下示例显示 API 密钥属性 (publicApiKey、privateApiKey)。如果使用服务账户,请将其替换为 clientId 和 clientSecret。要了解更多信息,请参阅使用服务账户配置对 Atlas 的访问权限。
在
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中填充具有以下属性的密钥:orgIdpublicApiKeyprivateApiKey
$ 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 此命令在
mongodb-atlas-system命名空间中创建 Kubernetes 密钥mongodb-atlas-operator-api-key。部署引用包含数据库用户档案的密钥的
ExternalSecret自定义资源。 您必须将spec.target.template.metadata.labels设置为atlas.mongodb.com/type,值为credentials,Atlas Kubernetes Operator 才能找到外部密钥 Operator 创建的密钥。在运行以下命令之前,请确保HashiCorp Vault已在 Kv V2 路径
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 预配密钥,请执行以下操作:
提示
以下示例显示 API 密钥属性 (publicApiKey、privateApiKey)。如果使用服务账户,请将其替换为 clientId 和 clientSecret。要了解更多信息,请参阅使用服务账户配置对 Atlas 的访问权限。
在
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中填充具有以下属性的密钥:orgIdpublicApiKeyprivateApiKey
$ 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 此命令在
mongodb-atlas-system命名空间中创建 Kubernetes 密钥mongodb-atlas-operator-api-key。运行以下命令,添加挂载所需密钥的 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 V2 路径
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-placeholderSentinel 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 返回您的数据库部署列表。