对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

多集群部署先决条件

在使用快速入门或部署过程创建多 Kubernetes集群MongoDB 部署之前,请完成以下任务。

要学习;了解有关快速入门特定先决条件的更多信息,请参阅快速入门先决条件。

请参阅支持的硬件架构。

克隆MongoDB Controllers for Kubernetes Operator存储库:

git clone https://github.com/mongodb/mongodb-kubernetes.git

使用部署集群的集群名称设置环境变量,如下示例:

export MDB_CENTRAL_CLUSTER_FULL_NAME="mdb-central"
export MDB_CLUSTER_1_FULL_NAME="mdb-1"
export MDB_CLUSTER_2_FULL_NAME="mdb-2"
export MDB_CLUSTER_3_FULL_NAME="mdb-3"

安装以下工具:

  1. 安装Go 1v.17 或更高版本。

要使用多 Kubernetes 集群 MongoDB 部署,您必须拥有一设立特定的 Kubernetes 角色、ClusterRolesRoleBindings、ClusterRoleBindingsServiceAccounts,您可以通过以下任一方式进行配置:

  • 按照多 Kubernetes 集群快速入门进行操作,该入门介绍如何使用MongoDB插件自动创建所需的对象,应用它们应用到多 Kubernetes集群MongoDB 部署中的相应集群。

  • 使用 Helm 为每个成员集群配置所需的Kubernetes角色和服务帐户:

    helm template --show-only \
    templates/database-roles.yaml \
    mongodb/mongodb-kubernetes \
    --set namespace=mongodb | \
    kubectl apply -f - \
    --context=$MDB_CLUSTER_1_FULL_NAME \
    --namespace mongodb
    helm template --show-only \
    templates/database-roles.yaml \
    mongodb/mongodb-kubernetes \
    --set namespace=mongodb | \
    kubectl apply -f - \
    --context=$MDB_CLUSTER_2_FULL_NAME \
    --namespace mongodb
    helm template --show-only \
    templates/database-roles.yaml \
    mongodb/mongodb-kubernetes \
    --set namespace=mongodb | \
    kubectl apply -f - \
    --context=$MDB_CLUSTER_3_FULL_NAME \
    --namespace mongodb
  • 手动创建 Kubernetes 对象.yaml文件,并使用kubectl apply命令将所需的 Kubernetes 角色和服务帐户添加到多 Kubernetes 集群 MongoDB 部署中。 这对于某些高度自动化的工作流程可能是必要的。 MongoDB 提供了示例配置文件。

    对于作用域为命名空间子集的自定义资源:

    对于范围为集群范围命名空间的自定义资源:

    每个文件定义多个资源。 为了支持您的部署,您必须替换以下字段中的占位符值:

    • subjects.namespace 在每个RoleBindingClusterRoleBinding资源中

    • metadata.namespace 在每个ServiceAccount资源中

    修改定义后,对每个文件运行以下命令来应用这些定义:

    kubectl apply -f <fileName>

By default, the multi-cluster Kubernetes Operator is scoped to the namespace in which you install it. The Kubernetes Operator reconciles the MongoDBMultiCluster resource deployed in the same namespace as the Kubernetes Operator.

当您在 多集群快速 入门中运行 MongoDB kubectl 插件 ,并且不修改kubectl mongodb 插件设置时,该插件:

  • 创建一个名为mongodb-kubernetes-operator-member-list的默认ConfigMap,其中包含多 Kubernetes集群MongoDB 部署的所有成员集群。 此名称是硬编码的,无法更改。 请参阅已知问题。

  • 在操作符集群和每个成员集群中创建 ServiceAccountsRoles、ClusterRolesRoleBindings 和 ClusterRoleBindings

  • 为服务帐户应用正确的权限。

  • 使用前面的设置创建多 Kubernetes 集群 MongoDB 部署。

一旦Kubernetes Operator 创建了多 Kubernetes集群MongoDB 部署, Kubernetes Operator 就会开始监视 MongoDB 资源在 mongodb 命名空间

要为 Kubernetes 操作符配置正确的权限以在子集或所有命名空间中进行部署,请运行以下命令并指定您希望 Kubernetes 操作符监视的命名空间。

