
Ta članek nadaljuje naš o migraciji RabbitMQ in se posveča MongoDB. Ker upravljamo z mnogimi klasterji Kubernetes in MongoDB, je prišla naravna potreba po migraciji podatkov iz ene inštalacije v drugo, in to brez zastojev. Glavni scenariji ostajajo enaki: prenos MongoDB z virtualnih/železnih strežnikov v Kubernetes ali prenos MongoDB znotraj enega klasterja Kubernetes (iz enega imenskega prostora v drugega).
Naša rešitev je namenjena primerom, ko funkcionira star klaster MongoDB (na primer, s 3 vozli in se nahaja bodisi že v K8s ali na starih strežnikih), s katerim dela aplikacija, nameščena v Kubernetes:

Kako bomo prenesli tak klaster v nov produkcijski sistem v Kubernetes?
Teorija
Splošni algoritem migracije je podoben tistemu, opisanemu v situaciji z RabbitMQ.
Pomembno je poudariti, da je za prenos potrebno, da so strežniki z MongoDB in Kubernetes v isti mreži. Vozlišča klasterja MongoDB se bodo med seboj povezovala preko IP starih strežnikov (kjer se nahajajo stare inštalacije MongoDB) in preko DNS imen podov z MongoDB v K8s. Zato bo potrebno na železnih strežnikih (s starimi inštalacijami) preusmeriti poti do podov, nato pa jih nastaviti na uporabo DNS strežnika, ki deluje v Kubernetes (ali pa ročno vnesti potrebna imena v /etc/hosts, čeprav je v splošnem priporočljivo, da se takim možnostim bolje izognemo).
Naslednji korak je vzpostaviti klaster MongoDB v podih Kubernetes. V našem primeru klaster BDP sestavlja 3 vozlišča, pri čemer se vsako vozlišče nahaja v ločenem podu K8s — njihovo število pa je lahko tudi drugačno. V ConfigMap je potrebno navesti naslov glavnega strežnika MongoDB iz stare inštalacije: takrat bodo vozlišča MongoDB, ki se nahajajo v podih v K8s, takoj začela s sinhronizacijo z njim.
Ko se vsi podi dvignejo, se oblikuje klaster MongoDB iz 6 vozlišč:

Upoštevajte, da se bodo podi dolgo dvigovali, saj se vsak pod zažene po vrsti in ob zagonu sinhronizira podatke z glavnim strežnikom.
Po tem lahko preklopimo aplikacijo na uporabo novih strežnikov MongoDB:

In ostane le še, da odstranimo stare vozlišča iz klasterja MongoDB, po čemer lahko migracijo štejemo za zaključeno:

Takšno shemo pogosto uporabljamo v produkciji in za lažjo uporabo smo jo реализirali v okviru modula k (to orodje smo ), ki omogoča razširjanje tipičnih konfiguracij MongoDB na več grozdov. Objavo svojih modulov načrtujemo v bližnji prihodnosti, trenutno pa predstavljamo posamezna navodila, s katerimi lahko preizkusite predlagano rešitev v praksi in brez uporabe addon-operatorja.
Preizkušamo v praksi.
Zahteve
Podatki:
- Kubernetes grozd (primerna je tudi minikube);
- Grozd MongoDB (lahko je nameščen na bare metal, ali pa ustvarjen kot običajen grozd v Kubernetesu iz uradnega Helm grafičnega vmesnika).
V spodnjem opisanem primeru bo star grozd z MongoDB imenovan mongo-stari in nameščen v istem grozdu Kubernetes, kjer bomo kasneje namestili tudi nov (mongo-novi).
Priprava starega grozda
1. Za primer, ki prikazuje opisano shemo v akciji, bomo ustvarili 'stari' (t.j. grozd, ki bo migriran) grozd MongoDB neposredno v Kubernetesu (v resnici je lahko tudi na ločenih strežnikih zunaj K8s). Za to bomo prenesli Helm grafični vmesnik:
helm fetch --untar stable/mongodb-replicaset… in ga nekoliko uredili, da nastavimo avtentifikacijo:
auth:
enabled: true
adminUser: mongo
adminPassword: pa33w0rd
# metricsUser: metrics
# metricsPassword: password
# key: keycontent
# existingKeySecret:
# existingAdminSecret:
# exisitingMetricsSecret: Prav tako lahko v values.yaml nastavite certifikate in še mnogo več.
2. Namestimo grafični vmesnik:
helm install . --name mongo-stari --namespace mongo-stariPo tem bo zagnana testna 'stara' namestitev MongoDB:
kubectl --namespace=mongo-stari get pods 
Vstopimo v pod z njenim glavnim strežnikom in ustvarimo testno bazo:
kubectl --namespace=mongo-stari exec -ti mongo-stari-mongodb-replicaset-0 mongo
use admin
db.auth('mongo','password')
use music
db.artists.insert({ artistname: "The Tea Party" })
show dbs 
V različnih pod-ih sem ugotovil, da je glavni strežnik mongo-stari-mongodb-replicaset-0. Vendar pa je za bolj enostavno rešitev tega vprašanja po namestitvi Helm grafičnega vmesnika podana ukaz, kako določiti MASTER_POD. V mojem primeru (za mongo-stari 3 vozlišča) izgleda takole:
for ((i = 0; i < 3; ++i)); do kubectl exec --namespace mongo-stari mongo-stari-mongodb-replicaset-$i -- sh -c 'mongo --eval="printjson(rs.isMaster())"'; doneS tem je priprava stare namestitve MongoDB, katerih podatki bodo preneseni, končana.
Migracija grozda MongoDB
Zdaj bomo razporedili novo namestitev MongoDB, ki bo v Kubernetesu in se bo uporabljala v produkciji.
NB: Opozarjam, da mora biti uporabljena enaka različica MongoDB kot prej. V nasprotnem primeru obstaja tveganje za težave s združljivostjo.
Po analogiji prejšnjemu razdelku (kjer smo posnemali 'staro' namestitev MongoDB) bomo vzeli že omenjeni Helm grafični vmesnik (z ukazom helm fetch) in nastavimo avtentikacijo ter druge nastavitve, če so uporabljene. Poleg tega bomo popravili datoteko init/on-start.sh, tako da bomo začasno dodali v vrstici 165 naslov mojstra, pridobljen v prejšnjem koraku (ali pa vam je znan iz namestitve MongoDB na samostojnih strežnikih):
peers='mongo-old-mongodb-replicaset-0.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017'Pripravljeni smo na ustvarjanje nove namestitve MongoDB:
helm install . --name mongo-new --namespace mongo-newPočakamo, da se vsi podi zaženejo (če je podatkov veliko, lahko njihovo zagon traja ure):

Zdaj naredimo exec v novo pod in si oglejmo seznam baz:
kubectl --namespace=mongo-new exec -ti mongo-new-mongodb-replicaset-0 mongo 
Oba klastera MongoDB sta združena v enega, ki obsega 6 vozlišč.
Trenutno lahko preklopimo aplikacijo na nov klaster, toda za dokončanje migracije je še nekaj korakov.
Iz datoteke init/on-start.sh v novi namestitvi odstranimo dodano vrstico:
peers='mongo-old-mongodb-replicaset-0.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017'Zdaj pojdimo do starega mojstra klastera in ga 'odstranimo' — takrat bo v klasteru določen nov mojster. Pojdimo v pod z mojstrom MongoDB:
kubectl --namespace=mongo-old exec -ti mongo-old-mongodb-replicaset-0 mongo
use admin
db.auth('mongo','password')Nato spremenimo prioritete vozlišč in spremenimo mojstra:
cfg = rs.conf()
cfg.members[5].priority = 2
rs.reconfig(cfg)
rs.stepDown(120)Trenutno vozlišče je prenehalo biti mojster — potekale bodo volitve novega. Ker smo spremenili prioritete, bo nov mojster postalo tisto vozlišče, ki ga potrebujemo.
NB: Privzeto ima vsa vozlišča MongoDB prioriteto 1. Zgoraj dvigujemo prioriteto potrebnega vozlišča na 2. Tako bo skupni mojster zagotovo član novega klastera. Več o tem, kako delujejo ti mehanizmi v MongoDB, lahko preberete v .
Izključili bomo staro namestitev MongoDB, nato pa se bomo povezali z mojstrom nove in odstranili stare vozlišča:
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")Po tem lahko migracijo štejemo za zaključeno: uspešno smo preklopili s starega klastera MongoDB na novega!
Zaključki
Opisani postopek ustreza skoraj vsem primerom, ko je treba prenesti MongoDB ali preprosto preiti v nov klaster.
Verjetno je glavni odtenek pri prenosu potreba po usklajevanju IP naslovov novih podov na strežnike stare namestitve MongoDB, če ta ni v K8s, ter pravilno poimenovanje v DNS (ali /etc/hosts). V tem primeru ti koraki niso bili potrebni, saj je prišlo do migracije med različnimi prostori imen istega Kubernetes gruče.
P.S.
Preberite tudi na našem blogu:
- «»;
- «»;
- «».
Izvor: habr.com
