Migrazione non semplice di RabbitMQ in Kubernetes

Migrazione non semplice di RabbitMQ in Kubernetes

RabbitMQ – un broker di messaggi scritto in Erlang, che consente di organizzare un cluster di alta disponibilità con replicazione completa dei dati su più nodi, dove ciascun nodo può gestire richieste di lettura e scrittura. Avendo in produzione diversi cluster Kubernetes, supportiamo un grande numero di installazioni di RabbitMQ e ci siamo trovati di fronte alla necessità di migrare dati da un cluster all'altro senza inattività.

Questa operazione è stata necessaria almeno in due casi:

  1. Trasferimento di dati da un cluster RabbitMQ che non si trova in Kubernetes a un nuovo cluster già 'kubernetesizzato' (cioè funzionante in pod K8s).
  2. Migrazione di RabbitMQ all'interno di Kubernetes da uno namespace a un altro (ad esempio, se i confini sono delimitati dagli spazi dei nomi, per trasferire l'infrastruttura da un confine all'altro).

La ricetta proposta nell'articolo è orientata a situazioni (ma non è limitata a queste) in cui esiste un vecchio cluster RabbitMQ (ad esempio, composto da 3 nodi), che si trova già in K8s o su alcuni vecchi server. Esso è utilizzato da un'applicazione ospitata in Kubernetes (già lì o in prospettiva):

Migrazione non semplice di RabbitMQ in Kubernetes

… e ora abbiamo il compito di migrare in un nuovo production in Kubernetes.

Inizialmente verrà descritto l'approccio generale alla migrazione, seguito dai dettagli tecnici per la sua implementazione.

Algoritmo di migrazione

Il primo passo preliminare, prima di intraprendere qualsiasi azione, è verificare che nella vecchia installazione di RabbitMQ sia attivata la modalità di alta disponibilità (HA). Il motivo è ovvio: non vogliamo perdere alcun dato. Per effettuare questa verifica, è possibile accedere all'interfaccia di amministrazione di RabbitMQ e nella scheda Admin → Policies assicurarsi che sia impostato il valore ha-mode: all:

Migrazione non semplice di RabbitMQ in Kubernetes

Il passo successivo consiste nel sollevare un nuovo cluster RabbitMQ nei pod di Kubernetes (nel nostro caso, ad esempio, composto da 3 nodi, ma il numero può variare).

Dopo di ciò uniamo i cluster RabbitMQ vecchio e nuovo, ottenendo un unico cluster (di 6 nodi):

Migrazione non semplice di RabbitMQ in Kubernetes

Si avvia il processo di sincronizzazione dei dati tra i vecchi e i nuovi cluster RabbitMQ. Una volta che tutti i dati sono sincronizzati tra i nodi nel cluster, possiamo switchare l'applicazione per utilizzare il nuovo cluster:

Migrazione non semplice di RabbitMQ in Kubernetes

Dopo queste operazioni è sufficiente rimuovere i vecchi nodi dal cluster RabbitMQ, e il trasferimento può considerarsi completato:

Migrazione non semplice di RabbitMQ in Kubernetes

Questo schema è stato applicato più volte nel nostro ambiente di produzione. Tuttavia, per comodità, lo abbiamo implementato all'interno di un sistema specializzato che distribuisce configurazioni standard di RMQ su più cluster Kubernetes. (per coloro che sono curiosi: si tratta di addon-operator, di cui noi abbiamo parlato recentemente). Di seguito verranno presentate istruzioni specifiche che chiunque può applicare alle proprie installazioni per provare la soluzione proposta in azione.

Proviamo nella pratica

Requisiti

I requisiti sono molto semplici:

  1. Cluster Kubernetes (va bene anche minikube);
  2. Un cluster RabbitMQ (che può essere distribuito su bare metal o creato come un normale cluster in Kubernetes usando il chart Helm ufficiale).

Per l'esempio descritto di seguito, ho distribuito RMQ in Kubernetes e l'ho chiamato rmq-old.

Preparazione dell'ambiente

1. Scarichiamo il chart Helm e apportiamo alcune modifiche:

helm fetch --untar stable/rabbitmq-ha

