Migrazione senza soluzione di continuità da RabbitMQ a Kubernetes

Migrazione senza soluzione di continuità da RabbitMQ a Kubernetes

RabbitMQ è un broker di messaggi scritto in Erlang che consente di organizzare un cluster di failover con replica completa dei dati su più nodi, in cui ciascun nodo può soddisfare richieste di lettura e scrittura. Avendo molti cluster Kubernetes in produzione, supportiamo un gran numero di installazioni RabbitMQ e ci siamo trovati di fronte alla necessità di migrare i dati da un cluster all'altro senza tempi di inattività.

Avevamo bisogno di questa operazione in almeno due casi:

  1. Trasferimento di dati da un cluster RabbitMQ che non si trova in Kubernetes a un nuovo cluster – già “kubernetizzato” (ovvero operante in pod K8).
  2. Migrazione di RabbitMQ all'interno di Kubernetes da uno spazio dei nomi a un altro (ad esempio, se i circuiti sono delimitati da spazi dei nomi, per trasferire l'infrastruttura da un circuito a un altro).

La ricetta proposta nell'articolo è focalizzata su situazioni (ma non si limita affatto a queste) in cui è presente un vecchio cluster RabbitMQ (ad esempio di 3 nodi), situato già in K8 o su alcuni vecchi server. Un'applicazione ospitata su Kubernetes (già presente o in futuro) funziona con esso:

Migrazione senza soluzione di continuità da RabbitMQ a Kubernetes

... e ci troviamo di fronte al compito di migrarlo nella nuova produzione in Kubernetes.

Innanzitutto verrà descritto l'approccio generale alla migrazione stessa, quindi verranno descritti i dettagli tecnici della sua implementazione.

Algoritmo di migrazione

La prima fase preliminare prima di qualsiasi azione è verificare che la modalità ad alta disponibilità sia abilitata nella vecchia installazione di RabbitMQ (HA). Il motivo è ovvio: non vogliamo perdere alcun dato. Per effettuare questo controllo, puoi andare al pannello di amministrazione di RabbitMQ e nella scheda Amministrazione → Politiche assicurati che il valore sia impostato ha-mode: all:

Migrazione senza soluzione di continuità da RabbitMQ a Kubernetes

Il prossimo passo è creare un nuovo cluster RabbitMQ nei pod Kubernetes (nel nostro caso, ad esempio, composto da 3 nodi, ma il loro numero potrebbe essere diverso).

Successivamente, uniamo il vecchio e il nuovo cluster RabbitMQ, ottenendo un unico cluster (di 6 nodi):

Migrazione senza soluzione di continuità da RabbitMQ a Kubernetes

Viene avviato il processo di sincronizzazione dei dati tra il vecchio e il nuovo cluster RabbitMQ. Una volta che tutti i dati sono stati sincronizzati tra tutti i nodi del cluster, possiamo cambiare l'applicazione per utilizzare il nuovo cluster:

Migrazione senza soluzione di continuità da RabbitMQ a Kubernetes

Dopo queste operazioni è sufficiente rimuovere i vecchi nodi dal cluster RabbitMQ e lo spostamento può considerarsi concluso:

Migrazione senza soluzione di continuità da RabbitMQ a Kubernetes

Abbiamo utilizzato questo schema molte volte nella produzione. Tuttavia, per nostra comodità, lo abbiamo implementato all'interno di un sistema specializzato che distribuisce configurazioni RMQ standard su più cluster Kubernetes (per chi è curioso: stiamo parlando di operatore-add-ondi cui noi detto proprio di recente). Di seguito presenteremo le singole istruzioni che chiunque potrà applicare sui propri impianti per provare in azione la soluzione proposta.

Proviamolo in pratica

Requisiti

I dettagli sono molto semplici:

  1. Cluster Kubernetes (funzionerà anche minikube);
  2. Cluster RabbitMQ (può essere distribuito su bare metal e creato come un normale cluster in Kubernetes dalla tabella Helm ufficiale).

Per l'esempio seguente, ho distribuito RMQ su Kubernetes e l'ho chiamato rmq-old.

Preparazione dello stand

1. Scarica il grafico Helm e modificalo leggermente:

helm fetch --untar stable/rabbitmq-ha

Per comodità, impostiamo una password, ErlangCookie e fare politica ha-allin modo che per impostazione predefinita le code siano sincronizzate tra tutti i nodi del cluster RMQ:

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. Installa il grafico:

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

