Komplexe Migration von RabbitMQ in Kubernetes

Komplexe Migration von RabbitMQ in Kubernetes

RabbitMQ – ein auf Erlang basierender Nachrichtenbroker, der es ermöglicht, ein ausfallsicheres Cluster mit vollständiger Datenreplikation über mehrere Knoten zu organisieren, wobei jeder Knoten Lese- und Schreibanfragen bedienen kann. Mit einer Vielzahl von Kubernetes-Clustern im Produktionsbetrieb unterstützen wir zahlreiche RabbitMQ-Installationen und stehen vor der Herausforderung, Daten von einem Cluster zu einem anderen ohne Ausfallzeiten zu migrieren.

Diese Operation war für uns in mindestens zwei Fällen notwendig:

  1. Die Übertragung von Daten aus einem RabbitMQ-Cluster, das sich nicht in Kubernetes befindet, in ein neues, bereits „kubernetisiertes“ Cluster (d.h. das in K8s-Pods funktioniert).
  2. Die Migration von RabbitMQ innerhalb von Kubernetes von einem Namespace in einen anderen (z.B. wenn die Grenzen durch Namensräume getrennt sind, um Infrastruktur von einem Bereich in einen anderen zu übertragen).

Das in diesem Artikel vorgeschlagene Rezept richtet sich an Situationen (aber ist keineswegs darauf beschränkt), in denen ein altes RabbitMQ-Cluster (z.B. aus 3 Knoten) vorhanden ist, das entweder bereits in K8s ist oder auf alten Servern läuft. Damit arbeitet eine Anwendung, die in Kubernetes gehostet wird (bereits dort oder in der Zukunft):

Komplexe Migration von RabbitMQ in Kubernetes

… und wir stehen vor der Aufgabe, diese in ein neues Produktionsumfeld in Kubernetes zu migrieren.

Zunächst wird der allgemeine Ansatz zur Migration beschrieben, gefolgt von den technischen Details zur Umsetzung.

Migrationsalgorithmus

Der erste, vorbereitende Schritt vor irgendwelchen Maßnahmen ist die Überprüfung, dass in der alten RabbitMQ-Installation der Hochverfügbarkeitsmodus aktiviert ist (HA). Der Grund ist offensichtlich – wir wollen schließlich keine Daten verlieren. Um diese Überprüfung durchzuführen, kann man das RabbitMQ-Admin-Panel aufrufen und im Reiter Admin → Policies überprüfen, ob der Wert eingestellt ist. ha-mode: all:

Komplexe Migration von RabbitMQ in Kubernetes

Der nächste Schritt besteht darin, ein neues RabbitMQ-Cluster in K8s-Pods einzurichten (in unserem Fall zum Beispiel aus 3 Knoten, aber die Anzahl kann auch anders sein).

Anschließend verbinden wir das alte und das neue RabbitMQ-Cluster zu einem einzigen Cluster (aus 6 Knoten):

Komplexe Migration von RabbitMQ in Kubernetes

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

Komplexe Migration von RabbitMQ in Kubernetes

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

Komplexe Migration von RabbitMQ in Kubernetes

Dieses Schema haben wir mehrfach in unserer Produktion angewendet. Für unsere eigene Bequemlichkeit haben wir es jedoch im Rahmen eines spezialisierten Systems implementiert, das Standardkonfigurationen von RMQ auf vielen Kubernetes-Clustern verteilt. (für diejenigen, die es interessiert: es geht um Addon-Operator, über die wir vor kurzem haben wir berichtet). Im Folgenden werden einzeln ausgewählte Anweisungen präsentiert, die jeder auf seinen Installationen anwenden kann, um die vorgeschlagene Lösung in der Praxis auszuprobieren.

Praktischer Versuch

Anforderungen

Die Voraussetzungen sind sehr einfach:

  1. Kubernetes-Cluster (minikube ist auch geeignet);
  2. RabbitMQ-Cluster (kann sowohl auf Bare Metal als auch als gewöhnlicher Cluster in Kubernetes aus dem offiziellen Helm-Chart bereitgestellt werden).

Für das nachfolgend beschriebene Beispiel habe ich RMQ in Kubernetes bereitgestellt und es " rmq-old.

" genannt.

Standausbereitung

1. Wir laden das Helm-Chart herunter und bearbeiten es ein wenig:

helm fetch --untar stable/rabbitmq-ha Für die Bequemlichkeit setzen wir das Passwort, ErlangCookie und erstellen eine Policyha-all, um sicherzustellen, dass 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. Wir installieren das Chart:

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

