Migration transparente de RabbitMQ vers Kubernetes

Migration transparente de RabbitMQ vers Kubernetes

RabbitMQ est un courtier de messages écrit en Erlang qui vous permet d'organiser un cluster de basculement avec une réplication complète des données sur plusieurs nœuds, où chaque nœud peut répondre aux demandes de lecture et d'écriture. Ayant de nombreux clusters Kubernetes en production, nous prenons en charge un grand nombre d'installations RabbitMQ et avons été confrontés à la nécessité de migrer les données d'un cluster à un autre sans temps d'arrêt.

Nous avons eu besoin de cette opération dans au moins deux cas :

  1. Transfert de données d'un cluster RabbitMQ qui n'est pas situé dans Kubernetes vers un nouveau cluster – déjà « kubernetisé » (c'est-à-dire fonctionnant dans les pods K8s).
  2. Migration de RabbitMQ au sein de Kubernetes d'un espace de noms à un autre (par exemple, si les circuits sont délimités par des espaces de noms, alors pour transférer l'infrastructure d'un circuit à un autre).

La recette proposée dans l'article se concentre sur les situations (mais ne s'y limite pas du tout) dans lesquelles il existe un ancien cluster RabbitMQ (par exemple, de 3 nœuds), situé soit déjà dans les K8, soit sur certains anciens serveurs. Une application hébergée sur Kubernetes (déjà là ou dans le futur) fonctionne avec :

Migration transparente de RabbitMQ vers Kubernetes

... et nous sommes confrontés à la tâche de le migrer vers la nouvelle production dans Kubernetes.

Tout d’abord, l’approche générale de la migration elle-même sera décrite, puis les détails techniques de sa mise en œuvre seront décrits.

Algorithme de migration

La première étape, préliminaire, avant toute action consiste à vérifier que le mode haute disponibilité est activé dans l'ancienne installation de RabbitMQ (HA). La raison est évidente : nous ne voulons perdre aucune donnée. Pour effectuer cette vérification, vous pouvez accéder au panneau d'administration de RabbitMQ et dans l'onglet Admin → Politiques, assurez-vous que la valeur est définie ha-mode: all:

Migration transparente de RabbitMQ vers Kubernetes

L'étape suivante consiste à créer un nouveau cluster RabbitMQ dans des pods Kubernetes (dans notre cas, par exemple, composé de 3 nœuds, mais leur nombre peut être différent).

Après cela, nous fusionnons l'ancien et le nouveau cluster RabbitMQ, obtenant un seul cluster (de 6 nœuds) :

Migration transparente de RabbitMQ vers Kubernetes

Le processus de synchronisation des données entre l'ancien et le nouveau cluster RabbitMQ est lancé. Une fois toutes les données synchronisées entre tous les nœuds du cluster, nous pouvons changer l'application pour utiliser le nouveau cluster :

Migration transparente de RabbitMQ vers Kubernetes

Après ces opérations, il suffit de supprimer les anciens nœuds du cluster RabbitMQ, et le déplacement peut être considéré comme terminé :

Migration transparente de RabbitMQ vers Kubernetes

Nous avons utilisé ce schéma à plusieurs reprises en production. Cependant, pour notre propre commodité, nous l'avons implémenté dans un système spécialisé qui distribue les configurations RMQ standard sur plusieurs clusters Kubernetes. (pour les curieux : on parle de opérateur complémentairedont nous je viens de le dire récemment). Nous présenterons ci-dessous des instructions individuelles que chacun peut appliquer sur ses installations pour essayer la solution proposée en action.

Essayons-le en pratique

Exigences

Les détails sont très simples :

  1. Cluster Kubernetes (minikube fonctionnera également) ;
  2. Cluster RabbitMQ (peut être déployé sur du métal nu et créé comme un cluster standard dans Kubernetes à partir de la charte Helm officielle).

Pour l'exemple ci-dessous, j'ai déployé RMQ sur Kubernetes et je l'ai appelé rmq-old.

Préparation des stands

1. Téléchargez la charte Helm et modifiez-la un peu :

helm fetch --untar stable/rabbitmq-ha

