Migración sin complicaciones de MongoDB a Kubernetes

Migración sin complicaciones de MongoDB a Kubernetes

Este artículo continúa nuestro contenido reciente sobre la migración de RabbitMQ y se dedica a MongoDB. Dado que gestionamos numerosos clústeres de Kubernetes y MongoDB, nos ha surgido naturalmente la necesidad de migrar datos de una instalación a otra y hacerlo sin interrupciones. Los escenarios principales son los mismos: trasladar MongoDB de un servidor virtual/físico a Kubernetes o mover MongoDB dentro de un mismo clúster de Kubernetes (de un espacio de nombres a otro).

Nuestra receta está destinada a situaciones en las que un antiguo clúster de MongoDB (por ejemplo, de 3 nodos y que ya se encuentra en K8s o en servidores antiguos) está funcionando, y que es utilizado por una aplicación alojada en Kubernetes:

Migración sin complicaciones de MongoDB a Kubernetes

¿Cómo vamos a trasladar dicho clúster a un nuevo entorno de producción en Kubernetes?

Teoría

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

Es importante señalar que para que la migración sea posible, los servidores con MongoDB y Kubernetes deben estar en la misma red. Los nodos del clúster de MongoDB se comunicarán entre sí a través de la IP de los antiguos servidores (donde se encuentran las antiguas instalaciones de MongoDB) y por los nombres DNS de los pods con MongoDB en K8s. Por lo tanto, en los servidores físicos (con las antiguas instalaciones), será necesario enrutar hacia los pods, y luego configurar su uso del servidor DNS que opera en Kubernetes (aunque en general es mejor evitar esta posibilidad). /etc/hosts, aunque en general es mejor evitar esta posibilidad).

El siguiente paso es levantar el clúster de MongoDB en los pods de Kubernetes. En nuestro caso, el clúster de base de datos consta de 3 nodos y cada nodo se encuentra en un pod separado de K8s; sin embargo, su número puede ser diferente. En el ConfigMap, debes especificar la dirección del maestro de MongoDB de la antigua instalación: entonces, los nodos de MongoDB en los pods de K8s comenzarán a sincronizarse con él de inmediato.

Una vez que todos los pods se levanten, se formará un clúster de MongoDB de 6 nodos:

Migración sin complicaciones de MongoDB a Kubernetes

Ten en cuenta que los pods tardarán en levantarse, ya que cada pod se inicia uno tras otro y, en el momento de su inicio, sincroniza datos con el maestro.

Después de esto, se puede cambiar la aplicación para utilizar los nuevos servidores de MongoDB:

Migración sin complicaciones de MongoDB a Kubernetes

Y solo quedará eliminar los nodos antiguos del clúster de MongoDB, después de lo cual la migración se podrá considerar completa:

Migración sin complicaciones de MongoDB a Kubernetes

Este esquema lo aplicamos a menudo en producción y, para facilitar su uso, lo hemos implementado en el marco del módulo de addon-operator (esta utilidad la anunciamos recientemente.), lo que permite desplegar configuraciones estándar de MongoDB en múltiples clústeres. Planeamos publicar nuestros módulos en breve, mientras tanto presentamos instrucciones independientes con las que se puede probar la solución propuesta en acción sin utilizar el addon-operator.

Probando en la práctica

Requisitos

Detalles:

  • Clúster de Kubernetes (también sirve minikube);
  • Clúster de MongoDB (puede estar desplegado en bare metal o creado como un clúster normal en Kubernetes a partir del Helm chart oficial).

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

Preparando el antiguo clúster

1. Para el ejemplo que demuestra el esquema descrito en acción, crearemos un clúster MongoDB “antiguo” (es decir, que será migrado) directamente en Kubernetes (en realidad puede estar en servidores separados fuera de K8s). Para esto descargaremos el Helm chart:

helm fetch --untar stable/mongodb-replicaset

… y lo editaremos un poco, configurando la autorización:

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

También en values.yaml se pueden configurar los certificados y muchas otras cosas.

2. Instalaremos el chart:

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

Después de esto, se iniciará una instalación de prueba “antigua” de MongoDB:

kubectl --namespace=mongo-old get pods

Migración sin complicaciones de MongoDB a Kubernetes

Entraremos en el pod con su maestro y crearemos una base de datos 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

Migración sin complicaciones de MongoDB a Kubernetes

Al revisar diferentes pod’ s, descubrí que el maestro es mongo-old-mongodb-replicaset-0. Sin embargo, para una solución más conveniente a esta cuestión, después de instalar el Helm chart se mostrará un comando para determinar MASTER_POD. En mi caso (para mongo-old de 3 nodos) parece 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

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

Migración del clúster de MongoDB

Ahora desplegaremos una nueva instalación de MongoDB que estará en Kubernetes y será utilizada por la aplicación en producción.

NB: Cabe destacar que se debe usar la misma versión de MongoDB que antes. De lo contrario, existe el riesgo de tener problemas de compatibilidad.

De manera similar a la sección anterior (donde simulamos una instalación 'vieja' de MongoDB), tomaremos el gráfico de Helm mencionado anteriormente (con el comando helm fetch) y configuraremos la autorización, así como otros parámetros, en caso de que se utilicen. Además, corregiremos el archivo init/on-start.sh, añadiendo temporalmente en la línea 165 la dirección del maestro, obtenida en la etapa anterior (o conocida por usted de la instalación de MongoDB en servidores individuales):

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 a que todos los pods se inicien (si hay muchos datos, su inicio puede tardar horas):

Migración sin complicaciones de MongoDB a Kubernetes

Ahora hacemos exec en el nuevo pod y vemos la lista de bases de datos:

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

Migración sin complicaciones de MongoDB a Kubernetes

Se han combinado dos clústeres de MongoDB en uno, que consta de 6 nodos.

En este momento, ya se puede cambiar la aplicación al nuevo clúster, pero quedan algunos pasos para completar la migración.

Del archivo init/on-start.sh en la nueva instalación eliminamos la línea añadida por nosotros:

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

Ahora accederemos al antiguo maestro del clúster y lo 'derrocamos' — entonces se designará un nuevo maestro en el clúster. Ingresamos al pod con el maestro de MongoDB:

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

Después de esto, cambiamos las prioridades de los nodos y cambiamos al maestro:

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

El nodo actual ha dejado de ser maestro — habrá elecciones para un nuevo. Como hemos cambiado las prioridades, el nodo deseado se convertirá en el maestro.

NB: Por defecto, todos los nodos de MongoDB tienen una prioridad de 1. Más arriba, aumentamos la prioridad del nodo deseado a 2. De esta manera, el miembro del nuevo clúster se convierte definitivamente en el maestro. Puede leer más sobre cómo funcionan estos mecanismos en MongoDB en la documentación.

Desactivaremos la antigua instalación de MongoDB, después entraremos en el maestro nuevo y eliminaremos 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, se puede considerar que la migración ha terminado: ¡hemos cambiado con éxito del antiguo clúster de MongoDB al nuevo!

Resultados

El esquema descrito se adapta prácticamente a todos los casos en los que es necesario trasladar MongoDB o simplemente mudarse a un nuevo clúster.

Quizás, el aspecto más importante al realizar la migración es la necesidad de pasar las direcciones IP de los nuevos pods a los servidores de la antigua instalación de MongoDB, si se encuentra fuera de K8s, y su correcta denominación en DNS (o /etc/hosts). En el ejemplo, estos pasos no fueron necesarios, ya que la migración se realizó entre diferentes espacios de nombres de un mismo clúster de Kubernetes.

P.D.

También puedes leer en nuestro blog:

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster