在使用快速入门或部署过程创建多 Kubernetes集群MongoDB 部署之前,请完成以下任务。
要学习;了解有关快速入门特定先决条件的更多信息,请参阅快速入门先决条件。
查看支持的硬件架构
请参阅支持的硬件架构。
克隆 MongoDB Enterprise Kubernetes Operator 存储库
克隆MongoDB Enterprise Kubernetes Operator存储库:
git clone https://github.com/mongodb/mongodb-enterprise-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" 
安装 Go 和 Helm
安装以下工具:
了解 Kubernetes 角色和角色绑定
要使用多 Kubernetes 集群 MongoDB 部署,您必须拥有一设立特定的 Kubernetes 角色、ClusterRoles、RoleBindings、ClusterRoleBindings 和 ServiceAccounts,您可以通过以下任一方式进行配置:
- 按照多 Kubernetes 集群快速入门进行操作,该入门介绍如何使用MongoDB插件自动创建所需的对象,应用它们应用到多 Kubernetes集群MongoDB 部署中的相应集群。 
- 使用 Helm 为每个成员集群配置所需的Kubernetes角色和服务帐户: - helm template --show-only \ - templates/database-roles.yaml \ - mongodb/enterprise-operator \ - --set namespace=mongodb | \ - kubectl apply -f - \ - --context=$MDB_CLUSTER_1_FULL_NAME \ - --namespace mongodb - helm template --show-only \ - templates/database-roles.yaml \ - mongodb/enterprise-operator \ - --set namespace=mongodb | \ - kubectl apply -f - \ - --context=$MDB_CLUSTER_2_FULL_NAME \ - --namespace mongodb - helm template --show-only \ - templates/database-roles.yaml \ - mongodb/enterprise-operator \ - --set namespace=mongodb | \ - kubectl apply -f - \ - --context=$MDB_CLUSTER_3_FULL_NAME \ - --namespace mongodb 
- 手动创建Kubernetes对象 - .yaml文件,并使用- kubectl apply命令将所需的Kubernetes角色和服务帐户添加到多 Kubernetes集群MongoDB 部署中。 这对于某些高度自动化的工作流程可能是必要的。 MongoDB提供了示例配置文件。- 对于作用域为命名空间子集的自定义资源: - 对于范围为集群范围命名空间的自定义资源: - 每个文件定义多个资源。 为了支持您的部署,您必须替换以下字段中的占位符值: - subjects.namespace在每个- RoleBinding或- ClusterRoleBinding资源中
- metadata.namespace在每个- ServiceAccount资源中
 - 修改定义后,对每个文件运行以下命令来应用这些定义: - kubectl apply -f <fileName> 