kubectl mongodb multicluster setup \
--central-cluster="${MDB_CENTRAL_CLUSTER_FULL_NAME}" \
--member-clusters="${MDB_CLUSTER_1_FULL_NAME},${MDB_CLUSTER_2_FULL_NAME},${MDB_CLUSTER_3_FULL_NAME}" \
--member-cluster-namespace="mongodb2" \
--central-cluster-namespace="mongodb2" \
--create-service-account-secrets \
--cluster-scoped="true"

当您将多 Kubernetes集群MongoDB 部署安装到多个或所有命名空间时,您可以将Kubernetes Operator 配置为:

注意

安装和设置单个 Kubernetes Operator 实例,并将其配置为监视不同的、不重叠的命名空间子集中的一个、多个或所有自定义资源。 另请参阅MongoDB 是否支持运行多个 Kubernetes 操作符 实例?

If you set the scope for the multi-Kubernetes cluster MongoDB deployment to many namespaces, you can configure the Kubernetes Operator to watch MongoDB resources in these namespaces in the multi-Kubernetes cluster MongoDB deployment.

将MongoDB Controllers for Kubernetes Operator Github存储库中的mongodb-kubernetes.yaml文件中的 spec.template.spec.containers.name.env.name:WATCH_NAMESPACE 设置为您希望Kubernetes Operator 监视的以逗号分隔的命名空间列表:

WATCH_NAMESPACE: "$namespace1,$namespace2,$namespace3"

运行以下命令,并将最后一行中的值替换为您希望Kubernetes Operator 监视的命名空间。

helm upgrade \
--install \
mongodb-kubernetes-operator-multi-cluster \
mongodb/mongodb-kubernetes \
--namespace mongodb \
--set namespace=mongodb \
--version <mongodb-kubernetes-operator-version>\
--set operator.name=mongodb-kubernetes-operator-multi-cluster \
--set operator.createOperatorServiceAccount=false \
--set operator.createResourcesServiceAccountsAndRoles=false \
--set "multiCluster.clusters={$MDB_CLUSTER_1_FULL_NAME,$MDB_CLUSTER_2_FULL_NAME,$MDB_CLUSTER_3_FULL_NAME}" \
--set operator.watchNamespace="$namespace1,$namespace2,$namespace3"

If you set the scope for the multi-Kubernetes cluster MongoDB deployment to all namespaces instead of the default mongodb namespace, you can configure the Kubernetes Operator to watch MongoDB resources in all namespaces in the multi-Kubernetes cluster MongoDB deployment.

