Migración perfecta de RabbitMQ a Kubernetes

Migración perfecta de RabbitMQ a Kubernetes

RabbitMQ es un intermediario de mensajes escrito en Erlang que le permite organizar un clúster de conmutación por error con replicación de datos completa en varios nodos, donde cada nodo puede atender solicitudes de lectura y escritura. Al tener muchos clústeres de Kubernetes en operación de producción, admitimos una gran cantidad de instalaciones de RabbitMQ y nos enfrentamos a la necesidad de migrar datos de un clúster a otro sin tiempo de inactividad.

Necesitábamos esta operación en al menos dos casos:

  1. Transferir datos de un clúster RabbitMQ que no está ubicado en Kubernetes a un clúster nuevo, ya “kubernetizado” (es decir, que opera en pods K8).
  2. Migración de RabbitMQ dentro de Kubernetes de un espacio de nombres a otro (por ejemplo, si los circuitos están delimitados por espacios de nombres, entonces transferir infraestructura de un circuito a otro).

La receta propuesta en el artículo se centra en situaciones (pero no se limita en absoluto a ellas) en las que hay un clúster RabbitMQ antiguo (por ejemplo, de 3 nodos), ubicado ya en K8 o en algunos servidores antiguos. Una aplicación alojada en Kubernetes (ya allí o en el futuro) funciona con él:

Migración perfecta de RabbitMQ a Kubernetes

... y nos encontramos ante la tarea de migrarlo a la nueva producción en Kubernetes.

Primero, se describirá el enfoque general de la migración en sí, y luego se describirán los detalles técnicos de su implementación.

Algoritmo de migración

La primera etapa preliminar antes de cualquier acción es verificar que el modo de alta disponibilidad esté habilitado en la instalación anterior de RabbitMQ (HA). La razón es obvia: no queremos perder ningún dato. Para llevar a cabo esta verificación, puede ir al panel de administración de RabbitMQ y en la pestaña Admin → Políticas asegurarse de que el valor esté establecido. ha-mode: all:

Migración perfecta de RabbitMQ a Kubernetes

El siguiente paso es crear un nuevo clúster RabbitMQ en pods de Kubernetes (en nuestro caso, por ejemplo, consta de 3 nodos, pero su número puede ser diferente).

Después de esto, fusionamos los clústeres RabbitMQ antiguos y nuevos, obteniendo un único clúster (de 6 nodos):

Migración perfecta de RabbitMQ a Kubernetes

Se inicia el proceso de sincronización de datos entre los clústeres RabbitMQ nuevos y antiguos. Una vez que todos los datos estén sincronizados entre todos los nodos del clúster, podemos cambiar la aplicación para usar el nuevo clúster:

Migración perfecta de RabbitMQ a Kubernetes

Después de estas operaciones, basta con eliminar los nodos antiguos del clúster RabbitMQ y el movimiento se puede considerar completo:

Migración perfecta de RabbitMQ a Kubernetes

Hemos utilizado este esquema muchas veces en producción. Sin embargo, para nuestra propia conveniencia, lo implementamos dentro de un sistema especializado que distribuye configuraciones RMQ estándar en múltiples clústeres de Kubernetes. (para los que tengan curiosidad: estamos hablando de operador-adicionalsobre el cual nosotros le dije hace poco). A continuación presentaremos instrucciones individuales que cualquiera puede aplicar en sus instalaciones para probar la solución propuesta en acción.

Probémoslo en la práctica.

Requisitos

Los detalles son muy simples:

  1. Clúster de Kubernetes (minikube también funcionará);
  2. Clúster RabbitMQ (se puede implementar en bare metal y crearse como un clúster normal en Kubernetes a partir del gráfico oficial de Helm).

Para el siguiente ejemplo, implementé RMQ en Kubernetes y lo llamé rmq-old.

Preparación del stand

1. Descargue el gráfico de Helm y edítelo un poco:

helm fetch --untar stable/rabbitmq-ha

Para mayor comodidad, establecemos una contraseña, ErlangCookie y hacer política ha-allde modo que, de forma predeterminada, las colas se sincronicen entre todos los nodos del clúster RMQ:

rabbitmqPassword: guest
rabbitmqErlangCookie: mae9joopaol7aiVu3eechei2waiGa2we
definitions:
policies: |-
  {
    "name": "ha-all",
    "pattern": ".*",
    "vhost": "/",
    "definition": {
      "ha-mode": "all",
      "ha-sync-mode": "automatic",
      "ha-sync-batch-size": 81920
    }
  }

2. Instale el gráfico:

helm install . --name rmq-old --namespace rmq-old

3. Vaya al panel de administración de RabbitMQ, cree una nueva cola y agregue varios mensajes. Serán necesarios para que después de la migración podamos asegurarnos de que todos los datos se conservan y no hemos perdido nada:

Migración perfecta de RabbitMQ a Kubernetes

El banco de pruebas está listo: tenemos el “antiguo” RabbitMQ con datos que deben transferirse.

Migrar un clúster RabbitMQ

1. Primero, implementemos el nuevo RabbitMQ en otro espacio de nombres con el mismo ErlangCookie y contraseña del usuario. Para ello realizaremos las operaciones descritas anteriormente, cambiando el comando final de instalación de RMQ por el siguiente:

helm install . --name rmq-new --namespace rmq-new

2. Ahora necesitas fusionar el nuevo clúster con el antiguo. Para ello, dirígete a cada uno de los pods. nuevo RabbitMQ y ejecuta los comandos:

export OLD_RMQ=rabbit@rmq-old-rabbitmq-ha-0.rmq-old-rabbitmq-ha-discovery.rmq-old.svc.cluster.local && 
  rabbitmqctl stop_app && 
  rabbitmqctl join_cluster $OLD_RMQ && 
  rabbitmqctl start_app

en una variable OLD_RMQ se encuentra la dirección de uno de los nodos viejo Clúster RMQ.

Estos comandos detendrán el nodo actual. nuevo Clúster RMQ, conéctelo al clúster anterior y ejecútelo nuevamente.

3. El clúster RMQ de 6 nodos está listo:

Migración perfecta de RabbitMQ a Kubernetes

Debe esperar mientras los mensajes se sincronizan entre todos los nodos. No es difícil adivinar que el tiempo de sincronización de mensajes depende de la capacidad del hardware en el que está implementado el clúster y de la cantidad de mensajes. En el escenario descrito, solo hay 10 de ellos, por lo que los datos se sincronizaron instantáneamente, pero con una cantidad suficientemente grande de mensajes, la sincronización puede durar horas.

Entonces, el estado de sincronización:

Migración perfecta de RabbitMQ a Kubernetes

es +5 significa que los mensajes ya están en mas en 5 nodos (excepto lo indicado en el campo Node). Por tanto, la sincronización fue exitosa.

4. Todo lo que queda es cambiar la dirección RMQ en la aplicación al nuevo clúster (las acciones específicas aquí dependen de la pila de tecnología que esté utilizando y otras características específicas de la aplicación), después de lo cual puede despedirse del anterior.

Para la última operación (es decir, ya después cambiar la aplicación a un nuevo clúster) ir a cada nodo viejo cluster y ejecutar los comandos:

rabbitmqctl stop_app
rabbitmqctl reset

El clúster se “olvidó” de los nodos antiguos: puede eliminar el RMQ antiguo, momento en el que se completará el movimiento.

Nota: Si utiliza RMQ con certificados, nada cambia fundamentalmente: el proceso de transferencia se llevará a cabo exactamente igual.

Hallazgos

El esquema descrito es adecuado para casi todos los casos en los que necesitamos migrar RabbitMQ o simplemente pasar a un nuevo clúster.

En nuestro caso, las dificultades surgieron solo una vez, cuando se accedió a RMQ desde muchos lugares y no tuvimos la oportunidad de cambiar la dirección de RMQ a una nueva en todas partes. Luego lanzamos una nueva RMQ en el mismo espacio de nombres con las mismas etiquetas para que se incluyera en los servicios e ingresos existentes, y al iniciar el pod manipulamos las etiquetas a mano, eliminándolas al principio para que las solicitudes no cayeran en el RMQ vacío y volver a agregarlos después de sincronizar los mensajes.

Usamos la misma estrategia al actualizar RabbitMQ a una nueva versión con una configuración modificada: todo funcionó como un reloj.

PS

Como continuación lógica de este material, estamos preparando artículos sobre MongoDB (migración de un servidor de hardware a Kubernetes) y MySQL (cómo preparamos este DBMS dentro de Kubernetes). Se publicarán en los próximos meses.

PPS

Lea también en nuestro blog:

Fuente: habr.com

Añadir un comentario