Migración sin obstáculos de MongoDB a Kubernetes



Este artículo continúa nuestro reciente material de migración RabbitMQ y está dedicado a MongoDB. Dado que servimos a muchos grupos de Kubernetes y MongoDB, hemos llegado a la necesidad natural de migrar datos de una instalación a otra y hacerlo sin tiempo de inactividad. Los escenarios principales son los mismos: portar MongoDB desde un servidor virtual / iron a Kubernetes o portar MongoDB dentro de un clúster de Kubernetes (de un espacio de nombres a otro).

Nuestra receta está destinada a casos en los que el antiguo clúster MongoDB está funcionando (por ejemplo, de 3 nodos y ubicados ya en K8 o en servidores antiguos) con los que funciona una aplicación alojada en Kubernetes:



¿Cómo transferiremos tal clúster a una nueva producción en Kubernetes?

Teoría


El algoritmo de migración general es similar al descrito en la situación con RabbitMQ.

Es importante tener en cuenta que la capacidad de moverse requiere que los servidores con MongoDB y Kubernetes estén en la misma red. Los nodos del clúster MongoDB se comunicarán entre sí a través de la IP de los servidores antiguos (donde se encuentran las antiguas instalaciones de MongoDB) y los nombres DNS de los pods de MongoDB en K8s. Por lo tanto, en servidores de hierro (con instalaciones antiguas), será necesario reenviar rutas a pods y luego configurarlos para usar el servidor DNS que se ejecuta en Kubernetes (o registrar los nombres necesarios en /etc/hosts , aunque en el caso general es mejor evitar esta posibilidad )

El siguiente paso es elevar el clúster MongoDB en los pods de Kubernetes. En nuestro caso, el clúster de la base de datos consta de 3 nodos y cada nodo está ubicado en un pod'8 K8 separado; sin embargo, su número puede ser diferente. En ConfigMap, debe especificar la dirección del maestro MongoDB de la instalación anterior: luego los nodos MongoDB ubicados en los pods en K8 comenzarán inmediatamente a sincronizarse con él.

Después de que todos los pods suben, se forma un clúster MongoDB de 6 nodos:



Tenga en cuenta que los pod se elevarán durante mucho tiempo, ya que cada pod se inicia a su vez y, en el momento del lanzamiento, sincroniza los datos del asistente.

Después de eso, puede cambiar la aplicación para usar los nuevos servidores MongoDB:



Y solo queda eliminar los nodos antiguos del clúster MongoDB, después de lo cual el movimiento se puede considerar completado:



A menudo usamos este esquema en la producción y, para la conveniencia de su uso, lo implementamos en el módulo addon-operator ( recientemente anunciamos esta utilidad), que nos permite distribuir configuraciones típicas de MongoDB en muchos clústeres. Planeamos publicar nuestros módulos en un futuro cercano, pero por ahora presentamos instrucciones separadas con las que puede probar la solución propuesta en acción y sin utilizar el operador de complemento.

Lo intentamos en la práctica


Requisitos


Detalles:

  • Clúster de Kubernetes (minikube también es adecuado);
  • Clúster MongoDB (puede implementarse en metal desnudo y hacerse como un clúster regular en Kubernetes a partir del gráfico oficial de Helm).

En el ejemplo que se describe a continuación, el clúster antiguo con MongoDB se llamará mongo-old y se instalará en el mismo clúster de Kubernetes, donde en el futuro instalaremos el nuevo ( mongo-new ).

Preparando el viejo clúster


1. Para un ejemplo que demuestre el esquema descrito en acción, crearemos un clúster MongoDB “antiguo” (es decir, sujeto a migración) directamente en Kubernetes (en realidad, también puede ubicarse en servidores separados fuera de K8). Para hacer esto, descargue la tabla Helm:

 helm fetch --untar stable/mongodb-replicaset 

... y edítelo un poco configurando la autorización:

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

También en values.yaml puedes configurar certificados y mucho más.

2. Establecer el gráfico:

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

Después de eso, se lanzará la instalación de prueba "antigua" de MongoDB:

 kubectl --namespace=mongo-old get pods 



Vayamos al pod con su maestro y creemos una base de prueba:

 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 



Al ingresar en diferentes pods, descubrí que el maestro es mongo-old-mongodb-replicaset-0 . Sin embargo, para una solución más conveniente a este problema, después de instalar Helm-chart, se muestra un comando sobre cómo determinar MASTER_POD . En mi caso (para mongo-old de 3 nodos) se ve así:

 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 

En esto, la preparación de la antigua instalación de MongoDB, cuyos datos serán transferidos, está lista.

MongoDB Cluster Migration


Ahora implementaremos la nueva instalación de MongoDB, que se ubicará en Kubernetes y será utilizada por la aplicación en producción.

NB : Tenga en cuenta que la misma versión de MongoDB debe usarse como antes. De lo contrario, existe el riesgo de problemas de compatibilidad.

Por analogía con la sección anterior (donde imitamos la instalación "antigua" de MongoDB), tomamos el Helm-chart ya mencionado (usando el helm fetch ) y configuramos la autorización, así como otros parámetros, si se usan. Además, arreglaremos el archivo init/on-start.sh agregándole temporalmente en la línea 165 la dirección del asistente obtenida en el paso anterior (o conocida por usted al instalar MongoDB en servidores separados):

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

Estamos listos para crear una nueva instalación de MongoDB:

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

Esperamos hasta que comiencen todos los pods (si hay muchos datos, entonces su lanzamiento puede tomar horas):



Ahora hacemos exec en un nuevo pod y miramos la lista de bases:

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



Dos grupos MongoDB se combinan en uno, que consta de 6 nodos.

Por el momento, ya puede cambiar la aplicación a un nuevo clúster, pero quedan algunos pasos para completar la migración.

Del init/on-start.sh en la nueva instalación, eliminamos la línea que agregamos:

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

Ahora vamos al viejo maestro del clúster y "lo derrocamos"; luego se asignará un nuevo maestro en el clúster. Entramos en el pod con el maestro MongoDB:

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

Después de eso, cambiamos las prioridades de los nodos y cambiamos el asistente:

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

El nodo actual ha dejado de ser un maestro: se producirá una nueva elección. A medida que cambiamos las prioridades, el nodo que necesitamos se convertirá en el maestro.

NB : Por defecto, todos los nodos MongoDB tienen una prioridad de 1. Arriba elevamos a 2 la prioridad del nodo que necesitamos. Por lo tanto, un miembro de un nuevo clúster definitivamente se convertirá en un maestro común. Puede leer más sobre cómo funcionan estos mecanismos en MongoDB en la documentación .

Deshabilite la instalación anterior de MongoDB, luego vaya al nuevo asistente y elimine los nodos antiguos:

 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") 

Después de esto, la migración se puede considerar completada: ¡cambiamos con éxito del antiguo clúster MongoDB al nuevo!

Resumen


El esquema descrito es adecuado para casi todos los casos en los que necesita transferir MongoDB o simplemente pasar a un nuevo clúster.

Quizás el matiz principal durante la transferencia es la necesidad de reenviar las direcciones IP de los nuevos pods a los servidores de la antigua instalación de MongoDB, si está fuera de K8, y nombrarlos correctamente en DNS (o /etc/hosts ). En el ejemplo, estos pasos no fueron necesarios, ya que la migración se produjo entre diferentes espacios de nombres del mismo clúster de Kubernetes.

PS


Lea también en nuestro blog:

Source: https://habr.com/ru/post/461149/


All Articles