Migrarea complexă a MongoDB în Kubernetes

Migrarea complexă a MongoDB în Kubernetes

Această articol continuă materialul nostru recent despre migrarea RabbitMQ și se concentrează pe MongoDB. Deoarece administrăm numeroase clustere Kubernetes și MongoDB, am ajuns la necesitatea naturală de a migra date dintr-o instalare în alta, făcând acest lucru fără downtime. Scenariile principale rămân aceleași: transferul MongoDB de pe un server virtual/sinde în Kubernetes sau migrarea MongoDB în cadrul aceluiași cluster Kubernetes (dintr-un spațiu de nume în altul).

Rețeta noastră este destinată cazurilor în care funcționează un vechi cluster MongoDB (de exemplu, format din 3 noduri, aflat fie în K8s, fie pe servere vechi), cu care colaborează o aplicație găzduită în Kubernetes:

Migrarea complexă a MongoDB în Kubernetes

Cum vom migra un astfel de cluster în noul mediu de producție în Kubernetes?

Teorie

Algoritmul general de migrare este similar celui descris în situația cu RabbitMQ.

Este important de menționat că, pentru a putea efectua migrarea, serverele cu MongoDB și Kubernetes trebuie să se afle în aceeași rețea. Nodurile clusterului MongoDB vor comunica între ele prin IP-urile serverelor vechi (unde sunt instalările vechi MongoDB) și prin numele DNS-urilor pod-urilor cu MongoDB în K8s. Prin urmare, pe serverele fizice (cu instalări vechi) va fi necesar să se redirecționeze rutele către pod-uri și apoi să le configurăm pentru a folosi serverul DNS care funcționează în Kubernetes (sau să specificăm numele necesare în /etc/hosts, deși, în general, este mai bine să se evite această posibilitate).

Următorul pas este să ridicăm clusterul MongoDB în pod-urile Kubernetes. În cazul nostru, clusterul de baze de date este format din 3 noduri, iar fiecare nod se află într-un pod K8s - totuși, numărul lor poate fi diferit. În ConfigMap trebuie să specificăm adresa masterului MongoDB din vechea instalare: astfel, nodurile MongoDB aflate în pod-uri în K8s vor începe imediat sincronizarea cu acesta.

După ce toate pod-urile vor fi pornite, se va forma un cluster MongoDB din 6 noduri:

Migrarea complexă a MongoDB în Kubernetes

Rețineți că pod-urile vor porni lent, deoarece fiecare pod este lansat pe rând și, în momentul lansării, sincronizează datele cu masterul.

După aceasta, se poate comuta aplicația pentru a folosi noile servere MongoDB:

Migrarea complexă a MongoDB în Kubernetes

Și va rămâne doar să eliminăm nodurile vechi din clusterul MongoDB, după care migrarea poate fi considerată finalizată:

Migrarea complexă a MongoDB în Kubernetes

Această schemă o aplicăm frecvent în mediu de producție și, pentru comoditatea utilizării sale, am implementat-o în cadrul modulului addon-operator (această unealtă noi am anunțat-o recent), care permite distribuirea configurațiilor standard MongoDB pe multe clustere. Publicarea modulelor noastre este planificată în curând, iar până atunci, prezentăm instrucțiuni separate cu care puteți testa soluția propusă în acțiune, fără utilizarea addon-operator.

Să încercăm în practică

Cerințe

Detalii:

  • Cluster Kubernetes (poate fi și minikube);
  • Cluster MongoDB (poate fi configurat atât pe bare metal, cât și ca un cluster obișnuit în Kubernetes din chart-ul oficial Helm).

În exemplul descris mai jos, vechiul cluster cu MongoDB va fi denumit mongo-old și va fi instalat în același cluster Kubernetes, unde ulterior vom instala și noul (mongo-new).

Pregătim vechiul cluster

1. Pentru exemplul care demonstrează schema descrisă în acțiune, vom crea un cluster „vechi” (adică supus migrației) MongoDB chiar în Kubernetes (în realitate, acesta poate fi pe servere separate în afara K8s). Pentru aceasta, vom descărca chart-ul Helm:

helm fetch --untar stable/mongodb-replicaset

… și vom edita puțin, configurând autorizarea:

auth:
  enabled: true
  adminUser: mongo
  adminPassword: pa33w0rd
  # metricsUser: metrics
  # metricsPassword: password
  # key: keycontent
  # existingKeySecret:
  # existingAdminSecret:
  # exisitingMetricsSecret:

De asemenea, în values.yaml se pot configura certificate și multe altele.

2. Vom instala chart-ul:

helm install . --name mongo-old --namespace mongo-old

După aceasta, va fi lansată o instalare de testare „veche” a MongoDB:

kubectl --namespace=mongo-old get pods

Migrarea complexă a MongoDB în Kubernetes

Vom intra în podul cu masterul său și vom crea o bază de date de test:

kubectl --namespace=mongo-old exec -ti mongo-old-mongodb-replicaset-0 mongo
use admin
db.auth('mongo','password')
use music
db.artists.insert({ artistname: "The Tea Party" })
show dbs

Migrarea complexă a MongoDB în Kubernetes

Vizitând diferite pod-uri, am descoperit că masterul este mongo-old-mongodb-replicaset-0. Totuși, pentru o soluție mai comodă la această întrebare, după instalarea chart-ului Helm, se afișează comanda pentru a determina MASTER_POD. În cazul meu (pentru mongo-old din 3 noduri) aceasta arată astfel:

for ((i = 0; i < 3; ++i)); do kubectl exec --namespace mongo-old mongo-old-mongodb-replicaset-$i -- sh -c 'mongo --eval="printjson(rs.isMaster())"'; done

În acest moment, pregătirea vechii instalări MongoDB, a căror date vor fi transferate, este completă.

Migrarea clusterului MongoDB

Acum vom desfășura o nouă instalare MongoDB, care va fi situată în Kubernetes și care va fi utilizată de aplicație în producție.

NB: Menționez că trebuie să fie utilizată aceeași versiune de MongoDB ca și înainte. Altfel, există riscul de a întâmpina probleme de compatibilitate.

Similar cu secțiunea anterioară (unde am simulato o instalare „veche” MongoDB), vom lua chart-ul Helm menționat anterior (comandă helm fetch) și configurăm autentificarea, precum și alte setări, dacă sunt utilizate. De asemenea, vom corecta fișierul init/on-start.sh, adăugând temporar pe linia 165 adresa maestrului, obținută în etapa anterioară (sau cunoscută de dvs. din instalarea MongoDB pe servere separate):

peers='mongo-old-mongodb-replicaset-0.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017'

Suntem pregătiți pentru a crea o nouă instalare MongoDB:

helm install . --name mongo-new --namespace mongo-new

Așteptăm să pornească toate pod-urile (dacă sunt multe date, pornirea lor poate dura ore):

Migrarea complexă a MongoDB în Kubernetes

Acum facem exec în noul pod și verificăm lista bazelor:

kubectl --namespace=mongo-new exec -ti mongo-new-mongodb-replicaset-0 mongo

Migrarea complexă a MongoDB în Kubernetes

Două clustere MongoDB au fost combinate într-unul compus din 6 noduri.

În prezent, deja putem comuta aplicația pe noul cluster, dar pentru a finaliza migrarea mai sunt câțiva pași.

Din fișier init/on-start.sh în noua instalare eliminăm linia adăugată de noi:

peers='mongo-old-mongodb-replicaset-0.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017'

Acum intrăm în vechiul maestru al clusterului și îl „racolăm” — astfel, va fi desemnat un nou maestru în cluster. Intrăm în pod-ul cu maestrul MongoDB:

kubectl --namespace=mongo-old exec -ti mongo-old-mongodb-replicaset-0 mongo
use admin
db.auth('mongo','password')

După aceasta, schimbăm prioritățile nodurilor și schimbăm maestrul:

cfg = rs.conf()
cfg.members[5].priority = 2
rs.reconfig(cfg)
rs.stepDown(120)

Nodul curent a încetat să mai fie maestru — vor avea loc alegeri pentru un nou. Deoarece am schimbat prioritățile, nodul de care avem nevoie va deveni maestru.

NB: Implicit, toate nodurile MongoDB au prioritatea setată la 1. Mai sus, noi ridicăm prioritatea nodului de care avem nevoie la 2. Astfel, maestru devine cu siguranță un membru al noului cluster. Puteți citi mai multe despre modul în care funcționează aceste mecanisme în MongoDB, în documentation.

Vom deconecta vechea instalare MongoDB, după care vom accesa maestrul nou și vom șterge vechile noduri:

rs.remove("mongo-old-mongodb-replicaset-0.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017")
rs.remove("mongo-old-mongodb-replicaset-1.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017")
rs.remove("mongo-old-mongodb-replicaset-2.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017")

După aceasta, migrarea poate fi considerată completă: ne-am transferat cu succes de la vechiul cluster MongoDB la cel nou!

Concluzii

Schema descrisă se potrivește practic tuturor cazurilor când trebuie să transferăm MongoDB sau pur și simplu să ne relocăm într-un nou cluster.

Probabil, principalul detaliu la transfer constă în necesitatea de a redirecționa adresele IP ale noilor pod-uri către serverele vechii instalări MongoDB, dacă aceasta se află în afara K8s, și denumirea corectă a acestora în DNS (sau /etc/hosts). În exemplul acesta, acești pași nu au fost necesari, deoarece migrarea a avut loc între spații de nume diferite ale aceleași clustere Kubernetes.

P.S.

Citiți și în blogul nostru:

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster