
RabbitMQ – ein in Erlang geschriebener Nachrichtendienst, der es ermöglicht, ein fehlertolerantes Cluster mit vollständiger Datenreplikation über mehrere Knoten zu organisieren, wobei jeder Knoten Lese- und Schreibanfragen bedienen kann. Mit zahlreichen Kubernetes-Clustern in der Produktionsnutzung unterstützen wir eine Vielzahl von RabbitMQ-Installationen und standen vor der Notwendigkeit, Daten von einem Cluster in ein anderes zu migrieren, ohne dabei Ausfallzeiten zu verursachen.
Diese Operation war für uns mindestens in zwei Fällen notwendig:
- Die Übertragung von Daten aus einem RabbitMQ-Cluster, das sich nicht in Kubernetes befindet, in ein neues – bereits „kubernetisiertes“ (d.h. funktionierend in K8s-Pods) – Cluster.
- Die Migration von RabbitMQ innerhalb von Kubernetes von einem Namespace in einen anderen (zum Beispiel, wenn die Umgebungen durch Namensräume voneinander getrennt sind, um die Infrastruktur von einer Umgebung in eine andere zu verschieben).
Das in diesem Artikel vorgeschlagene Rezept richtet sich an Situationen (ist aber nicht darauf beschränkt), in denen ein altes RabbitMQ-Cluster (zum Beispiel aus 3 Knoten) entweder bereits in K8s oder auf älteren Servern betrieben wird. Es arbeitet mit einer Anwendung, die in Kubernetes platziert ist (bereits dort oder perspektivisch):

… und wir stehen vor der Aufgabe, es in die neue Produktion in Kubernetes zu migrieren.
Zuerst wird der allgemeine Ansatz für die Migration selbst beschrieben, gefolgt von den technischen Details zur Umsetzung.
Migrationsalgorithmus
Der erste, vorbereitende Schritt vor jeglichen Maßnahmen ist die Überprüfung, dass in der alten RabbitMQ-Installation der Hochverfügbarkeitsmodus aktiviert ist (). Der Grund ist offensichtlich – wir möchten schließlich keine Daten verlieren. Um diese Überprüfung durchzuführen, kann man das Admin-Panel von RabbitMQ aufrufen und im Tab Admin → Policies sicherstellen, dass der Wert gesetzt ist. ha-mode: all:

Der nächste Schritt besteht darin, einen neuen RabbitMQ-Cluster in den Pods von Kubernetes zu starten (in unserem Fall beispielsweise bestehend aus 3 Knoten, aber ihre Anzahl kann auch variieren).
Danach verbinden wir den alten und den neuen RabbitMQ-Cluster, um einen einzigen Cluster (bestehend aus 6 Knoten) zu erhalten:

Der Prozess der Datensynchronisation zwischen dem alten und dem neuen RabbitMQ-Cluster wird initiiert. Nachdem alle Daten zwischen den Knoten im Cluster synchronisiert sind, können wir die Anwendung auf den neuen Cluster umschalten:

Nach diesen Vorgängen reicht es aus, die alten Knoten aus dem RabbitMQ-Cluster zu entfernen, und der Umzug kann als abgeschlossen betrachtet werden:

Dieses Schema haben wir mehrfach in unserer Produktionsumgebung verwendet. Für unseren eigenen Komfort haben wir es jedoch in einem spezialisierten System implementiert, das Standardkonfigurationen von RMQ auf mehrere Kubernetes-Cluster verteilt. (für die Neugierigen: es geht um , über das wir ). Im Folgenden werden einige Anleitungen präsentiert, die jeder auf seinen Installationen anwenden kann, um die vorgeschlagene Lösung in der Praxis auszuprobieren.
Praktisch testen
Anforderungen
Die Voraussetzungen sind sehr einfach:
- Kubernetes-Cluster (minikube ist auch geeignet);
- RabbitMQ-Cluster (kann sowohl auf bare metal bereitgestellt werden als auch als herkömmlicher Cluster in Kubernetes aus dem offiziellen Helm-Chart erstellt werden).
Für das unten beschriebene Beispiel habe ich RMQ in Kubernetes bereitgestellt und es " rmq-old.
" genannt.
Standvorbereitung
1. Laden Sie das Helm-Chart herunter und bearbeiten Sie es ein wenig: helm fetch --untar stable/rabbitmq-ha Zur Vereinfachung setzen wir ein Passwort, ErlangCookie und erstellen die Policy, damit die Warteschlangen standardmäßig zwischen allen Knoten des RMQ-Clusters synchronisiert werden:
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. Chart installieren:
helm install . --name rmq-old --namespace rmq-old3. Melden Sie sich im RabbitMQ-Adminbereich an, erstellen Sie eine neue Warteschlange und fügen Sie einige Nachrichten hinzu. Diese werden benötigt, um nach der Migration sicherzustellen, dass alle Daten erhalten geblieben sind und nichts verloren ging:
![]()
Die Testumgebung ist bereit: Wir haben ein „altes“ RabbitMQ mit den Daten, die migriert werden müssen.
Migration des RabbitMQ-Clusters
1. Zuerst setzen wir ein neues RabbitMQ auf in einem Freund gesprochen dem Namensraum mit den gleichen Zur Vereinfachung setzen wir ein Passwort, Benutzerdaten und Passwort. Dazu führen wir die oben beschriebenen Schritte durch und ändern den Installationsbefehl für RMQ wie folgt:
helm install . --name rmq-new --namespace rmq-new2. Jetzt ist es erforderlich, das neue Cluster mit dem alten zu verbinden. Gehen Sie dazu in jeden der Pods des neuen RabbitMQ und führen Sie die folgenden Befehle aus:
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 In der Variablen OLD_RMQ befindet sich die Adresse eines der Knoten des alten RMQ-Clusters.
Diese Befehle stoppen den aktuellen Knoten des neuen des RMQ-Clusters, fügen ihn dem alten Cluster hinzu und starten ihn erneut.
3. Das RMQ-Cluster mit 6 Knoten ist bereit:

Es ist notwendig, zu warten, bis die Nachrichten zwischen allen Knoten synchronisiert sind. Es ist leicht zu erraten, dass die Zeit für die Nachrichtensynchronisation von der Hardware-Performance des Clusters und der Anzahl der Nachrichten abhängt. In dem beschriebenen Szenario gibt es nur 10 Nachrichten, sodass die Daten sofort synchronisiert wurden, aber bei einer ausreichend hohen Anzahl von Nachrichten kann die Synchronisation Stunden in Anspruch nehmen.
Also, der Synchronisierungsstatus:

Hier +5 bedeutet, dass die Nachrichten bereits noch auf 5 Knoten (außer dem, der im Feld angegeben ist Knoten). Somit war die Synchronisation erfolgreich.
4. Es bleibt nur noch, die RMQ-Adresse in der Anwendung auf den neuen Cluster umzuschalten (konkrete Schritte hängen hier von Ihrem verwendeten Technologie-Stack und spezifischen Eigenschaften der Anwendung ab), danach können Sie sich vom alten verabschieden.
Für den letzten Schritt (d.h. das nach Umschalten der Anwendung auf den neuen Cluster) gehen wir auf jeden Knoten des alten des Clusters und führen die Befehle aus:
rabbitmqctl stop_app
rabbitmqctl resetDer Cluster hat die alten Knoten „vergessen“: Sie können den alten RMQ löschen, womit der Umzug abgeschlossen ist.
Hinweis: Wenn Sie RMQ mit Zertifikaten verwenden, bleibt alles prinzipiell unverändert – der Migrationsprozess erfolgt genau wie zuvor.
Fazit
Das beschriebene Schema eignet sich praktisch für alle Szenarien, in denen wir RabbitMQ umziehen oder einfach in ein neues Cluster wechseln müssen.
In unserem Fall gab es nur einmal Schwierigkeiten, als RMQ von vielen Stellen gleichzeitig angesprochen wurde, und wir nicht überall die RMQ-Adresse auf die neue ändern konnten. In diesem Fall haben wir RMQ im gleichen Namensraum mit denselben Labels gestartet, damit es unter die bestehenden Dienste und Ingresses fiel, und bei der manuellen Pod-Bereitstellung haben wir die Labels vorübergehend entfernt, sodass keine Anfragen an das leere RMQ gingen, und sie nach der Synchronisierung der Nachrichten wieder hinzugefügt.
Die gleiche Strategie haben wir bei der Aktualisierung von RabbitMQ auf eine neue Version mit geänderter Konfiguration angewendet – alles lief einwandfrei.
P.S.
Als logische Fortsetzung dieses Materials bereiten wir Artikel über MongoDB (Migration von einem physischen Server zu Kubernetes) und MySQL (wie wir dieses DBMS innerhalb von Kubernetes vorbereiten) vor. Diese werden in den nächsten Monaten veröffentlicht.
P.P.S.
Lesen Sie auch in unserem Blog:
- «»;
- «».
Quelle: habr.com
