Migração descomplicada do RabbitMQ para Kubernetes

Migração descomplicada do RabbitMQ para Kubernetes

RabbitMQ – um broker de mensagens escrito em Erlang, que permite organizar um cluster tolerante a falhas com replicação completa de dados em múltiplos nós, onde cada nó pode atender a solicitações de leitura e gravação. Com múltiplos clusters Kubernetes em operação de produção, nós suportamos um grande número de instalações do RabbitMQ e enfrentamos a necessidade de migrar dados de um cluster para outro sem tempo de inatividade.

Esta operação foi necessária para nós em pelo menos dois casos:

  1. Transferir dados de um cluster RabbitMQ que não está no Kubernetes para um novo cluster já "kubernetizado" (ou seja, funcionando em pods K8s).
  2. Migração do RabbitMQ dentro do Kubernetes de um namespace para outro (por exemplo, se os contornos estão separados por namespaces, então para transferir a infraestrutura de um contorno para outro).

A receita proposta no artigo é voltada para situações (mas não se limita a elas) em que há um antigo cluster RabbitMQ (por exemplo, de 3 nós), que já esteja em K8s ou em alguns servidores antigos. Um aplicativo que já está no Kubernetes (ou com a intenção de estar) interage com ele:

Migração descomplicada do RabbitMQ para Kubernetes

… e temos a tarefa de sua migração para um novo ambiente de produção no Kubernetes.

Primeiro, será descrita a abordagem geral à migração, e só depois os detalhes técnicos de sua implementação.

Algoritmo de migração

A primeira etapa preliminar antes de qualquer ação é verificar se na antiga instalação do RabbitMQ o modo de alta disponibilidade está ativado (HA). A razão é evidente – pois não queremos perder dados. Para realizar essa verificação, podemos acessar o painel administrativo do RabbitMQ e, na aba Admin → Policies, confirmar que está definido o valor ha-mode: all:

Migração descomplicada do RabbitMQ para Kubernetes

O próximo passo é levantar um novo cluster RabbitMQ em pods Kubernetes (no nosso caso, por exemplo, composto por 3 nós, mas seu número pode ser diferente).

Depois disso, nós unimos os antigos e novos clusters RabbitMQ, formando um único cluster (de 6 nós):

Migração descomplicada do RabbitMQ para Kubernetes

Inicia-se o processo de sincronização de dados entre os antigos e novos clusters RabbitMQ. Após a sincronização de todos os dados entre todos os nós do cluster, podemos mudar o aplicativo para usar o novo cluster:

Migração descomplicada do RabbitMQ para Kubernetes

Após essas operações, basta remover os nós antigos do cluster RabbitMQ, e a migração pode ser considerada concluída:

Migração descomplicada do RabbitMQ para Kubernetes

Este esquema foi aplicado várias vezes em nossa produção. No entanto, para nossa conveniência, realizamos isso em um sistema especializado que distribui configurações padrão do RMQ em múltiplos clusters Kubernetes. (para aqueles que estão curiosos: trata-se do addon-operator, sobre o qual nós falamos recentemente.)Abaixo, estarão apresentadas instruções específicas que qualquer um pode aplicar em suas instalações para experimentar a solução proposta em ação.

Vamos tentar na prática.

Requisitos

Os requisitos são muito simples:

  1. Cluster Kubernetes (minikube também serve);
  2. Cluster RabbitMQ (pode ser implementado em bare metal ou como um cluster comum em Kubernetes a partir do chart oficial do Helm).

Para o exemplo descrito abaixo, implantei o RMQ no Kubernetes e o nomeei como rmq-old..

Preparação do ambiente.

1. Baixaremos o chart do Helm e faremos algumas edições:

helm fetch --untar stable/rabbitmq-ha

Para conveniência, definimos a senha, ErlangCookie, e criamos a política ha-all,para que, por padrão, as filas sejam sincronizadas entre todos os nós do cluster 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. Instalamos o chart:

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

