MongoDB顺利迁移到Kubernetes



本文是我们最近的 RabbitMQ迁移材料的继续,专门针对MongoDB。 由于我们为许多Kubernetes和MongoDB集群提供服务,因此自然而然地需要将数据从一个安装迁移到另一个安装,并且无需停机即可进行迁移。 主要场景是相同的:将MongoDB从虚拟/铁服务器传输到Kubernetes,或在一个Kubernetes集群内(从一个命名空间到另一个命名空间)传输MongoDB。

我们的食谱适用于旧的MongoDB集群运行正常的情况(例如,三个节点,并且已经位于K8或旧服务器上),而Kubernetes托管的应用程序可以正常工作:



我们如何将这样的集群转移到Kubernetes的新产品中?

理论


通用迁移算法与RabbitMQ情况下描述的算法相似。

重要的是要注意,移动能力要求具有MongoDB和Kubernetes的服务器位于同一网络上。 MongoDB群集的节点将通过旧服务器的IP(旧的MongoDB安装所在的位置)和K8s中来自MongoDB的Pod的DNS名称相互通信。 因此,在铁器服务器(具有旧安装)上,有必要将路由转发到Pod,然后将其配置为使用Kubernetes中运行的DNS服务器(或在/etc/hosts注册必要的名称,尽管通常情况下最好避免这种情况) )

下一步是在Kubernetes Pod中提升MongoDB集群。 在我们的例子中,数据库集群由3个节点组成,每个节点位于一个单独的pod'8 K8中-但是,它们的数量可能不同。 在ConfigMap中,您必须从旧的安装中指定MongoDB主服务器的地址:然后,位于K8s吊舱中的MongoDB节点将立即开始与其同步。

在所有Pod启动之后,形成了一个6节点的MongoDB集群:



请注意,由于每个Pod会依次启动,因此Pod会上升很长时间,并且在启动时会同步向导中的数据。

之后,您可以将应用程序切换为使用新的MongoDB服务器:



而且仅保留从MongoDB集群中删除旧节点,然后可以认为移动已完成:



我们经常在生产中使用此方案,为了方便使用,我们在addon-operator模块(我们最近宣布了该实用程序)中实现了该方案,该模块使我们能够在许多集群中分布典型的MongoDB配置。 我们计划在不久的将来发布我们的模块,但是目前,我们提供了单独的说明,您可以使用这些说明在实践中尝试所建议的解决方案,而无需使用addon-operator。

我们在实践中尝试


要求条件


详细资料:

  • Kubernetes集群(minikube也适用);
  • MongoDB集群(可以部署在裸机上,并根据官方Helm图表在Kubernetes中作为常规集群进行构建)。

在下面描述的示例中,具有MongoDB的旧集群将被称为mongo-old并安装在同一Kubernetes集群中,将来我们将在其中安装新的( mongo-new )。

准备旧集群


1.作为一个演示上述方案的示例,我们将直接在Kubernetes中创建一个“旧的”(即,需要迁移)MongoDB集群(实际上,它也可以位于K8之外的单独服务器上)。 为此,请下载Helm图表:

 helm fetch --untar stable/mongodb-replicaset 

...并通过设置授权对其进行一些编辑:

 auth: enabled: true adminUser: mongo adminPassword: pa33w0rd # metricsUser: metrics # metricsPassword: password # key: keycontent # existingKeySecret: # existingAdminSecret: # exisitingMetricsSecret: 

另外,在values.yaml您可以配置证书等等。

2.设置图表:

 helm install . --name mongo-old --namespace mongo-old 

之后,将启动测试的“旧” MongoDB安装:

 kubectl --namespace=mongo-old get pods 



让我们与Pod一起使用它的母版并创建一个测试基础:

 kubectl --namespace=mongo-old exec -ti mongo-old-mongodb-replicaset-0 mongo use admin db.auth('mongo','password') use music db.artists.insert({ artistname: "The Tea Party" }) show dbs 



进入不同的Pod,我发现主机是mongo-old-mongodb-replicaset-0 。 但是,为了更方便地解决此问题,在安装Helm-chart之后,将显示有关如何确定MASTER_POD的命令。 以我mongo-old (对于3个节点的mongo-old ),它看起来像这样:

 for ((i = 0; i < 3; ++i)); do kubectl exec --namespace mongo-old mongo-old-mongodb-replicaset-$i -- sh -c 'mongo --eval="printjson(rs.isMaster())"'; done 

至此,旧的MongoDB安装准备就绪,准备转移其数据。

MongoDB集群迁移


现在,我们将部署新的MongoDB安装,该安装位于Kubernetes中,供生产中的应用程序使用。

注意 :请注意,应使用与以前相同的MongoDB版本。 否则,存在兼容性问题的风险。

与上一节类似(我们模仿了“旧的” MongoDB安装),我们采用了已经提到的Helm-chart(使用helm fetch命令)并配置授权以及其他参数(如果使用)。 另外,我们将通过在第165行上临时添加上一步中获得的向导地址(或通过在单独的服务器上安装MongoDB所知)向init/on-start.sh文件修复init/on-start.sh文件:

 peers='mongo-old-mongodb-replicaset-0.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017' 

我们准备创建一个新的MongoDB安装:

 helm install . --name mongo-new --namespace mongo-new 

我们等到所有Pod启动(如果有大量数据,那么它们的启动可能需要几个小时):



现在,我们在一个新的pod中创建exec ,并查看基础列表:

 kubectl --namespace=mongo-new exec -ti mongo-new-mongodb-replicaset-0 mongo 



两个MongoDB集群合并为一个集群,由6个节点组成。

目前,您已经可以将应用程序切换到新的集群,但是还需要完成一些步骤来完成迁移。

在新安装的init/on-start.sh中,我们删除添加的行:

 peers='mongo-old-mongodb-replicaset-0.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017' 

现在,让我们进入集群的旧主服务器并“推翻”它-然后将在集群中分配一个新的主服务器。 我们和MongoDB大师一起进入吊舱:

 kubectl --namespace=mongo-old exec -ti mongo-old-mongodb-replicaset-0 mongo use admin db.auth('mongo','password') 

之后,我们更改节点的优先级并更改向导:

 cfg = rs.conf() cfg.members[5].priority = 2 rs.reconfig(cfg) rs.stepDown(120) 

当前节点已不再是主节点-将会进行新的选择。 随着我们更改优先级,我们需要的节点将成为主节点。

注意 :默认情况下,所有MongoDB节点的优先级均为1。在上面,我们将所需节点的优先级提高到2。 因此,一个新集群的成员肯定会成为一个共同的主人。 您可以在文档中阅读有关MongoDB中这些机制如何工作的更多信息。

禁用旧的MongoDB安装,然后转到新的向导并删除旧的节点:

 rs.remove("mongo-old-mongodb-replicaset-0.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017") rs.remove("mongo-old-mongodb-replicaset-1.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017") rs.remove("mongo-old-mongodb-replicaset-2.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017") 

此后,迁移就可以视为完成了:我们成功地从旧的MongoDB集群切换到了新的集群!

总结


所描述的方案几乎适用于所有需要转移MongoDB或仅移至新集群的情况。

传输过程中的主要细微差别可能是需要将新Pod的IP地址转发到旧的MongoDB安装的服务器(如果它在K8之外),并在DNS(或/etc/hosts )中正确命名。 在该示例中,不需要这些步骤,因为迁移发生在同一Kubernetes集群的不同名称空间之间。

聚苯乙烯


另请参阅我们的博客:

Source: https://habr.com/ru/post/zh-CN461149/


All Articles