Set the spec.template.spec.containers.name.env.name:WATCH_NAMESPACE in mongodb-kubernetes.yaml to "*". You must include the double quotation marks (") around the asterisk (*) in the YAML file.

WATCH_NAMESPACE: "*"

运行以下命令:

helm upgrade \
--install \
mongodb-kubernetes-operator-multi-cluster \
mongodb/mongodb-kubernetes \
--namespace mongodb \
--set namespace=mongodb \
--version <mongodb-kubernetes-operator-version>\
--set operator.name=mongodb-kubernetes-operator-multi-cluster \
--set operator.createOperatorServiceAccount=false \
--set operator.createResourcesServiceAccountsAndRoles=false \
--set "multiCluster.clusters={$MDB_CLUSTER_1_FULL_NAME,$MDB_CLUSTER_2_FULL_NAME,$MDB_CLUSTER_3_FULL_NAME}" \
--set operator.watchNamespace="*"

服务网格可实现不同Kubernetes集群中部署的副本集成员之间的集群间通信。 使用服务网格可大幅简化创建多 Kubernetes集群MongoDB部署的过程,是跨多个Kubernetes集群部署MongoDB的推荐方法。 但是,如果您的 IT组织不使用服务网格,您可以在没有服务网格的多 Kubernetes集群MongoDB 部署中部署副本集。

根据您的环境,执行以下操作:

无论哪种部署类型,Kubernetes 中的 MongoDB 部署都必须建立以下连接:

  • 从 Pod 中的 Ops Manager MongoDB Agent 到其mongod进程,以启用 MongoDB deployment 的生命周期管理和监控。

  • 从 Pod 中的 Ops Manager MongoDB Agent 到 Ops Manager 实例,以启用自动化。

  • 在所有mongod进程之间,以允许复制。

当 Kubernetes Operator 部署 MongoDB 资源时,它会根据部署类型,通过以下方式处理这些连接要求:

  • In a single Kubernetes cluster deployment, the Kubernetes Operator configures hostnames in the replica set as FQDNs of a Headless Service. This is a single service that resolves the DNS of a direct IP address of each Pod hosting a MongoDB instance by the Pod's FQDN, as follows: <pod-name>.<replica-set-name>-svc.<namespace>.svc.cluster.local.

  • 在使用服务网格的多 Kubernetes集群MongoDB 部署中, Kubernetes Operator 为Kubernetes集群中的每个MongoDB副本集成员创建一个单独的 StatefulSet。 服务网格允许不同Kubernetes集群的mongod进程之间进行通信。

    通过使用服务网格,多 Kubernetes集群MongoDB 部署可以:

    • Achieve global DNS hostname resolution across Kubernetes clusters and establish connectivity between them. For each MongoDB deployment Pod in each Kubernetes cluster, the Kubernetes Operator creates a ClusterIP service through the spec.duplicateServiceObjects: true configuration in the MongoDBMultiCluster resource. Each process has a hostname defined to this service's FQDN: <pod-name>-svc.<namespace>.svc.cluster.local. These hostnames resolve from DNS to a service's ClusterIP in each member cluster.

    • 在不同 Kubernetes 集群中的 Pod 之间建立通信。 因此,托管在不同集群上的副本集成员形成了跨这些集群的单个副本集。

  • 在没有服务网格的多 Kubernetes集群MongoDB 部署中, Kubernetes Operator 使用以下MongoDBMultiCluster资源设置向外部公开其所有mongod进程。 这样就可以对不同Kubernetes集群之间的主机名进行 DNS 解析,并在通过连接这些集群的网络路由的 Pod 之间建立连接。

使用 Istio 文档在不同网络上以多主节点模式安装 Istio。Istio 是一个服务网格,可简化 DNS 解析并帮助在多 Kubernetes集群MongoDB 部署中的成员Kubernetes集群之间建立集群间通信。如果选择使用服务网格,则需要安装它。如果您无法使用服务网格,请跳过本节并使用外部域并配置 DNS 以启用外部连接。

此外,我们还提供了 install_istio_separate_network 示例脚本 。此脚本基于 Istio 文档,并提供了 在不同网络上使用多主模式 的示例安装 。我们不保证未来的 Istio 版本能够维护该脚本。 如果您选择使用脚本,请查看最新的 Istio 文档,了解如何 安装多 集群 ,并根据需要调整脚本以匹配文档和您的部署。如果您使用其他服务网格解决方案,请创建自己的脚本来配置单独的网络,以便于 DNS 解析。

如果您不使用服务网格,请执行以下操作以启用与mongod进程和 Ops Manager MongoDB 代理之间的外部连接以及之间的外部连接:

  • 创建多 Kubernetes集群MongoDB 部署时,请使用spec.clusterSpecList.externalAccess.externalDomain 设置指定外部域,并指示Kubernetes Operator 按以下模式为mongod进程配置主机名:

    <pod-name>.<externalDomain>

    注意

    只能为新部署指定外部域。 配置多 Kubernetes集群MongoDB 部署后,无法更改外部域。

    以这种方式配置外部域后,Ops Manager MongoDB 代理和mongod进程将使用此域相互连接。

  • 自定义 Kubernetes Operator 为 Kubernetes 集群中每个 Pod 创建的外部服务。 使用spec.externalAccess中的全局配置 设置和 Kubernetes 集群特定的覆盖在spec.clusterSpecList.externalAccess.externalService 设置。

  • DNS区域中配置 Pod 主机名,以确保托管 mongod进程的每个Kubernetes Pod 都允许与多 Kubernetes集群MongoDB 部署中的其他 mongod 进程建立外部连接。 Pod 被视为“暴露在外部”。您可以使用 <pod-name>.<externalDomain> 主机名在端口 27017(这是默认数据库端口)和 27018(这是数据库端口 + 1)上连接到 mongod进程。您可能还需要配置防火墙规则,允许端口 27017 和 27018 上的 TCP 流量。

完成这些先决条件后,您可以在没有服务网格的情况下部署多 Kubernetes 集群。

按照此过程中的步骤验证是否可跨 Kubernetes 集群访问服务FQDN

在此示例中,您将跨两个Kubernetes集群部署sample-service.yaml中定义的示例应用程序。

1

在每个 Kubernetes 集群中创建一个命名空间以部署sample-service.yaml

kubectl create --context="${CTX_CLUSTER_1}" namespace sample
kubectl create --context="${CTX_CLUSTER_2}" namespace sample

注意

在某些服务网格解决方案中,您可能需要对命名空间进行注释或标记。

2
kubectl apply --context="${CTX_CLUSTER_1}" \
-f sample-service.yaml \
-l service=helloworld1 \
-n sample
kubectl apply --context="${CTX_CLUSTER_2}" \
-f sample-service.yaml \
-l service=helloworld2 \
-n sample
3
kubectl apply --context="${CTX_CLUSTER_1}" \
-f sample-service.yaml \
-l version=v1 \
-n sample
4

检查托管 Pod 的CLUSTER_1是否处于Running状态。

kubectl get pod --context="${CTX_CLUSTER_1}" \
-n sample \
-l app=helloworld
5
kubectl apply --context="${CTX_CLUSTER_2}" \
-f sample-service.yaml \
-l version=v2 \
-n sample
6

检查托管 Pod 的CLUSTER_2是否处于Running状态。

kubectl get pod --context="${CTX_CLUSTER_2}" \
-n sample \
-l app=helloworld
7

CLUSTER_1中部署 Pod,并检查是否可以访问CLUSTER_2中的示例应用程序。

kubectl run --context="${CTX_CLUSTER_1}" \
-n sample \
curl --image=radial/busyboxplus:curl \
-i --tty \
curl -sS helloworld2.sample:5000/hello

您应该会看到类似于以下示例的输出:

Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8
8

CLUSTER_2中部署 Pod,并检查是否可以访问CLUSTER_1中的示例应用程序。

kubectl run --context="${CTX_CLUSTER_2}" \
-n sample \
curl --image=radial/busyboxplus:curl \
-i --tty \
curl -sS helloworld1.sample:5000/hello

您应该会看到类似于以下示例的输出:

Hello version: v1, instance: helloworld-v1-758dd55874-6x4t8

作为快速入门的一部分,您将在中央集群上部署MongoDB Ops Manager资源。

如果计划使用MongoDB TLS 加密来保护多 Kubernetes 集群 部署,请完成以下任务以启用内部集群身份验证,并为成员集群和 助手生成 TLS MongoDB Agent证书:

注意

您必须拥有CA证书和用于签署TLS证书的密钥。

1

使用以下选项之一:

  • 生成通配符TLS证书,其中涵盖 Kubernetes 操作符为部署中每个 Pod 创建的服务的主机名。

    如果生成通配符证书,则在扩展或重新平衡 Kubernetes 成员集群中的节点时(例如用于灾难恢复),可以继续使用相同的证书。

    例如,将类似于以下格式的主机名添加到SAN

    *.<namespace>.svc.cluster.local
  • 对于 Kubernetes 操作符生成的与每个成员集群中的每个 Pod 对应的每个 Kubernetes 服务,将SAN添加到证书中。在TLS证书中,每个 Kubernetes 服务的SAN必须使用以下格式:

    <metadata.name>-<member_cluster_index>-<n>-svc.<namespace>.svc.cluster.local

    其中n的范围为0clusterSpecList[member_cluster_index].members - 1

2

对于MongoDB Agent TLS证书:

  • TLS证书中的公用名不能为空。

  • 每个TLS证书中的组合组织和组织单位必须不同于副本集成员的TLS证书中的组织和组织单位。

为了加快为成员Kubernetes集群创建TLS证书,我们提供了setup_tls脚本。我们不保证脚本的维护性。如果您选择使用脚本,请对其进行测试并根据需要进行调整。该脚本执行以下操作:

  • Creates the cert-manager namespace in the connected cluster and installs cert-manager using Helm in the cert-manager namespace.

  • Installs a local CA using mkcert.

  • Downloads TLS certificates from downloads.mongodb.com and concatenates them with the CA file name and ca-chain.

  • 创建一个包含ca-chain文件的 ConfigMap。

  • 创建Issuer资源,证书管理器使用该资源生成证书。

  • 创建Certificate资源,证书管理器使用该资源为证书创建密钥对象。

要使用脚本:

1

在计划运行此脚本的计算机上安装 mkcert

2
kubectl --context $MDB_CENTRAL_CLUSTER_FULL_NAME \
--namespace=<metadata.namespace> \
3
curl https://raw.githubusercontent.com/mongodb/mongodb-kubernetes/master/scripts/release/kubectl-mongodb/setup_tls.sh -o setup_tls.sh

输出包括:

  • A secret containing the CA named ca-key-pair.

  • 包含中央 n clustercert-${resource}-cert上的服务器证书的密钥。

  • A ConfigMap containing the CA certificates named issuer-ca.

4

对于MongoDB Agent TLS证书:

  • TLS证书中的公用名不能为空。

  • 每个TLS证书中的组合组织和组织单位必须不同于副本集成员的TLS证书中的组织和组织单位。

1

使用以下选项之一:

  • 生成通配符 TLS 证书,其中包含您在 SAN 中创建的所有 externalDomain 。示例,将类似于以下格式的主机名添加到SAN

    *.cluster-0.example.com, *.cluster-1.example.com

    如果生成通配符证书,则在扩展或重新平衡Kubernetes成员集群中的节点时(示例用于灾难恢复),可以继续使用它们。

  • SAN 中的每个MongoDB副本集节点主机名生成 TLS 证书。示例,将类似于以下内容的主机名添加到SAN

    my-replica-set-0-0.cluster-0.example.com,
    my-replica-set-0-1.cluster-0.example.com,
    my-replica-set-1-0.cluster-1.example.com,
    my-replica-set-1-1.cluster-1.example.com

    如果生成包含所有特定主机名的单独TLS证书,则每次在Kubernetes节点集群中扩展或重新平衡节点时(示例为了灾难恢复),都必须创建新证书。

2

对于MongoDB Agent TLS证书:

  • TLS证书中的公用名不能为空。

  • 每个TLS证书中的组合组织和组织单位必须不同于副本集成员的TLS证书中的组织和组织单位。

重要

Kubernetes Operator 使用 kubernetes.io/tls secrets 来存储Ops Manager和MongoDB资源的 TLS 证书和私钥。从Kubernetes Operator 版本 1.17.0 开始, Kubernetes Operator 不支持存储为不透明密钥的连接 PEM 文件。

您可以选择创建和维护在 GitOps 环境中部署MongoDBMultiCluster资源所需的资源文件。

If you use a GitOps workflow, you can't use the kubectl mongodb plugin, which automatically configures role-based access control (RBAC) and creates the kubeconfig file that allows the operator cluster to communicate with its member clusters. Instead, you must manually configure or build your own automation for configuring the RBAC and kubeconfig files based on the procedure and examples in Configure Resources for GitOps.

以下先决条件部分描述了如何在不使用 GitOps的情况下安装 kubectl MongoDB插件,或者在使用 GitOps的情况下为 GitOps 配置资源

使用kubectl mongodb插件可以:

注意

如果您使用 GitOps,则无法使用kubectl mongodb插件。 相反,请按照为 GitOps 配置资源中的步骤进行操作。

要安装kubectl mongodb插件:

1

从MongoDB Controllers for Kubernetes Operator 存储库的发布页面下载所需的Kubernetes Operator包版本。

包的名称使用以下模式: kubectl-mongodb_{{ .Version }}_{{ .Os }}_{{ .Arch }}.tar.gz

使用以下包之一:

  • kubectl-mongodb_{{ .Version }}_darwin_amd64.tar.gz

  • kubectl-mongodb_{{ .Version }}_darwin_arm64.tar.gz

  • kubectl-mongodb_{{ .Version }}_linux_amd64.tar.gz

  • kubectl-mongodb_{{ .Version }}_linux_arm64.tar.gz

2

解压软件包,如以下示例所示:

tar -zxvf kubectl-mongodb_<version>_darwin_amd64.tar.gz
3

在解压缩的目录中找到kubectl-mongodb二进制文件,并将其移动到 Kubernetes 操作符 用户的 PATH 内的所需目标,如以下示例所示:

mv kubectl-mongodb /usr/local/bin/kubectl-mongodb

现在,您可以使用以下命令运行kubectl mongodb插件:

kubectl mongodb multicluster setup
kubectl mongodb multicluster recover

要了解有关支持标志的更多信息,请参阅MongoDB kubectl 插件参考资料。

如果使用 GitOps 工作流程,则无法使用 kubectl MongoDB 插件 自动配置 基于角色的访问权限控制 (RBAC) 或允许操作符集群与其成员集群通信的 kubeconfig 文件。相反,您必须手动配置和应用以下资源文件,或根据以下信息构建自己的自动化。

注意

To learn how the kubectl mongodb plugin automates the following steps, see the plugin source code in the MongoDB Kubernetes Operator repository.

要为 GitOps 配置 RBAC 和kubeconfig

1

使用 这些 RBAC资源示例 创建自己的 。要学习;了解有关这些 RBAC 资源的更多信息,请参阅了解Kubernetes角色和角色绑定。

要通过 GitOps 将它们应用到中央集群和成员集群,您可以使用 Argo CD等工具。

2

Kubernetes Operator 使用 ConfigMap 追踪其成员集群 文件。复制、修改并应用以下示例ConfigMap:

apiVersion: v1
kind: ConfigMap
data:
cluster1: ""
cluster2: ""
metadata:
namespace: <namespace>
name: mongodb-kubernetes-operator-member-list
labels:
multi-cluster: "true"
3

The Kubernetes Operator, which runs in the operator cluster, communicates with the Pods in the member clusters through the Kubernetes API. For this to work, the Kubernetes Operator needs a kubeconfig file that contains the service account tokens of the member clusters. Create this kubeconfig file by following these steps:

  1. Obtain a list of service accounts configured in the Kubernetes Operator's namespace. For example, if you chose to use the default mongodb namespace, then you can obtain the service accounts using the following command:

    kubectl get serviceaccounts -n mongodb
  2. 获取属于成员集群的每个服务帐户的密钥。

    kubectl get secret <service-account-name> -n mongodb -o yaml
  3. In each service account secret, copy the CA certificate and token. For example, copy <ca_certificate> and <token> from the secret, as shown in the following example:

    apiVersion: v1
    kind: Secret
    metadata:
    name: my-service-account
    namespace: mongodb
    data:
    ca.crt: <ca_certificate>
    token: <token>
  4. 复制操作符集群的以下 kubeconfig示例,并通过运行下列命令,将占位符替换为从服务帐户密钥中复制的 <ca_certificate><token>

    apiVersion: v1
    clusters:
    - cluster:
    certificate-authority:
    server: https://
    name: kind-e2e-cluster-1
    - cluster:
    certificate-authority:
    server: https://
    name: kind-e2e-cluster-2
    contexts:
    - context:
    cluster: kind-e2e-cluster-1
    namespace: mongodb
    user: kind-e2e-cluster-1
    name: kind-e2e-cluster-1
    - context:
    cluster: kind-e2e-cluster-2
    namespace: mongodb
    user: kind-e2e-cluster-2
    name: kind-e2e-cluster-2
    kind: Config
    users:
    - name: kind-e2e-cluster-1
    user:
    token:
    - name: kind-e2e-cluster-2
    user:
    token:

    使用正确的值填充以下 kubectl 命令并运行这些值以更新示例kubeconfig文件。

    kubectl config --kubeconfig=kubeconfig set-cluster kind-e2e-cluster-1 --certificate-authority=<cluster-1-ca.crt>
    kubectl config --kubeconfig=kubeconfig set-cluster kind-e2e-cluster-2 --certificate-authority=<cluster-2-ca.crt>
    kubectl config --kubeconfig=kubeconfig set-credentials kind-e2e-cluster-1 --token=<cluster-1-token>
    kubectl config --kubeconfig=kubeconfig set-credentials kind-e2e-cluster-2 --token=<cluster-2-token>
  5. 在挂载到Kubernetes Operator 中的操作符集群中创建密钥,如参考 Helm图表所示。示例:

    kubectl --context="${CTX_CENTRAL_CLUSTER}" -n <operator-namespace> create secret --from-file=kubeconfig=<path-to-kubeconfig-file> <kubeconfig-secret-name>