Pour plus de commodité, nous définissons un mot de passe, ErlangCookie et faire de la politique ha-allafin que par défaut les files d'attente soient synchronisées entre tous les nœuds du 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. Installez la carte :

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

3. Accédez au panneau d'administration RabbitMQ, créez une nouvelle file d'attente et ajoutez plusieurs messages. Ils seront nécessaires pour qu'après la migration, nous puissions nous assurer que toutes les données sont préservées et que nous n'avons rien perdu :

Migration transparente de RabbitMQ vers Kubernetes

Le banc de test est prêt : nous avons le « vieux » RabbitMQ avec les données à transférer.

Migration d'un cluster RabbitMQ

1. Tout d’abord, déployons le nouveau RabbitMQ dans autre espace de noms avec le même ErlangCookie et le mot de passe de l'utilisateur. Pour ce faire, nous effectuerons les opérations décrites ci-dessus, en modifiant la commande finale d'installation de RMQ comme suit :

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

2. Vous devez maintenant fusionner le nouveau cluster avec l'ancien. Pour cela, rendez-vous sur chacun des pods nouveau RabbitMQ et exécutez les commandes :

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 variable OLD_RMQ l'adresse d'un des nœuds est trouvée vieux Grappe RMQ.

Ces commandes arrêteront le nœud actuel nouveau Cluster RMQ, attachez-le à l'ancien cluster et relancez-le.

3. Le cluster RMQ de 6 nœuds est prêt :

Migration transparente de RabbitMQ vers Kubernetes

Vous devez attendre que les messages soient synchronisés entre tous les nœuds. Il n'est pas difficile de deviner que le temps de synchronisation des messages dépend de la capacité du matériel sur lequel le cluster est déployé et du nombre de messages. Dans le scénario décrit, il n'y en a que 10, les données ont donc été synchronisées instantanément, mais avec un nombre de messages suffisamment important, la synchronisation peut durer des heures.

Donc, l'état de synchronisation :

Migration transparente de RabbitMQ vers Kubernetes

il est +5 signifie que les messages sont déjà arrivés ещё sur 5 nœuds (sauf ce qui est indiqué dans le champ Node). La synchronisation a donc réussi.

4. Il ne reste plus qu'à basculer l'adresse RMQ de l'application vers le nouveau cluster (les actions spécifiques ici dépendent de la pile technologique que vous utilisez et d'autres spécificités de l'application), après quoi vous pourrez dire au revoir à l'ancienne.

Pour la dernière opération (c'est-à-dire déjà après basculer l'application vers un nouveau cluster) accédez à chaque nœud vieux cluster et exécutez les commandes :

rabbitmqctl stop_app
rabbitmqctl reset

Le cluster a « oublié » les anciens nœuds : vous pouvez supprimer l'ancien RMQ, auquel cas le déplacement sera terminé.

Noter: Si vous utilisez RMQ avec des certificats, rien ne change fondamentalement - le processus de déplacement sera effectué exactement de la même manière.

résultats

Le schéma décrit convient à presque tous les cas où nous devons migrer RabbitMQ ou simplement passer à un nouveau cluster.

Dans notre cas, les difficultés ne sont survenues qu'une seule fois, lorsque RMQ était accessible depuis de nombreux endroits, et nous n'avons pas eu la possibilité de changer l'adresse RMQ pour une nouvelle partout. Ensuite, nous avons lancé un nouveau RMQ dans le même espace de noms avec les mêmes étiquettes afin qu'il relève des services et entrées existants, et lors du lancement du pod, nous avons manipulé les étiquettes à la main, en les supprimant au début afin que les requêtes ne tombent pas sur le RMQ vide, et les rajouter une fois les messages synchronisés.

Nous avons utilisé la même stratégie lors de la mise à jour de RabbitMQ vers une nouvelle version avec une configuration modifiée : tout a fonctionné comme une horloge.

PS

Dans la continuité logique de ce matériel, nous préparons des articles sur MongoDB (migration d'un serveur matériel vers Kubernetes) et MySQL (comment nous préparons ce SGBD dans Kubernetes). Ils seront publiés dans les prochains mois.

PPS

A lire aussi sur notre blog :

Source: habr.com

Ajouter un commentaire