Docs 菜单
Docs 主页
/ /
MongoDB Atlas Kubernetes Operator
/

配置密钥存储

在此页面上

  • Considerations
  • 先决条件
  • 步骤

您可以选择存储 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 集群预配密钥。

以下教程将安装或配置以下工具和选项:

在完成本教程之前,您需要以下工具和配置:

  • 运行 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 配置密钥存储。

1

选择一个密钥预配工具进行安装。

使用 外部密钥操作符 作为密钥配置工具:

  1. 运行以下命令以安装带有 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`
  2. 确保外部密钥成功运行:

    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驱动程序用作密钥预配工具,请执行以下步骤:

  1. 运行以下命令,安装带有 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
  2. 运行以下命令以安装密钥存储 CSI HashiCorp Vault 带有 Helm Charts的插件。您无需安装 HashiCorp Vault 服务器或密钥注入器。

    helm install vault hashicorp/vault \
    --set "server.enabled=false" --set "injector.enabled=false" \
    --set "csi.enabled=true"
  3. 确保密钥存储 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
  4. 确保 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
2

要设立OIDC JSON web token和Kubernetes身份验证:

  1. 运行以下命令,为挂载路径启用OIDC JSON web token身份验证。 如果设置了多个Kubernetes集群,则必须为每个集群的挂载路径启用OIDC JSON web token身份验证。

    vault auth enable -path=jwt-kube01 jwt
  2. 运行以下命令以允许对kube01.internal.io集群上的OIDC发现 URL 进行未经身份验证的访问:

    $ kubectl create clusterrolebinding oidc-reviewer \
    --clusterrole=system:service-account-issuer-discovery \
    --group=system:unauthenticated
  3. 运行以下命令以定向 HashiCorp Vault 信任集群。https://kube01.internal.io/集群的颁发者必须与.well-known/openid-configurationOIDC发现文档中的 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"
  4. 创建策略,允许访问要向集群公开的密钥。

    以下示例创建您在后续步骤中指定的external-secrets策略。

    echo external-secrets-policy.hcl
    path "secret/data/kube01/external-secrets/*" {
    capabilities = ["read"]
    }
  5. 运行命令以创建 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"
  6. 运行命令为外部密钥操作符创建另一个角色,以访问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"
  7. 确保系统服务帐户成功运行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凭证。

  8. 确保为默认服务帐户成功运行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身份验证,请执行以下操作:

  1. 运行以下命令,为挂载路径启用Kubernetes身份验证。 如果设立了多个Kubernetes集群,则必须为每个集群的挂载路径启用Kubernetes身份验证。

    vault auth enable -path=jwt-kube01 kubernetes

    与 Helm 一起安装时,它会自动配置集群角色绑定。

  2. 创建策略,允许访问权限要公开给集群的密钥。

    以下示例创建了在后续步骤中使用的策略vault-secretvault它使用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
  3. 运行以下命令以信任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)
  4. 运行命令以创建 HashiCorp Vault 角色并将Kubernetes服务帐户绑定到该角色,从而限制该服务帐户在 HashiCorp Vault 中的访问权限。

    以下命令在auth/k8s-kube01上创建绑定到defaultmongodb-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"]
    }
  5. 确保系统服务帐户成功运行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)
  6. 确保默认帐户的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)
3

要使用外部密钥操作符预配密钥,请执行以下操作:

  1. 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
  2. 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
  3. 部署引用包含 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命名空间中的 。

  4. 部署引用包含数据库用户档案的密钥的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-userpassword属性填充密钥。

    $ 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
  5. 确保运行以下命令时按预期返回密钥:

    $ kubectl get -n mongodb-atlas-system secrets/mongodb-atlas-operator-api-key
    $ kubectl get -n default secrets/dbuser-password

要使用密钥存储 CSI 预配密钥,请执行以下操作:

  1. 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命名空间中的 。

  2. 运行以下命令,添加挂载所需密钥的 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
  3. 部署引用包含数据库用户凭证的密钥的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-userpassword属性填充密钥。

    $ 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
  4. 运行以下命令以创建secret-placeholder Sentinel Pod,确保密钥存储 CSI驾驶员获取dbuserKubernetes并将其同步到凭证 :

    $ 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
  5. 确保运行以下命令时按预期返回密钥:

    $ kubectl get -n mongodb-atlas-system secrets/mongodb-atlas-operator-api-key
    $ kubectl get -n default secrets/dbuser-password
4

现在,您可以部署 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

要了解有关这些自定义资源的更多信息,请参阅自定义资源。

5

要测试 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 返回您的数据库部署列表。

后退

Atlas 访问