RabbitMQ je sprostredkovateľ správ napísaný v jazyku Erlang, ktorý vám umožňuje organizovať klaster prepnutia pri zlyhaní s úplnou replikáciou údajov vo viacerých uzloch, kde každý uzol môže obsluhovať požiadavky na čítanie a zápis. S mnohými klastrami Kubernetes v produkčnej prevádzke podporujeme veľké množstvo inštalácií RabbitMQ a čelili sme potrebe migrovať údaje z jedného klastra do druhého bez prestojov.
Túto operáciu sme potrebovali minimálne v dvoch prípadoch:
Prenos údajov z klastra RabbitMQ, ktorý sa nenachádza v Kubernetes, do nového – už „kubernetizovaného“ (t. j. fungujúceho v K8s podoch) – klastra.
Migrácia RabbitMQ v rámci Kubernetes z jedného menného priestoru do druhého (napríklad, ak sú okruhy ohraničené mennými priestormi, potom na prenos infraštruktúry z jedného okruhu do druhého).
Recept navrhnutý v článku je zameraný na situácie (ale nie je na ne vôbec obmedzený), v ktorých existuje starý klaster RabbitMQ (napríklad s 3 uzlami), ktorý sa už nachádza v K8 alebo na niektorých starých serveroch. Aplikácia hostovaná na Kubernetes (už tam alebo v budúcnosti) s ním funguje:
... a stojíme pred úlohou migrovať to do novej produkcie v Kubernetes.
Najprv bude popísaný všeobecný prístup k samotnej migrácii a následne budú popísané technické detaily jej implementácie.
Migračný algoritmus
Prvou, predbežnou fázou pred akoukoľvek akciou je skontrolovať, či je v starej inštalácii RabbitMQ povolený režim vysokej dostupnosti (HA). Dôvod je zrejmý – nechceme prísť o žiadne dáta. Ak chcete vykonať túto kontrolu, prejdite na panel správcu RabbitMQ a na karte Správca → Zásady skontrolujte, či je nastavená hodnota ha-mode: all:
Ďalším krokom je vytvorenie nového klastra RabbitMQ v Kubernetes podoch (v našom prípade napríklad pozostávajúceho z 3 uzlov, ale ich počet môže byť iný).
Potom zlúčime staré a nové klastre RabbitMQ, čím získame jeden klaster (zo 6 uzlov):
Spustí sa proces synchronizácie údajov medzi starým a novým klastrom RabbitMQ. Keď sú všetky údaje synchronizované medzi všetkými uzlami v klastri, môžeme prepnúť aplikáciu na používanie nového klastra:
Po týchto operáciách stačí odstrániť staré uzly z klastra RabbitMQ a presun možno považovať za dokončený:
Túto schému sme pri výrobe použili mnohokrát. Pre naše pohodlie sme ho však implementovali v rámci špecializovaného systému, ktorý distribuuje štandardné konfigurácie RMQ cez viacero klastrov Kubernetes (pre tých, ktorí sú zvedaví: hovoríme o operátor doplnkuo ktorých sme len nedávno povedal). Nižšie predstavíme jednotlivé pokyny, ktoré môže ktokoľvek použiť na svojich inštaláciách a vyskúšať si navrhované riešenie v akcii.
Skúsme to v praxi
Požiadavky
Podrobnosti sú veľmi jednoduché:
Kubernetes cluster (funguje aj minikube);
Klaster RabbitMQ (môže byť nasadený na holý kov a vyrobený ako bežný klaster v Kubernetes z oficiálneho grafu Helm).
Pre príklad nižšie som nasadil RMQ do Kubernetes a zavolal som ho rmq-old.
Príprava stojana
1. Stiahnite si tabuľku Helm a trochu ju upravte:
helm fetch --untar stable/rabbitmq-ha
Pre pohodlie sme nastavili heslo, ErlangCookie a robiť politiku ha-alltakže predvolene sú fronty synchronizované medzi všetkými uzlami klastra RMQ:
3. Prejdite na panel správcu RabbitMQ, vytvorte nový front a pridajte niekoľko správ. Budú potrebné, aby sme sa po migrácii mohli uistiť, že všetky údaje sú zachované a nič sme nestratili:
Testovacia stolica je pripravená: máme „starý“ RabbitMQ s údajmi, ktoré je potrebné preniesť.
Migrácia klastra RabbitMQ
1. Najprv nasadíme nový RabbitMQ priateľa menný priestor s rovnakýErlangCookie a heslo pre používateľa. Za týmto účelom vykonáme operácie opísané vyššie a zmeníme konečný príkaz na inštaláciu RMQ na nasledujúci:
helm install . --name rmq-new --namespace rmq-new
2. Teraz musíte zlúčiť nový klaster so starým. Ak to chcete urobiť, prejdite na každý z modulov nový RabbitMQ a vykonajte príkazy:
V premennej OLD_RMQ nájde sa adresa jedného z uzlov starý RMQ klaster.
Tieto príkazy zastavia aktuálny uzol nový Klaster RMQ, pripojte ho k starému klastru a znova ho spustite.
3. Klaster RMQ so 6 uzlami je pripravený:
Musíte počkať, kým sa správy zosynchronizujú medzi všetkými uzlami. Nie je ťažké uhádnuť, že čas synchronizácie správ závisí od kapacity hardvéru, na ktorom je klaster nasadený, a od počtu správ. V popísanom scenári je ich len 10, takže údaje boli synchronizované okamžite, no pri dostatočne veľkom počte správ môže synchronizácia trvať aj hodiny.
Takže stav synchronizácie:
Tu +5 znamená, že správy sú už vložené viac na 5 uzloch (okrem toho, čo je uvedené v poli Node). Synchronizácia teda prebehla úspešne.
4. Zostáva len prepnúť adresu RMQ v aplikácii do nového klastra (konkrétne akcie tu závisia od technologického zásobníka, ktorý používate a ďalších špecifík aplikácie), po čom sa môžete so starým rozlúčiť.
Na poslednú operáciu (t.j. už po prepnutie aplikácie do nového klastra) prejdite na každý uzol starý cluster a vykonajte príkazy:
rabbitmqctl stop_app
rabbitmqctl reset
Klaster „zabudol“ na staré uzly: môžete odstrániť starý RMQ, v tomto bode bude presun dokončený.
Poznámka: Ak používate RMQ s certifikátmi, nič sa zásadne nemení - proces sťahovania bude prebiehať úplne rovnako.
Závery
Opísaná schéma je vhodná takmer pre všetky prípady, keď potrebujeme migrovať RabbitMQ alebo jednoducho prejsť do nového klastra.
V našom prípade sa ťažkosti vyskytli iba raz, keď sa k RMQ pristupovalo z mnohých miest a nie všade sme mali možnosť zmeniť adresu RMQ na novú. Potom sme spustili nové RMQ v rovnakom mennom priestore s rovnakými menovkami, aby spadalo pod existujúce služby a Ingresses, a pri spustení modulu sme ručne manipulovali s menovkami a odstránili ich na začiatku, aby požiadavky nepadali na prázdne RMQ a ich pridanie späť po synchronizácii správ.
Rovnakú stratégiu sme použili pri aktualizácii RabbitMQ na novú verziu so zmenenou konfiguráciou – všetko fungovalo ako hodinky.
PS
Ako logické pokračovanie tohto materiálu pripravujeme články o MongoDB (migrácia z hardvérového servera na Kubernetes) a MySQL (ako tento DBMS pripravujeme v Kubernetes). Budú zverejnené v najbližších mesiacoch.