3. Vai al pannello di amministrazione di RabbitMQ, crea una nuova coda e aggiungi diversi messaggi. Saranno necessari affinché dopo la migrazione possiamo assicurarci che tutti i dati siano conservati e che non abbiamo perso nulla:

Migrazione senza soluzione di continuità da RabbitMQ a Kubernetes

Il banco di prova è pronto: abbiamo il “vecchio” RabbitMQ con i dati da trasferire.

Migrazione di un cluster RabbitMQ

1. Innanzitutto, distribuiamo il nuovo RabbitMQ другом spazio dei nomi con lo stesso ErlangCookie e la password per l'utente. Per fare ciò eseguiremo le operazioni sopra descritte, modificando il comando finale per l'installazione di RMQ nel seguente:

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

2. Ora devi unire il nuovo cluster con quello vecchio. Per fare ciò, vai su ciascuno dei pod nuovo RabbitMQ ed esegui i comandi:

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 una variabile OLD_RMQ viene trovato l'indirizzo di uno dei nodi vecchio Gruppo RMQ.

Questi comandi interromperanno il nodo corrente nuovo Cluster RMQ, collegalo al vecchio cluster e avvialo di nuovo.

3. Il cluster RMQ di 6 nodi è pronto:

Migrazione senza soluzione di continuità da RabbitMQ a Kubernetes

È necessario attendere mentre i messaggi vengono sincronizzati tra tutti i nodi. Non è difficile intuire che il tempo di sincronizzazione dei messaggi dipende dalla capacità dell'hardware su cui è distribuito il cluster e dal numero di messaggi. Nello scenario descritto ce ne sono solo 10, quindi i dati sono stati sincronizzati immediatamente, ma con un numero sufficientemente elevato di messaggi la sincronizzazione può durare ore.

Quindi, lo stato della sincronizzazione:

Migrazione senza soluzione di continuità da RabbitMQ a Kubernetes

Qui +5 significa che i messaggi sono già arrivati più su 5 nodi (ad eccezione di quanto indicato nel campo Node). Pertanto, la sincronizzazione ha avuto successo.

4. Non resta che cambiare l'indirizzo RMQ nell'applicazione sul nuovo cluster (le azioni specifiche qui dipendono dallo stack tecnologico che stai utilizzando e da altre specifiche dell'applicazione), dopodiché puoi dire addio a quello vecchio.

Per l'ultima operazione (cioè già dopo passaggio dell'applicazione a un nuovo cluster) passare a ciascun nodo vecchio cluster ed eseguire i comandi:

rabbitmqctl stop_app
rabbitmqctl reset

Il cluster si è “dimenticato” dei vecchi nodi: puoi eliminare il vecchio RMQ, a quel punto lo spostamento sarà completato.

Nota: Se utilizzi RMQ con i certificati, non cambia sostanzialmente nulla: il processo di spostamento verrà eseguito esattamente allo stesso modo.

risultati

Lo schema descritto è adatto a quasi tutti i casi in cui dobbiamo migrare RabbitMQ o semplicemente spostarci in un nuovo cluster.

Nel nostro caso, le difficoltà sono sorte solo una volta, quando si accedeva a RMQ da molti luoghi e non abbiamo avuto l'opportunità di cambiare l'indirizzo RMQ con uno nuovo ovunque. Quindi abbiamo lanciato un nuovo RMQ nello stesso spazio dei nomi con le stesse etichette in modo che rientrasse nei servizi e negli ingressi esistenti e durante il lancio del pod abbiamo manipolato manualmente le etichette, rimuovendole all'inizio in modo che le richieste non cadessero sul RMQ vuoti e aggiungerli nuovamente dopo la sincronizzazione dei messaggi.

Abbiamo utilizzato la stessa strategia durante l'aggiornamento di RabbitMQ a una nuova versione con una configurazione modificata: tutto ha funzionato come un orologio.

PS

Come continuazione logica di questo materiale, stiamo preparando articoli su MongoDB (migrazione da un server hardware a Kubernetes) e MySQL (come prepariamo questo DBMS all'interno di Kubernetes). Verranno pubblicati nei prossimi mesi.

PPS

Leggi anche sul nostro blog:

Fonte: habr.com

Aggiungi un commento