Per comodità, impostiamo la password, ErlangCookie e definiamo la politica ha-all, affinché, 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. Installiamo il chart:

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

3. Accediamo all'interfaccia di amministrazione di RabbitMQ, creiamo una nuova coda e aggiungiamo alcuni messaggi. Questi saranno necessari per assicurarci, dopo la migrazione, che tutti i dati siano stati conservati e che nulla sia andato perso:

Migrazione non semplice di RabbitMQ in Kubernetes

Il banco di prova è pronto: abbiamo un 'vecchio' RabbitMQ con i dati da trasferire.

Migrazione del cluster RabbitMQ

1. Iniziamo a distribuire un nuovo RabbitMQ in amico uno spazio dei nomi con le stesse ErlangCookie credenziali e password per l'utente. A tal fine, eseguiamo le operazioni descritte sopra, modificando il comando finale per l'installazione di RMQ nella seguente maniera:

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

2. Ora è necessario unire il nuovo cluster a quello esistente. Per farlo, accediamo a ciascun pod di del nuovo RabbitMQ ed eseguiamo 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

Nella variabile OLD_RMQ è l'indirizzo di uno dei nodi del vecchio cluster RMQ.

Questi comandi fermeranno il nodo corrente del nuovo del cluster RMQ, lo uniranno al vecchio cluster e lo riavvieranno.

3. Il cluster RMQ composto da 6 nodi è pronto:

Migrazione non semplice di RabbitMQ in Kubernetes

È necessario attendere che i messaggi vengano sincronizzati tra tutti i nodi. È facile intuire che il tempo di sincronizzazione dei messaggi dipende dalle capacità dell'hardware su cui è effettuato il cluster e dal numero di messaggi. Nel caso descritto, ce ne sono solo 10, quindi i dati si sono sincronizzati immediatamente, ma con un numero sufficientemente elevato di messaggi la sincronizzazione può richiedere ore.

Quindi, lo stato di sincronizzazione:

Migrazione non semplice di RabbitMQ in Kubernetes

Qui +5 significa che i messaggi sono già presenti ancora su 5 nodi (oltre a quello indicato nel campo Node). Pertanto, la sincronizzazione è avvenuta con successo.

4. Resta solo da cambiare nell'app l'indirizzo RMQ al nuovo cluster (le azioni specifiche qui dipendono dalla tecnologia utilizzata e da altre specifiche dell'applicazione), dopo di che si può salutare il vecchio.

Per l'ultima operazione (ossia dopo cambiare l'app al nuovo cluster) accediamo a ciascun nodo del vecchio del cluster ed eseguiamo i comandi:

rabbitmqctl stop_app
rabbitmqctl reset

Il cluster ha “dimenticato” i vecchi nodi: si può eliminare il vecchio RMQ, completando così la migrazione.

Nota: Se stai utilizzando RMQ con certificati, il principio rimane invariato: il processo di migrazione avverrà esattamente nello stesso modo.

Conclusioni

Lo schema descritto si adatta praticamente a tutti i casi in cui dobbiamo trasferire RabbitMQ o semplicemente migrare a un nuovo cluster.

Nel nostro caso, abbiamo incontrato difficoltà solo una volta, quando RMQ veniva utilizzato da molteplici origini e non avevamo la possibilità di cambiare l'indirizzo di RMQ ovunque. Allora abbiamo avviato un nuovo RMQ nello stesso namespace con etichette identiche, affinché venisse intercettato dai servizi e dagli Ingress già esistenti, e durante l'avvio del pod abbiamo manipolato le etichette manualmente, rimuovendole inizialmente per impedire che le richieste arrivassero al nuovo RMQ vuoto, aggiungendole nuovamente dopo la sincronizzazione dei messaggi.

Abbiamo applicato la stessa strategia durante l'aggiornamento di RabbitMQ a una nuova versione con configurazione modificata: tutto ha funzionato alla perfezione.

P.S.

Come logico seguito a questo materiale, stiamo preparando articoli su MongoDB (migrazione da server fisico a Kubernetes) e MySQL (come prepariamo questo DBMS all'interno di Kubernetes). Saranno pubblicati nei prossimi mesi.

P.P.S.

Leggete anche nel nostro blog:

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS 🔥 Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS | ProHoster