RabbitMQ je broker poruka napisan na Erlangu koji vam omogućava da organizirate klaster za nadilaženje greške s punom replikacijom podataka na više čvorova, gdje svaki čvor može servisirati zahtjeve za čitanje i pisanje. Pošto imamo mnogo Kubernetes klastera u proizvodnji, podržavamo veliki broj RabbitMQ instalacija i bili smo suočeni sa potrebom da migriramo podatke iz jednog klastera u drugi bez zastoja.
Ova operacija nam je bila potrebna u najmanje dva slučaja:
Prijenos podataka iz RabbitMQ klastera koji se ne nalazi u Kubernetesu u novi – već “kubernetizirani” (tj. koji radi u K8s podovima) – klaster.
Migracija RabbitMQ-a unutar Kubernetesa iz jednog imenskog prostora u drugi (na primjer, ako su kola omeđena prostorima imena, onda za prijenos infrastrukture iz jednog kruga u drugi).
Recept predložen u članku fokusiran je na situacije (ali uopće nije ograničen na njih) u kojima postoji stari RabbitMQ klaster (na primjer, od 3 čvora), koji se već nalazi u K8s ili na nekim starim serverima. Aplikacija hostirana na Kubernetes-u (već postoji ili u budućnosti) radi s njim:
... i pred nama je zadatak da ga migriramo u novu produkciju u Kubernetesu.
Najprije će biti opisan opći pristup samoj migraciji, a nakon toga bit će opisani tehnički detalji njene implementacije.
Migracijski algoritam
Prva, preliminarna faza prije bilo kakve radnje je provjeriti da li je način visoke dostupnosti omogućen u staroj RabbitMQ instalaciji (HA). Razlog je očigledan - ne želimo da izgubimo podatke. Da biste izvršili ovu provjeru, možete otići na RabbitMQ admin panel i na kartici Admin → Policies provjerite je li vrijednost postavljena ha-mode: all:
Sljedeći korak je podizanje novog RabbitMQ klastera u Kubernetes podovima (u našem slučaju, na primjer, koji se sastoji od 3 čvora, ali njihov broj može biti drugačiji).
Nakon toga, spajamo stari i novi RabbitMQ klaster, dobijajući jedan klaster (od 6 čvorova):
Pokreće se proces sinkronizacije podataka između starog i novog RabbitMQ klastera. Kada se svi podaci sinkroniziraju između svih čvorova u klasteru, možemo prebaciti aplikaciju da koristi novi klaster:
Nakon ovih operacija, dovoljno je ukloniti stare čvorove iz RabbitMQ klastera, a potez se može smatrati završenim:
Ovu šemu smo koristili mnogo puta u proizvodnji. Međutim, radi naše udobnosti, implementirali smo ga u okviru specijalizovanog sistema koji distribuira standardne RMQ konfiguracije na više Kubernetes klastera (za one koji su radoznali: govorimo o addon-operatoro čemu mi tek nedavno rečeno). U nastavku ćemo predstaviti pojedinačne upute koje svako može primijeniti na svojim instalacijama kako bi isprobao predloženo rješenje na djelu.
Hajde da probamo u praksi
zahtjevi
Detalji su vrlo jednostavni:
Kubernetes klaster (minikube će takođe raditi);
RabbitMQ klaster (može se postaviti na goli metal i napraviti kao običan klaster u Kubernetesu sa službenog Helm grafikona).
Za primjer ispod, implementirao sam RMQ na Kubernetes i nazvao ga rmq-old.
Priprema štanda
1. Preuzmite Helm grafikon i malo ga uredite:
helm fetch --untar stable/rabbitmq-ha
Radi praktičnosti postavljamo lozinku, ErlangCookie i praviti politiku ha-alltako da su prema zadanim postavkama redovi sinhronizirani između svih čvorova RMQ klastera:
3. Idite na RabbitMQ admin panel, kreirajte novi red čekanja i dodajte nekoliko poruka. Oni će biti potrebni kako bismo nakon migracije bili sigurni da su svi podaci sačuvani i da nismo ništa izgubili:
Testna ploča je spremna: imamo „stari“ RabbitMQ sa podacima koje treba prenijeti.
Migracija RabbitMQ klastera
1. Prvo, ugradimo novi RabbitMQ prijatelju imenskog prostora sa istoErlangCookie i lozinku za korisnika. Da bismo to učinili, izvršit ćemo gore opisane operacije, mijenjajući završnu naredbu za instalaciju RMQ-a u sljedeću:
helm install . --name rmq-new --namespace rmq-new
2. Sada morate spojiti novi klaster sa starim. Da biste to učinili, idite na svaku od mahuna novo RabbitMQ i izvršite naredbe:
U varijablu OLD_RMQ pronađena je adresa jednog od čvorova staro RMQ klaster.
Ove komande će zaustaviti trenutni čvor novo RMQ klaster, priključite ga na stari klaster i ponovo ga pokrenite.
3. RMQ klaster od 6 čvorova je spreman:
Morate sačekati da se poruke sinhronizuju između svih čvorova. Nije teško pretpostaviti da vrijeme sinhronizacije poruka ovisi o kapacitetu hardvera na kojem je klaster raspoređen i o broju poruka. U opisanom scenariju ima ih samo 10, tako da su podaci trenutno sinhronizovani, ali uz dovoljno veliki broj poruka, sinhronizacija može trajati satima.
Dakle, status sinhronizacije:
to je +5 znači da su poruke već unutra više na 5 čvorova (osim onoga što je naznačeno u polju Node). Dakle, sinhronizacija je bila uspješna.
4. Ostaje samo da prebacite RMQ adresu u aplikaciji na novi klaster (konkretne radnje ovdje zavise od tehnološkog steka koji koristite i drugih specifičnosti aplikacije), nakon čega se možete oprostiti od stare.
Za posljednju operaciju (tj. već после prebacivanje aplikacije na novi klaster) idite na svaki čvor staro klaster i izvršiti naredbe:
rabbitmqctl stop_app
rabbitmqctl reset
Klaster je "zaboravio" na stare čvorove: možete obrisati stari RMQ, nakon čega će premještanje biti završeno.
primjedba: Ako koristite RMQ s certifikatima, ništa se suštinski ne mijenja - proces selidbe će se odvijati potpuno isto.
nalazi
Opisana shema je prikladna za gotovo sve slučajeve kada trebamo migrirati RabbitMQ ili jednostavno preći na novi klaster.
U našem slučaju poteškoće su se pojavile samo jednom, kada se pristupilo RMQ-u sa mnogo mjesta, a mi nismo svuda imali priliku promijeniti RMQ adresu u novu. Zatim smo pokrenuli novi RMQ u istom imenskom prostoru sa istim oznakama kako bi potpadao pod postojeće servise i ulaze, a prilikom pokretanja pod-a ručno smo manipulirali oznakama, uklanjajući ih na početku kako zahtjevi ne bi padali na ispraznite RMQ i vratite ih nakon što se poruke sinhronizuju.
Koristili smo istu strategiju kada smo ažurirali RabbitMQ na novu verziju sa promijenjenom konfiguracijom - sve je radilo kao sat.
PS
Kao logičan nastavak ovog materijala, pripremamo članke o MongoDB-u (migracija sa hardverskog servera na Kubernetes) i MySQL-u (kako pripremamo ovaj DBMS unutar Kubernetesa). Oni će biti objavljeni u narednim mjesecima.