设置部署范围
默认下,多集群Kubernetes Operator 的作用域为安装它的命名空间。Kubernetes Operator 协调与Kubernetes Operator 部署在同一命名空间中的 MongoDBMultiCluster资源。
当您在 多集群快速 入门中运行 MongoDB kubectl 插件 ,并且不修改kubectl mongodb 插件设置时,该插件:
- 创建一个名为 - mongodb-enterprise-operator-member-list的默认ConfigMap,其中包含多 Kubernetes集群MongoDB 部署的所有成员集群。 此名称是硬编码的,无法更改。 请参阅已知问题。
- 在操作符集群和每个成员集群中创建 ServiceAccounts、Roles、ClusterRoles、RoleBindings 和 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 操作符 实例?
监视多个命名空间中的资源
如果将多 Kubernetes集群MongoDB 部署的范围设立为多个命名空间,则可以配置Kubernetes Operator 以在多 Kubernetes集群MongoDB 部署中监视这些命名空间中的 MongoDB 资源。
将MongoDB Enterprise Kubernetes Operator Github存储库的 mongodb-enterprise.yaml 文件中的 spec.template.spec.containers.name.env.name:WATCH_NAMESPACE 设置为您希望Kubernetes Operator 监视的命名空间的逗号分隔列表:
WATCH_NAMESPACE: "$namespace1,$namespace2,$namespace3" 
运行以下命令,并将最后一行中的值替换为您希望Kubernetes Operator 监视的命名空间。
helm upgrade \   --install \   mongodb-enterprise-operator-multi-cluster \   mongodb/enterprise-operator \   --namespace mongodb \   --set namespace=mongodb \   --version <mongodb-kubernetes-operator-version>\   --set operator.name=mongodb-enterprise-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" 
监视所有命名空间中的资源
如果将多 Kubernetes集群MongoDB 部署的范围设立为所有命名空间,而不是默认的mongodb命名空间,则可以配置Kubernetes Operator 以监视多 Kubernetes集群MongoDB 部署中所有命名空间中的 MongoDB 资源。
将 mongodb-enterprise.yaml 中的 spec.template.spec.containers.name.env.name:WATCH_NAMESPACE 设置为 "*"。您必须在 YAML文件中用双引号 (") 将星号 (*) 括起来。
WATCH_NAMESPACE: "*" 
运行以下命令:
helm upgrade \   --install \   mongodb-enterprise-operator-multi-cluster \   mongodb/enterprise-operator \   --namespace mongodb \   --set namespace=mongodb \   --version <mongodb-kubernetes-operator-version>\   --set operator.name=mongodb-enterprise-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 部署中部署副本集。
根据您的环境,执行以下操作:
- 如果可以使用服务网格,请安装 Istio。 
- 如果无法使用服务网格: 
Kubernetes Operator 如何建立连接?
无论哪种部署类型,Kubernetes 中的 MongoDB 部署都必须建立以下连接:
- 从 Pod 中的 Ops Manager MongoDB Agent 到其 - mongod进程,以启用 MongoDB deployment 的生命周期管理和监控。
- 从 Pod 中的 Ops Manager MongoDB Agent 到 Ops Manager 实例,以启用自动化。 
- 在所有 - mongod进程之间,以允许复制。
当 Kubernetes Operator 部署 MongoDB 资源时,它会根据部署类型,通过以下方式处理这些连接要求:
- 在单个Kubernetes集群部署中, Kubernetes Operator 将副本集的主机名配置为无头服务的 FQDN。这是一项单一服务,通过 Pod 的 FQDN 解析托管MongoDB实例的每个 Pod 的直接IP地址的 DNS ,如下所示: - <pod-name>.<replica-set-name>-svc.<namespace>.svc.cluster.local。
- 在使用服务网格的多 Kubernetes集群MongoDB 部署中, Kubernetes Operator 为Kubernetes集群中的每个MongoDB副本集成员创建一个单独的 StatefulSet。 服务网格允许不同Kubernetes集群的 - mongod进程之间进行通信。- 通过使用服务网格,多 Kubernetes集群MongoDB 部署可以: - 跨 Kubernetes 集群实现全局DNS主机名解析,并在它们之间建立连接。 对于每个 Kubernetes 集群中的每个 MongoDB 部署 Pod,Kubernetes Operator 通过 - MongoDBMultiCluster资源中的- spec.duplicateServiceObjects: true配置创建一个 ClusterIP 服务。 每个进程都有一个为此服务的FQDN定义的主机名:- <pod-name>-svc.<namespace>.svc.cluster.local。 这些主机名从 DNS 解析为每个成员集群中服务的 ClusterIP。
- 在不同 Kubernetes 集群中的 Pod 之间建立通信。 因此,托管在不同集群上的副本集成员形成了跨这些集群的单个副本集。 
 
- 在没有服务网格的多 Kubernetes集群MongoDB 部署中, Kubernetes Operator 使用以下 - MongoDBMultiCluster资源设置向外部公开其所有- mongod进程。 这样就可以对不同Kubernetes集群之间的主机名进行 DNS 解析,并在通过连接这些集群的网络路由的 Pod 之间建立连接。
可选:安装 Istio
使用 Istio 文档在不同网络上以多主节点模式安装 Istio。Istio 是一个服务网格,可简化 DNS 解析并帮助在多 Kubernetes集群MongoDB 部署中的成员Kubernetes集群之间建立集群间通信。如果选择使用服务网格,则需要安装它。如果您无法使用服务网格,请跳过本节并使用外部域并配置 DNS 以启用外部连接。
此外,我们还提供了install_istio_separate_network示例脚本。此脚本基于 Istio 文档,并提供在不同网络上使用多主节点模式的示例安装。我们不保证未来的 Istio 版本能够维护该脚本。如果您选择使用脚本,查看有关安装多集群的最新 Istio 文档,并在必要时调整脚本以匹配文档和您的部署。如果您使用其他服务网格解决方案,请创建自己的脚本来配置单独的网络,以便于 DNS 解析。
通过外部域和 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进程建立外部连接。 当您可以在端口27017 (这是默认数据库端口)和27018 (这是数据库端口)上使用1- <pod-name>.<externalDomain>主机名连接到- mongod进程时,Pod 被视为“外部公开” )。 您可能还需要配置防火墙规则,允许端口27017和27018上的 TCP 流量。
完成这些先决条件后,您可以在没有服务网格的情况下部署多 Kubernetes 集群。
检查集群间的连接
按照此过程中的步骤验证是否可跨 Kubernetes 集群访问服务FQDN 。
在此示例中,您将跨两个Kubernetes集群部署sample-service.yaml中定义的示例应用程序。
查看部署 Ops Manager 的要求
作为快速入门的一部分,您将在中央集群上部署MongoDB Ops Manager资源。
准备 TLS 加密连接
如果计划使用MongoDB TLS 加密来保护多 Kubernetes 集群 部署,请完成以下任务以启用内部集群身份验证,并为成员集群和 助手生成 TLS MongoDB Agent证书:
注意
您必须拥有CA证书和用于签署TLS证书的密钥。
为 Kubernetes 服务生成 TLS 证书。
使用以下选项之一:
- 生成通配符TLS证书,其中涵盖Kubernetes Operator 为部署中每个 Pod 创建的服务的主机名。 - 如果生成通配符证书,则在扩展或重新平衡 Kubernetes 成员集群中的节点时(例如用于灾难恢复),可以继续使用相同的证书。 - 示例,将类似于以下格式的主机名添加到SAN : - *.<namespace>.svc.cluster.local 
- 对于Kubernetes Operator 生成的与每个成员集群中的每个 Pod 对应的每个Kubernetes服务,将SAN添加到证书中。 在TLS证书中,每个Kubernetes服务的SAN必须使用以下格式: - <metadata.name>-<member_cluster_index>-<n>-svc.<namespace>.svc.cluster.local - 其中 - n的范围为- 0到- clusterSpecList[member_cluster_index].members - 1。
为了加快为成员Kubernetes集群创建TLS证书,我们提供了setup_tls脚本。我们不保证脚本的维护性。如果您选择使用脚本,请对其进行测试并根据需要进行调整。该脚本执行以下操作:
- cert-manager在连接的集群中创建 命名空间,并在- cert-manager命名空间中使用 Helm 安装 cert-manager 。
- 使用 mkcert 安装本地 CA。 
- 从 - downloads.mongodb.com下载量TLS证书并将其与CA文件名和- ca-chain连接。
- 创建一个包含 - ca-chain文件的 ConfigMap。
- 创建 - Issuer资源,证书管理器使用该资源生成证书。
- 创建 - Certificate资源,证书管理器使用该资源为证书创建密钥对象。
要使用脚本:
安装mkcert 。
在计划运行此脚本的计算机上安装 mkcert。
为 SAN 主机名生成 TLS 证书。
使用以下选项之一:
- 生成通配符 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节点集群中扩展或重新平衡节点时(示例为了灾难恢复),都必须创建新证书。 
重要
Kubernetes Operator 使用 kubernetes.io/tls用于存储 MongoDB Ops Manager 和 MongoDB 资源的 TLS 证书和私钥的密钥。从 Kubernetes Operator1 17版本..0 开始,Kubernetes Operator 不支持存储为 不透明密钥 的连接 PEM 文件。
选择 GitOps 或 kubectl MongoDB 插件
您可以选择创建和维护在 GitOps 环境中部署MongoDBMultiCluster资源所需的资源文件。
如果使用 GitOps 工作流程,则无法使用 kubectl MongoDB 插件,该插件会自动配置基于角色的访问权限控制 (RBAC) 并创建 kubeconfig 文件,以允许操作符集群与其成员集群通信。相反,您必须根据为kubeconfig GitOps 配置资源中的过程和示例,手动配置或构建自己的自动化配置 RBAC 和 文件。
以下先决条件部分描述了如何在不使用 GitOps的情况下安装 kubectl MongoDB插件,或者在使用 GitOps的情况下为 GitOps 配置资源。
安装 kubectl MongoDB 插件
使用kubectl mongodb插件可以:
注意
如果您使用 GitOps,则无法使用kubectl mongodb插件。 相反,请按照为 GitOps 配置资源中的步骤进行操作。
要安装kubectl mongodb插件:
下载所需的 Kubernetes Operator 软件包版本。
从MongoDB Enterprise 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
找到kubectl mongodb 插件二进制文件并将其复制到所需的目标。
在解压缩的目录中找到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 配置资源
如果使用 GitOps 工作流程,则无法使用 kubectl MongoDB 插件 自动配置 基于角色的访问权限控制 (RBAC) 或允许操作符集群与其成员集群通信的 kubeconfig 文件。相反,您必须手动配置和应用以下资源文件,或根据以下信息构建自己的自动化。
要为 GitOps 配置 RBAC 和kubeconfig :
创建 RBAC 资源并将其应用于每个集群。
使用这些 RBAC资源示例来创建您自己的资源示例。要学习;了解有关这些 RBAC 资源的更多信息,请参阅了解Kubernetes角色和角色绑定。
要通过 GitOps 将它们应用到中央集群和成员集群,您可以使用 Argo CD等工具。
创建并应用 ConfigMap 文件。
Kubernetes Operator 使用ConfigMap文件追踪其成员集群。复制、修改并应用以下示例ConfigMap:
apiVersion: v1 kind: ConfigMap data:   cluster1: ""   cluster2: "" metadata:   namespace: <namespace>   name: mongodb-enterprise-operator-member-list   labels:     multi-cluster: "true" 
为Kubernetes Operator 配置kubeconfig 密钥。
在操作符集群中运行的Kubernetes Operator 通过Kubernetes API与成员集群中的 Pod 进行通信。为此, Kubernetes Operator 需要一个包含成员集群的服务帐户令牌的kubeconfig文件。通过以下步骤创建此 kubeconfig文件:
- 获取在Kubernetes Operator 的命名空间中配置的服务帐户列表。示例,如果您选择使用默认的 - mongodb命名空间,则可以使用以下命令获取服务帐户:- kubectl get serviceaccounts -n mongodb 
- 获取属于成员集群的每个服务帐户的密钥。 - kubectl get secret <service-account-name> -n mongodb -o yaml 
- 在每个服务帐户密钥中,复制CA证书和令牌。 例如,从密钥中复制 - <ca_certificate>和- <token>,如以下示例所示:- apiVersion: v1 - kind: Secret - metadata: - name: my-service-account - namespace: mongodb - data: - ca.crt: <ca_certificate> - token: <token> 
- 复制操作符集群的以下 - 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> 
- 在挂载到Kubernetes Operator 中的操作符集群中创建密钥,如参考 Helm图表所示。示例: - kubectl --context="${CTX_CENTRAL_CLUSTER}" -n <operator-namespace> create secret --from-file=kubeconfig=<path-to-kubeconfig-file> <kubeconfig-secret-name>