3. Acesse o painel administrativo do RabbitMQ, crie uma nova fila e adicione algumas mensagens. Elas serão necessárias para que, após a migração, possamos garantir que todos os dados foram preservados e que não perdemos nada:

Migração descomplicada do RabbitMQ para Kubernetes

O ambiente de teste está pronto: temos um RabbitMQ 'antigo' com os dados que precisam ser transferidos.

Migração do cluster RabbitMQ.

1. Para começar, vamos implantar um novo RabbitMQ no um amigo espaço de nomes com as mesmas ErlangCookie, e senha para o usuário. Para isso, realizamos as operações descritas acima, alterando o comando final de instalação do RMQ para o seguinte:

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

2. Agora é necessário unir o novo cluster com o antigo. Para isso, acessamos cada um dos pods novos RabbitMQ e executamos os 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

Na variável OLD_RMQ é o endereço de um dos nós do antigo cluster RMQ.

Esses comandos interromperão o nó atual novos do cluster RMQ, o conectarão ao antigo cluster e o reiniciarão.

3. O cluster RMQ de 6 nós está pronto:

Migração descomplicada do RabbitMQ para Kubernetes

É necessário esperar enquanto as mensagens são sincronizadas entre todos os nós. Não é difícil adivinhar que o tempo de sincronização das mensagens depende da capacidade do hardware em que o cluster está implementado e da quantidade de mensagens. No cenário descrito, há apenas 10, portanto os dados foram sincronizados instantaneamente, mas com um número suficientemente grande de mensagens, a sincronização pode levar horas.

Então, o status da sincronização:

Migração descomplicada do RabbitMQ para Kubernetes

Aqui +5 significa que as mensagens já estão ainda em 5 nós (além do que está indicado no campo Nó). Assim, a sincronização foi bem-sucedida.

4. Resta apenas mudar no aplicativo o endereço RMQ para o novo cluster (as ações específicas aqui dependem da pilha tecnológica que você está usando e de outras especificidades do aplicativo), após o que você pode se despedir do antigo.

Para a última operação (ou seja, já após mudando o aplicativo para o novo cluster), acesse cada nó do antigo do cluster e execute os comandos:

rabbitmqctl stop_app
rabbitmqctl reset

O cluster 'esqueceu' os nós antigos: agora você pode remover o antigo RMQ, e a migração estará concluída.

Nota: Se você estiver usando RMQ com certificados, o princípio não muda — o processo de migração será realizado exatamente da mesma forma.

Como resultado, obtemos um serviço de "monitoramento como serviço", automatizado na linha de produção de integração contínua. O desenvolvedor ou testador precisa apenas definir a lista de métricas em um arquivo JSON, e tudo o mais acontece automaticamente. Obtemos um controle de qualidade transparente dos lançamentos: todas as notificações sobre desempenho, consumo de recursos ou regressões arquitetônicas.

O esquema descrito é adequado praticamente para todos os casos em que precisamos transferir o RabbitMQ ou simplesmente migrar para um novo cluster.

No nosso caso, as dificuldades ocorreram apenas uma vez, quando o RMQ era acessado de muitos locais, e não tínhamos a possibilidade de mudar o endereço RMQ para o novo em todos eles. Nesse caso, executamos um novo RMQ no mesmo namespace com rótulos iguais, para que ele se encaixasse nos serviços e Ingress existentes, e ao iniciar o pod manualmente manipulamos os rótulos, removendo-os no início, para que o RMQ vazio não recebesse solicitações, e adicionando-os de volta após a sincronização das mensagens.

Aplicamos a mesma estratégia ao atualizar o RabbitMQ para uma nova versão com configuração alterada — tudo funcionou como um relógio.

P.S.

Como uma continuação lógica deste material, estamos preparando artigos sobre MongoDB (migração de servidor físico para Kubernetes) e MySQL (como preparamos este SGBD dentro do Kubernetes). Eles serão publicados nos próximos meses.

P.P.S.

Confira também em nosso blog:

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster