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 ad alta disponibilità con replicazione completa dei dati su più nodi, dove ogni nodo può gestire richieste di lettura e scrittura. Avendo in produzione molti cluster Kubernetes, gestiamo un gran numero di installazioni di RabbitMQ e ci siamo trovati nella necessità di migrare dati da un cluster all'altro senza downtime.

Questa operazione è stata necessaria in almeno due casi:

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

La ricetta proposta nell'articolo è orientata a situazioni (ma non limitata a esse) in cui è presente un vecchio cluster RabbitMQ (ad esempio, composto da 3 nodi), che è già in K8s o su server obsoleti. Un'applicazione, già presente o prevista, lavora con questo cluster in Kubernetes:

Migrazione non semplice di RabbitMQ in Kubernetes

… e ci troviamo di fronte alla necessità di migrare il cluster in un nuovo ambiente di produzione in Kubernetes.

Inizialmente verrà descritto l'approccio generale alla migrazione, seguito da dettagli tecnici sulla sua attuazione.

Algoritmo di migrazione

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

Migrazione non semplice di RabbitMQ in Kubernetes

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

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

Migrazione non semplice di RabbitMQ in Kubernetes

Viene avviato il processo di sincronizzazione dei dati tra il vecchio e il nuovo cluster RabbitMQ. Dopo che tutti i dati sono stati sincronizzati tra tutti i nodi del cluster, possiamo passare l'applicazione all'uso del nuovo cluster:

Migrazione non semplice di RabbitMQ in Kubernetes

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

Migrazione non semplice di RabbitMQ in Kubernetes

Abbiamo applicato questo schema più volte nella nostra produzione. Tuttavia, per comodità, lo abbiamo implementato all'interno di un sistema specializzato che distribuisce configurazioni standard RMQ su più cluster Kubernetes. (per chi è curioso: si tratta di addon-operator, di cui abbiamo proprio recentemente abbiamo parlato). Di seguito verranno presentate singole istruzioni che ognuno può applicare nelle proprie installazioni per provare la soluzione proposta in azione.

Proviamo nella pratica

Requisiti

I requisiti sono molto semplici:

  1. Un cluster Kubernetes (va bene anche minikube);
  2. Un cluster RabbitMQ (può essere implementato su bare metal o come un normale cluster in Kubernetes utilizzando il Helm-chart ufficiale).

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

Preparazione dell'ambiente

1. Scarichiamo il Helm-chart e lo modifichiamo leggermente:

helm fetch --untar stable/rabbitmq-ha

Per comodità impostiamo la password, ErlangCookie e impostiamo la policy ha-all, in modo che per default 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'amministrazione di RabbitMQ, creiamo una nuova coda e aggiungiamo alcuni messaggi. Ci serviranno per verificare che tutti i dati siano stati salvati e che non abbiamo perso nulla dopo la migrazione:

Migrazione non semplice di RabbitMQ in Kubernetes

L'ambiente di test è pronto: abbiamo un RabbitMQ "vecchio" con i dati che devono essere trasferiti.

Migrazione del cluster RabbitMQ

1. Per prima cosa, implementiamo un nuovo RabbitMQ in un'altra namespace con le stesse ErlangCookie e password per l'utente. Per farlo, effettuiamo le operazioni descritte sopra, modificando il comando finale per l'installazione di RMQ come segue:

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

2. Ora dobbiamo unire il nuovo cluster con quello vecchio. A tal fine, accediamo a ciascun pod del nuovo RabbitMQ ed eseguiamo i seguenti 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 c'è l'indirizzo di uno dei nodi del vecchio cluster RMQ.

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

3. Il cluster RMQ con 6 nodi è pronto:

Migrazione non semplice di RabbitMQ in Kubernetes

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

Quindi, stato di sincronizzazione:

Migrazione non semplice di RabbitMQ in Kubernetes

Qui +5 significa che i messaggi si trovano già ancora su 5 nodi (oltre a quello specificato nel campo Node). Pertanto, la sincronizzazione è stata completata con successo.

4. Resta solo da cambiare nell'app l'indirizzo RMQ al nuovo cluster (le azioni specifiche qui dipendono dal stack tecnologico che stai utilizzando e da altre specificità dell'app), dopo di che puoi salutare il vecchio.

Per l'ultima operazione (cioè già la data rientri nel PITR. il passaggio dell'app al nuovo cluster), accediamo a ciascun nodo del vecchio del cluster e eseguiamo i comandi:

rabbitmqctl stop_app
rabbitmqctl reset

Il cluster ha "dimenticato" i vecchi nodi: puoi rimuovere il vecchio RMQ, a quel punto la migrazione sarà completata.

Nota: Se utilizzi RMQ con certificati, non cambia nulla di sostanziale: il processo di migrazione avverrà proprio allo stesso modo.

Conclusioni

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

Nel nostro caso, le difficoltà si sono presentate solo una volta, quando RMQ veniva utilizzato da molti luoghi e non avevamo la possibilità di cambiare ovunque l'indirizzo RMQ al nuovo. In quel caso, abbiamo avviato un nuovo RMQ nella stessa namespace con gli stessi label, affinché rientrasse nei servizi e negli ingress già esistenti. Durante l'avvio del pod, abbiamo manipolato manualmente le etichette, rimuovendole all'inizio in modo che i richieste non andassero a un RMQ vuoto, e aggiungendole di nuovo dopo la sincronizzazione dei messaggi.

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

P.S.

Come naturale continuazione di 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.

Leggi anche nel nostro blog:

Fonte: habr.com

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