
RabbitMQ â en med Erlang skrivna meddelandebroker som möjliggör att skapa en fel-tolerant kluster med full datareplication över flera noder, dĂ€r varje nod kan hantera lĂ€s- och skrivförfrĂ„gningar. Med mĂ„nga kluster Kubernetes i produktion stöder vi ett stort antal RabbitMQ-installationer och har stött pĂ„ behovet av att migrera data frĂ„n ett kluster till ett annat utan driftstopp.
Denna operation var nödvÀndig för oss i minst tvÄ fall:
- Ăverföring av data frĂ„n ett RabbitMQ-kluster som inte Ă€r i Kubernetes till ett nytt â redan "kuberneteserat" (d.v.s. som fungerar i K8s-poddar) â kluster.
- Migrering av RabbitMQ inom Kubernetes frÄn ett namespace till ett annat (t.ex. om konturerna Àr avgrÀnsade av namnrymder, för att överföra infrastrukturen frÄn ett kontur till ett annat).
Receptet som föreslÄs i artikeln Àr inriktat pÄ situationer (men begrÀnsas inte till dem) dÀr det finns ett gammalt RabbitMQ-kluster (t.ex. med 3 noder) som antingen redan Àr i K8s eller pÄ nÄgra gamla servrar. Ett applikation arbetar med detta, som Àr placerad i Kubernetes (redan dÀr eller i framtiden):

⊠och vi stÄr inför uppgiften att migrera den till en ny produktion i Kubernetes.
Först kommer den allmÀnna metoden för sjÀlva migreringen att beskrivas, och först dÀrefter tekniska detaljer för dess genomförande.
Migreringsalgoritm
Det första, preliminĂ€ra steget innan nĂ„gra Ă„tgĂ€rder â kontrollera att den gamla RabbitMQ-installationen har hög tillgĂ€nglighet aktiverad (). Anledningen Ă€r uppenbar â vi vill ju inte förlora nĂ„gra data. För att genomföra denna kontroll kan du gĂ„ in i RabbitMQ:s adminpanel och under fliken Admin â Policies kontrollera att vĂ€rdet Ă€r instĂ€llt pĂ„ ha-mode: all:

NĂ€sta steg â vi upprĂ€ttar ett nytt RabbitMQ-kluster i K8s-poddar (i vĂ„rt fall till exempel med 3 noder, men antalet kan vara annat).
DÀrefter slÄr vi samman det gamla och det nya RabbitMQ-klustret, vilket ger oss ett enda kluster (med 6 noder):

Processen för datasykronisering mellan det gamla och det nya RabbitMQ-klustret initieras. NÀr alla data har synkroniserats mellan alla noder i klustret kan vi byta applikationen till att anvÀnda det nya klustret:

Efter dessa operationer rÀcker det att ta bort de gamla noderna frÄn RabbitMQ-klustret, och flytten kan anses vara avslutad:

Denna lösning har vi anvÀnt flera gÄnger i vÄr produktion. Men för vÄr egen bekvÀmlighet har vi implementerat den inom en specialiserad system, som sprider standardkonfigurationer av RMQ pÄ flera Kubernetes-kluster. (för dem som Àr nyfikna: det handlar om , om vilken vi ). Nedan kommer separata instruktioner att presenteras som var och en kan tillÀmpa pÄ sina installationer för att prova den föreslagna lösningen i praktiken.
Testar i praktiken
Krav
Specifikationerna Àr mycket enkla:
- Kubernetes-kluster (minikube fungerar ocksÄ);
- RabbitMQ-kluster (kan Àven distribueras pÄ bare metal och skapas som ett vanligt kluster i Kubernetes frÄn den officiella Helm-diagrammet).
För exemplet nedan har jag distribuerat RMQ i Kubernetes och kallat den rmq-old.
Förberedelse av stand
1. Ladda ner Helm-diagrammet och redigera det lite:
helm fetch --untar stable/rabbitmq-ha För bekvÀmlighetens skull anger vi lösenordet, ErlangCookie och gör en policy ha-all, sÄ att köerna som standard synkroniseras mellan alla noder i RMQ-klustret:
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. Installera diagrammet:
helm install . --name rmq-old --namespace rmq-old3. GÄ in i RabbitMQ-administrationsgrÀnssnittet, skapa en ny kö och lÀgg till nÄgra meddelanden. De kommer att behövas för att vi efter migrationen ska kunna sÀkerstÀlla att alla data har bevarats och att vi inte har förlorat nÄgot:
![]()
Teststandet Àr klart: vi har en 'gammal' RabbitMQ med data som behöver flyttas.
Migration av RabbitMQ-kluster
1. Först ska vi distribuera en ny RabbitMQ i annan namnrymden med samma ErlangCookie och lösenord för anvÀndaren. För detta gör vi de ovan beskrivna operationerna, Àndrar den slutliga installationskommandot för RMQ till följande:
helm install . --name rmq-new --namespace rmq-new2. Nu behöver den nya klustern sammanfogas med den gamla. För detta gÄr vi in i varje av pod'arna ny RabbitMQ och kör kommandona:
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 I variabeln OLD_RMQ Àr adressen till en av noderna i den gamla RMQ-klustret.
Dessa kommandon kommer att stoppa den aktuella noden ny i RMQ-klustret, koppla den till det gamla klustret och starta den igen.
3. RMQ-klustret med 6 noder Àr klart:

Du mÄste vÀnta tills meddelandena synkroniseras mellan alla noder. Det Àr inte svÄrt att gissa att tiden för meddelandesynkronisering beror pÄ kapaciteten hos den hÄrdvara dÀr klustret Àr implementerat och antalet meddelanden. I det beskrivna scenariot finns det totalt 10 meddelanden, sÄ datan synkroniserades omedelbart, men med ett tillrÀckligt stort antal meddelanden kan synkroniseringen ta timmar.
SÄ, status för synkronisering:

HÀr +5 betyder att meddelandena redan finns om pÄ 5 noder (förutom den som anges i fÀltet Node). DÀrmed har synkroniseringen genomförts framgÄngsrikt.
4. Det ÄterstÄr bara att vÀxla applikationens RMQ-adress till det nya klustret (specifika ÄtgÀrder hÀr beror pÄ vilken teknikstack du anvÀnder och andra specifika egenskaper hos applikationen), efter vilket du kan sÀga adjö till det gamla.
För den sista operationen (dvs. efter vÀxling av applikationen till det nya klustret), gÄr vi in pÄ varje nod i den gamla i klustret och utför kommandona:
rabbitmqctl stop_app
rabbitmqctl resetKlustret har "glömt" de gamla noderna: du kan ta bort den gamla RMQ, och flytten kommer att vara avslutad.
AnmĂ€rkning: Om du anvĂ€nder RMQ med certifikat förĂ€ndras ingenting principiellt â flyttprocessen kommer att genomföras pĂ„ precis samma sĂ€tt.
Slutsatser
Det beskrivna schemat passar praktiskt taget för alla situationer nÀr vi behöver flytta RabbitMQ eller helt enkelt flytta till ett nytt kluster.
I vÄrt fall uppstod svÄrigheter bara en gÄng, nÀr RMQ anropades frÄn mÄnga stÀllen och vi inte hade möjlighet att Àndra RMQ-adressen överallt. DÄ startade vi en ny RMQ i samma namespaces med samma etiketter, sÄ att den skulle matcha de redan existerande tjÀnsterna och Ingressarna, och nÀr vi startade podden manipulerade vi etiketter manuellt, tog bort dem i början sÄ att ingen förfrÄgan hamnade pÄ den tomma RMQ, och lade tillbaka dem efter synkronisering av meddelanden.
Samma strategi tillĂ€mpade vi vid uppgradering av RabbitMQ till en ny version med Ă€ndrad konfiguration â allt fungerade som en klocka.
P.S.
Som en logisk fortsÀttning pÄ detta material förbereder vi artiklar om MongoDB (migration frÄn en fysisk server till Kubernetes) och MySQL (hur vi förbereder denna DBMS inom Kubernetes). De kommer att publiceras inom de kommande mÄnaderna.
P.P.S.
LÀs Àven i vÄr blogg:
- «»;
- «».
KĂ€lla: habr.com
