RabbitMQ is een berichtenmakelaar geschreven in Erlang waarmee u een failovercluster kunt organiseren met volledige gegevensreplicatie over meerdere knooppunten, waarbij elk knooppunt lees- en schrijfverzoeken kan afhandelen. Omdat we veel Kubernetes-clusters in productie hebben, ondersteunen we een groot aantal RabbitMQ-installaties en werden we geconfronteerd met de noodzaak om gegevens zonder downtime van het ene cluster naar het andere te migreren.
We hadden deze operatie in minstens twee gevallen nodig:
Het overbrengen van gegevens van een RabbitMQ-cluster dat zich niet in Kubernetes bevindt, naar een nieuw – reeds “kubernetized” (d.w.z. actief in K8s-pods) – cluster.
Migratie van RabbitMQ binnen Kubernetes van de ene naamruimte naar de andere (als circuits bijvoorbeeld worden begrensd door naamruimten, dan om de infrastructuur van het ene circuit naar het andere over te dragen).
Het in het artikel voorgestelde recept is gericht op situaties (maar is er helemaal niet toe beperkt) waarin er een oud RabbitMQ-cluster is (bijvoorbeeld van 3 knooppunten), dat zich al in K8s of op sommige oude servers bevindt. Een applicatie die gehost wordt op Kubernetes (al aanwezig of in de toekomst) werkt ermee:
... en we staan voor de taak om het te migreren naar de nieuwe productie in Kubernetes.
Eerst zal de algemene aanpak van de migratie zelf worden beschreven, en daarna zullen de technische details van de implementatie ervan worden beschreven.
Migratie-algoritme
De eerste, voorbereidende fase voordat enige actie wordt ondernomen, is het controleren of de modus voor hoge beschikbaarheid is ingeschakeld in de oude RabbitMQ-installatie (HA). De reden ligt voor de hand: we willen geen gegevens verliezen. Om deze controle uit te voeren, kunt u naar het RabbitMQ-beheerpaneel gaan en op het tabblad Beheer → Beleid ervoor zorgen dat de waarde is ingesteld ha-mode: all:
De volgende stap is het opzetten van een nieuw RabbitMQ-cluster in Kubernetes-pods (in ons geval bijvoorbeeld bestaande uit 3 knooppunten, maar hun aantal kan verschillen).
Hierna voegen we de oude en nieuwe RabbitMQ-clusters samen, waardoor één cluster (van 6 knooppunten) ontstaat:
Het proces van gegevenssynchronisatie tussen de oude en nieuwe RabbitMQ-clusters wordt gestart. Zodra alle gegevens tussen alle knooppunten in het cluster zijn gesynchroniseerd, kunnen we de applicatie overschakelen om het nieuwe cluster te gebruiken:
Na deze bewerkingen is het voldoende om de oude knooppunten uit het RabbitMQ-cluster te verwijderen en kan de verhuizing als voltooid worden beschouwd:
We hebben dit schema vele malen in de productie gebruikt. Voor ons eigen gemak hebben we het echter geïmplementeerd binnen een gespecialiseerd systeem dat standaard RMQ-configuraties distribueert over meerdere Kubernetes-clusters (voor wie nieuwsgierig is: we hebben het over add-on-operatorwaarover wij onlangs verteld). Hieronder presenteren we individuele instructies die iedereen op zijn installaties kan toepassen om de voorgestelde oplossing in actie te proberen.
Laten we het in de praktijk proberen
Eisen
De details zijn heel eenvoudig:
Kubernetes-cluster (minikube werkt ook);
RabbitMQ-cluster (kan op bare metal worden ingezet en als een gewoon cluster in Kubernetes worden gemaakt op basis van de officiële Helm-grafiek).
Voor het onderstaande voorbeeld heb ik RMQ in Kubernetes geïmplementeerd en aangeroepen rmq-old.
Standvoorbereiding
1. Download het Helm-diagram en bewerk het een beetje:
helm fetch --untar stable/rabbitmq-ha
Voor het gemak hebben we een wachtwoord ingesteld, ErlangCookie en politiek maken ha-allzodat de wachtrijen standaard worden gesynchroniseerd tussen alle knooppunten van het RMQ-cluster:
3. Ga naar het RabbitMQ-beheerpaneel, maak een nieuwe wachtrij en voeg verschillende berichten toe. Ze zullen nodig zijn zodat we er na de migratie voor kunnen zorgen dat alle gegevens behouden blijven en dat we niets verloren hebben:
De testbank is klaar: we hebben de “oude” RabbitMQ met data die overgezet moeten worden.
Een RabbitMQ-cluster migreren
1. Laten we eerst de nieuwe RabbitMQ implementeren vriend naamruimte met dezelfdeErlangCookie en wachtwoord voor de gebruiker. Om dit te doen, zullen we de hierboven beschreven bewerkingen uitvoeren, waarbij we de laatste opdracht voor het installeren van RMQ wijzigen in het volgende:
helm install . --name rmq-new --namespace rmq-new
2. Nu moet je het nieuwe cluster samenvoegen met het oude. Om dit te doen, ga naar elk van de pods nieuw RabbitMQ en voer de opdrachten uit:
Variabel OLD_RMQ het adres van een van de knooppunten wordt gevonden oud RMQ-cluster.
Deze opdrachten stoppen het huidige knooppunt nieuw RMQ-cluster, koppel het aan het oude cluster en start het opnieuw.
3. RMQ-cluster van 6 knooppunten is klaar:
U moet wachten terwijl berichten tussen alle knooppunten worden gesynchroniseerd. Het is niet moeilijk te raden dat de berichtsynchronisatietijd afhangt van de capaciteit van de hardware waarop het cluster wordt ingezet en van het aantal berichten. In het beschreven scenario zijn er slechts 10, dus de gegevens werden onmiddellijk gesynchroniseerd, maar bij een voldoende groot aantal berichten kan de synchronisatie uren duren.
Dus de synchronisatiestatus:
Hier +5 betekent dat er al berichten binnen zijn meer op 5 knooppunten (behalve wat is aangegeven in het veld Node). De synchronisatie was dus succesvol.
4. Het enige dat overblijft is het omschakelen van het RMQ-adres in de applicatie naar het nieuwe cluster (de specifieke acties hier zijn afhankelijk van de technologiestack die u gebruikt en andere applicatiespecificaties), waarna u afscheid kunt nemen van het oude.
Voor de laatste operatie (d.w.z. al na het overschakelen van de applicatie naar een nieuw cluster) naar elk knooppunt oud cluster en voer de opdrachten uit:
rabbitmqctl stop_app
rabbitmqctl reset
Het cluster is de oude knooppunten ‘vergeten’: u kunt de oude RMQ verwijderen, waarna de verplaatsing voltooid zal zijn.
Noot: Als u RMQ met certificaten gebruikt, verandert er fundamenteel niets - het verhuisproces zal precies hetzelfde worden uitgevoerd.
Bevindingen
Het beschreven schema is geschikt voor bijna alle gevallen waarin we RabbitMQ moeten migreren of eenvoudigweg naar een nieuw cluster moeten verhuizen.
In ons geval deden zich slechts één keer problemen voor, toen RMQ vanaf veel plaatsen toegankelijk was, en we niet overal de mogelijkheid hadden om het RMQ-adres naar een nieuw adres te wijzigen. Vervolgens lanceerden we een nieuwe RMQ in dezelfde naamruimte met dezelfde labels, zodat deze onder bestaande services en Ingresses zou vallen, en bij het lanceren van de pod manipuleerden we de labels met de hand en verwijderden ze in het begin, zodat verzoeken niet op de lege RMQ en voeg ze weer toe nadat de berichten zijn gesynchroniseerd.
We gebruikten dezelfde strategie bij het updaten van RabbitMQ naar een nieuwe versie met een gewijzigde configuratie - alles werkte als een klok.
PS
Als logisch vervolg op dit materiaal bereiden we artikelen voor over MongoDB (migratie van een hardwareserver naar Kubernetes) en MySQL (hoe we dit DBMS binnen Kubernetes voorbereiden). Ze zullen de komende maanden worden gepubliceerd.