在使用快速入门或部署过程创建多 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 OperatorMongoDBMultiCluster
协调与Kubernetes Operator 部署在同一命名空间中的 资源。
当您在 多集群快速 入门中运行 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 OperatorMongoDB
以在多 Kubernetes集群MongoDB 部署中监视这些命名空间中的 资源。
将MongoDB Enterprise Kubernetes spec.template.spec.containers.name.env.name:WATCH_NAMESPACE
Operator GitHub 存储库的 mongodb-enterprise.yaml文件中的 设置为您希望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 以监视多MongoDB
Kubernetes集群MongoDB 部署中所有命名空间中的 资源。
将spec.template.spec.containers.name.env.name:WATCH_NAMESPACE
mongodb-enterprise.yaml 中的 设置为"*"
。您必须在 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 secrets 来存储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 等工具。
为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>