3. Wir gehen ins RabbitMQ-Adminpanel, erstellen eine neue Warteschlange und fügen einige Nachrichten hinzu. Diese werden benötigt, um sicherzustellen, dass nach der Migration alle Daten erhalten geblieben sind und nichts verloren gegangen ist:

Komplexe Migration von RabbitMQ in Kubernetes

Der Teststand ist bereit: Wir haben ein "altes" RabbitMQ mit den Daten, die migriert werden müssen.

Migration des RabbitMQ-Clusters

1. Zunächst lassen wir ein neues RabbitMQ im Freund beraten Namespace mit denselben Für die Bequemlichkeit setzen wir das Passwort, Und Passwort für den Benutzer. Dazu führen wir die oben beschriebenen Schritte aus und ändern den Endbefehl zur Installation von RMQ auf den folgenden:

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

2. Jetzt müssen wir das neue Cluster mit dem alten verbinden. Dazu gehen wir in jeden der Pods neu von RabbitMQ und führen 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 ist die Adresse eines der Knoten des alten RMQ-Clusters.

Diese Befehle stoppen den aktuellen Knoten neu des RMQ-Clusters, fügen ihn dem alten Cluster hinzu und starten ihn erneut.

3. Das RMQ-Cluster mit 6 Knoten ist bereit:

Komplexe Migration von RabbitMQ in Kubernetes

Es ist notwendig, zu warten, bis die Nachrichten zwischen allen Knoten synchronisiert sind. Es ist nicht schwer zu erraten, dass die Zeit für die Nachrichtensynchronisierung von der Hardwareleistung des Clusters abhängt und von der Anzahl der Nachrichten. In dem beschriebenen Szenario gibt es insgesamt 10 Nachrichten, daher wurden die Daten sofort synchronisiert, aber bei einer ausreichend hohen Anzahl von Nachrichten kann die Synchronisierung Stunden dauern.

Also, der Synchronisierungsstatus:

Komplexe Migration von RabbitMQ in Kubernetes

Hier +5 bedeutet, dass die Nachrichten bereits noch auf 5 Knoten (außer dem, der im Feld angegeben ist Node). Somit war die Synchronisation erfolgreich.

4. Es bleibt nur, die Adresse RMQ in der Anwendung auf das neue Cluster umzuschalten (die spezifischen Schritte hängen hier von dem Tech-Stack ab, den Sie verwenden, und anderen Besonderheiten der Anwendung), danach können Sie sich von der alten verabschieden.

Für den letzten Schritt (d.h. das nach Umschalten der Anwendung auf das neue Cluster) gehen wir auf jeden Knoten des alten des Clusters und führen die Befehle aus:

rabbitmqctl stop_app
rabbitmqctl reset

Der Cluster hat die alten Knoten "vergessen": der alte RMQ kann entfernt werden, damit der Umzug abgeschlossen ist.

Hinweis: Wenn Sie RMQ mit Zertifikaten verwenden, ändert sich grundlegend nichts — der Umzug erfolgt genau so.

Das DBMS Tarantool ist ein attraktives, zukunftsträchtiges Produkt zur Erstellung von hochbelasteten Anwendungen.

Das beschriebene Schema passt praktisch für alle Fälle, in denen wir RabbitMQ übertragen oder einfach in ein neues Cluster umziehen müssen.

In unserem Fall gab es Schwierigkeiten nur einmal, als auf RMQ von vielen Stellen zugegriffen wurde und wir nicht die Möglichkeit hatten, überall die RMQ-Adresse auf die neue zu ändern. In diesem Fall starteten wir den neuen RMQ im gleichen Namensraum mit denselben Labels, damit er unter bestehenden Diensten und Ingresses erfasst wurde, und beim manuellen Starten des Pods manipulierten wir die Labels, indem wir sie zu Beginn entfernten, damit keine Anfragen an den leeren RMQ gesendet wurden, und fügten sie nach der Synchronisierung der Nachrichten wieder hinzu.

Die gleiche Strategie wandten wir bei der Aktualisierung von RabbitMQ auf eine neue Version mit geänderter Konfiguration an – alles funktionierte wie am Schnürchen.

P.S.

Als logische Fortsetzung dieses Materials bereiten wir Artikel über MongoDB (Migration von einem physischen Server nach Kubernetes) und MySQL (wie wir diese DB innerhalb von Kubernetes vorbereiten) vor. Sie werden in den kommenden Monaten veröffentlicht.

P.P.S.

Lesen Sie auch in unserem Blog:

Quelle: habr.com

60GB SSD 8Gb DDR4