Sömlös migrering av RabbitMQ till Kubernetes

Sömlös migrering av RabbitMQ till Kubernetes

RabbitMQ är en meddelandeförmedlare skriven i Erlang som låter dig organisera ett failover-kluster med full datareplikering över flera noder, där varje nod kan betjäna läs- och skrivförfrågningar. Med många Kubernetes-kluster i produktionsdrift stöder vi ett stort antal RabbitMQ-installationer och ställdes inför behovet av att migrera data från ett kluster till ett annat utan stillestånd.

Vi behövde den här operationen i minst två fall:

  1. Överföra data från ett RabbitMQ-kluster som inte finns i Kubernetes till ett nytt – redan "kubernetiserat" (dvs. fungerar i K8s-poddar) – kluster.
  2. Migrering av RabbitMQ inom Kubernetes från ett namnområde till ett annat (till exempel om kretsar är avgränsade av namnområden, för att överföra infrastruktur från en krets till en annan).

Receptet som föreslås i artikeln är fokuserat på situationer (men är inte alls begränsat till dem) där det finns ett gammalt RabbitMQ-kluster (till exempel med 3 noder), som finns antingen redan i K8s eller på några gamla servrar. En applikation som finns på Kubernetes (redan där eller i framtiden) fungerar med den:

Sömlös migrering av RabbitMQ till Kubernetes

... och vi står inför uppgiften att migrera den till den nya produktionen i Kubernetes.

Först kommer det allmänna tillvägagångssättet för själva migreringen att beskrivas, och efter det kommer de tekniska detaljerna för dess implementering att beskrivas.

Migrationsalgoritm

Det första, preliminära, steget innan någon åtgärd är att kontrollera att läget för hög tillgänglighet är aktiverat i den gamla RabbitMQ-installationen (HA). Anledningen är uppenbar - vi vill inte förlora någon data. För att utföra denna kontroll kan du gå till RabbitMQs adminpanel och se till att värdet är inställt på fliken Admin → Policies ha-mode: all:

Sömlös migrering av RabbitMQ till Kubernetes

Nästa steg är att skapa ett nytt RabbitMQ-kluster i Kubernetes-pods (i vårt fall, till exempel, bestående av 3 noder, men deras antal kan vara olika).

Efter detta slår vi samman de gamla och nya RabbitMQ-klustren och erhåller ett enda kluster (av 6 noder):

Sömlös migrering av RabbitMQ till Kubernetes

Processen för datasynkronisering mellan de gamla och nya RabbitMQ-klustren initieras. När all data är synkroniserad mellan alla noder i klustret kan vi byta applikation för att använda det nya klustret:

Sömlös migrering av RabbitMQ till Kubernetes

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

Sömlös migrering av RabbitMQ till Kubernetes

Vi har använt detta schema många gånger i produktionen. Men för vår egen bekvämlighet implementerade vi det i ett specialiserat system som distribuerar standard RMQ-konfigurationer över flera Kubernetes-kluster (för den som är nyfiken: vi pratar om addon-operatörom vilka vi berättade nyss). Nedan kommer vi att presentera individuella instruktioner som alla kan tillämpa på sina installationer för att prova den föreslagna lösningen i praktiken.

Låt oss prova det i praktiken

Krav

Detaljerna är mycket enkla:

  1. Kubernetes-kluster (minikube kommer också att fungera);
  2. RabbitMQ-kluster (kan användas på bar metall och göras som ett vanligt kluster i Kubernetes från det officiella Helm-diagrammet).

För exemplet nedan distribuerade jag RMQ till Kubernetes och kallade det rmq-old.

Förberedelse av monter

1. Ladda ner Helm-diagrammet och redigera det lite:

helm fetch --untar stable/rabbitmq-ha

För enkelhetens skull anger vi ett lösenord, ErlangCookie och göra politik ha-allså 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-old

3. Gå till RabbitMQs adminpanel, skapa en ny kö och lägg till flera meddelanden. De kommer att behövas så att vi efter migreringen kan se till att all data bevaras och att vi inte har förlorat något:

Sömlös migrering av RabbitMQ till Kubernetes

Testbänken är klar: vi har den "gamla" RabbitMQ med data som behöver överföras.

Migrera ett RabbitMQ-kluster

1. Låt oss först distribuera den nya RabbitMQ i andra namnutrymme med samma ErlangCookie och lösenord för användaren. För att göra detta kommer vi att utföra operationerna som beskrivs ovan och ändra det sista kommandot för att installera RMQ till följande:

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

2. Nu måste du slå samman det nya klustret med det gamla. För att göra detta, gå till var och en av poddarna 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 en variabel OLD_RMQ adressen till en av noderna hittas gammal RMQ-kluster.

Dessa kommandon kommer att stoppa den aktuella noden ny RMQ-klustret, anslut det till det gamla klustret och starta det igen.

3. RMQ-kluster med 6 noder är klart:

Sömlös migrering av RabbitMQ till Kubernetes

Du måste vänta medan meddelanden synkroniseras mellan alla noder. Det är inte svårt att gissa att meddelandesynkroniseringstiden beror på kapaciteten hos hårdvaran som klustret är utplacerat på och på antalet meddelanden. I det beskrivna scenariot finns det bara 10 av dem, så data synkroniserades omedelbart, men med ett tillräckligt stort antal meddelanden kan synkroniseringen pågå i timmar.

Så, synkroniseringsstatusen:

Sömlös migrering av RabbitMQ till Kubernetes

Här +5 betyder att meddelanden redan är inne mer på 5 noder (förutom vad som anges i fältet Node). Således lyckades synkroniseringen.

4. Allt som återstår är att byta RMQ-adressen i applikationen till det nya klustret (de specifika åtgärderna här beror på den teknologistacken du använder och andra applikationsspecifikationer), varefter du kan säga adjö till den gamla.

För den sista operationen (dvs redan efter byta applikationen till ett nytt kluster) gå till varje nod gammal kluster och kör kommandona:

rabbitmqctl stop_app
rabbitmqctl reset

Klustret "glömde" de gamla noderna: du kan ta bort den gamla RMQ, vid vilken tidpunkt flytten kommer att slutföras.

Notera: Om du använder RMQ med certifikat, förändras ingenting i grunden - flyttprocessen kommer att utföras på exakt samma sätt.

Resultat

Det beskrivna schemat är lämpligt för nästan alla fall när vi behöver migrera RabbitMQ eller helt enkelt flytta till ett nytt kluster.

I vårt fall uppstod svårigheter bara en gång, då RMQ nås från många håll, och vi hade inte möjlighet att ändra RMQ-adressen till en ny överallt. Sedan lanserade vi en ny RMQ i samma namnutrymme med samma etiketter så att den skulle falla under befintliga tjänster och ingresser, och när vi lanserade podden manipulerade vi etiketterna för hand, tog bort dem i början så att förfrågningar inte skulle falla på töm RMQ och lägg till dem igen efter att meddelandena har synkroniserats.

Vi använde samma strategi när vi uppdaterade RabbitMQ till en ny version med ändrad konfiguration - allt fungerade som en klocka.

PS

Som en logisk fortsättning på detta material förbereder vi artiklar om MongoDB (migrering från en hårdvaruserver till Kubernetes) och MySQL (hur vi förbereder detta DBMS inuti Kubernetes). De kommer att publiceras under de kommande månaderna.

PPS

Läs även på vår blogg:

Källa: will.com

Lägg en kommentar