
Dit artikel gaat verder met onze over de migratie van RabbitMQ en is gewijd aan MongoDB. Aangezien we veel Kubernetes- en MongoDB-clusters beheren, zijn we op de natuurlijke noodzaak gekomen om gegevens van de ene installatie naar de andere te migreren en dit te doen zonder downtime. De belangrijkste scenario's blijven hetzelfde: het verplaatsen van MongoDB van een virtuele/fysieke server naar Kubernetes of het verplaatsen van MongoDB binnen hetzelfde Kubernetes-cluster (van de ene namespace naar de andere).
Ons recept is bedoeld voor situaties waarin er een oude MongoDB-cluster draait (bijvoorbeeld met 3 knooppunten en al dan niet in K8s of op oude servers), waar een applicatie op draait die in Kubernetes is gehost:

Hoe zullen we zo'n cluster migreren naar een nieuwe productieomgeving in Kubernetes?
Theorie
Het algemene migratie-algoritme is vergelijkbaar met dat beschreven in de situatie met RabbitMQ.
Het is belangrijk op te merken dat voor een succesvolle verhuizing vereist is dat de servers met MongoDB en Kubernetes zich in hetzelfde netwerk bevinden. De knooppunten van de MongoDB-cluster zullen met elkaar communiceren via de IP-adressen van de oude servers (waar de oude MongoDB-installaties zich bevinden) en via de DNS-namen van de pods met MongoDB in K8s. Daarom moet op de fysieke servers (met de oude installaties) de routering naar de pods worden doorgestuurd en moet deze worden ingesteld om de DNS-server te gebruiken die in Kubernetes draait (of de benodigde namen te registreren in /etc/hosts, hoewel het in het algemeen beter is om deze mogelijkheid te vermijden).
De volgende stap is het opzetten van de MongoDB-cluster in de pods van Kubernetes. In ons geval bestaat de databasecluster uit 3 knooppunten en elk knooppunt bevindt zich in een afzonderlijke K8s-pod — hoewel hun aantal ook anders kan zijn. In de ConfigMap moet het adres van de master MongoDB uit de oude installatie worden opgegeven: dan zullen de MongoDB-knooppunten in de pods in K8s onmiddellijk beginnen met synchronisatie met hem.
Nadat alle pods zijn opgestart, ontstaat er een MongoDB-cluster bestaande uit 6 knooppunten:

Houd er rekening mee dat de pods langzaam opstarten, aangezien elke pod om de beurt wordt gestart en tijdens de opstart gegevens synchroniseert met de master.
Daarna kun je de applicatie inschakelen om gebruik te maken van de nieuwe MongoDB-servers:

En resteert alleen het verwijderen van de oude knooppunten uit de MongoDB-cluster, waarna de verhuizing als voltooid kan worden beschouwd:

Dit schema passen we vaak toe in productie en voor het gemak hebben we dit geïmplementeerd in de module (deze tool hebben wij ), waarmee de standaardconfiguraties van MongoDB over meerdere clusters kunnen worden verspreid. We zijn van plan om binnenkort onze modules te publiceren, en voor nu presenteren we afzonderlijke instructies waarmee je de voorgestelde oplossing in de praktijk kunt proberen zonder gebruik te maken van de addon-operator.
Laten we het in de praktijk proberen
Vereisten
Gegevens:
- Kubernetes-cluster (minikube is ook geschikt);
- MongoDB-cluster (kan zowel op bare metal worden opgezet als als een gewoon cluster in Kubernetes via de officiële Helm-chart).
In het onderstaande voorbeeld wordt het oude cluster met MongoDB genoemd mongo-old en geïnstalleerd in hetzelfde Kubernetes-cluster waar we later een nieuw cluster gaan installeren (mongo-new).
Oud cluster voorbereiden
1. Voorbeeld dat het beschreven schema in de praktijk demonstreert, laten we een "oud" (d.w.z. te migreren) MongoDB-cluster rechtstreeks in Kubernetes creëren (in werkelijkheid kan deze ook op afzonderlijke servers buiten K8s staan). Hiervoor downloaden we de Helm-chart:
helm fetch --untar stable/mongodb-replicaset… en we bewerken deze een beetje, om de autorisatie in te stellen:
auth:
enabled: true
adminUser: mongo
adminPassword: pa33w0rd
# metricsUser: metrics
# metricsPassword: password
# key: keycontent
# existingKeySecret:
# existingAdminSecret:
# exisitingMetricsSecret: In de values.yaml kan je ook certificaten en veel meer instellen.
2. We installeren de chart:
helm install . --name mongo-old --namespace mongo-oldDaarna wordt een testinstallatie van de "oude" MongoDB gestart:
kubectl --namespace=mongo-old get pods 
Laten we de pod met de master binnen gaan en een testdatabase aanmaken:
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 
Bij het inloggen op verschillende pod'en ontdekte ik dat de master mongo-old-mongodb-replicaset-0is. Voor een handiger oplossing van deze kwestie geeft het installatiecommando van de Helm-chart weer hoe je kunt bepalen MASTER_POD. In mijn geval (voor mongo-old van 3 knooppunten) ziet het er zo uit:
for ((i = 0; i < 3; ++i)); do kubectl exec --namespace mongo-old mongo-old-mongodb-replicaset-$i -- sh -c 'mongo --eval="printjson(rs.isMaster())"'; doneZo is de voorbereiding van de oude MongoDB-installatie, waarvan de gegevens zullen worden overgebracht, voltooid.
Migratie van het MongoDB-cluster
Nu gaan we een nieuwe MongoDB-installatie opzetten die in Kubernetes draait en door de productie-app zal worden gebruikt.
NB: Let op, dezelfde versie van MongoDB moet worden gebruikt als eerder. Anders bestaat het risico op compatibiliteitsproblemen.
Op basis van het vorige gedeelte (waar we de "oude" MongoDB-installatie imiteerden), nemen we de eerder genoemde Helm-chart (met het commando helm fetch) en configureren we de autorisatie, evenals andere parameters, indien van toepassing. Ook passen we het bestand init/on-start.shtijdelijk aan door op regel 165 het adres van de master in te voegen, verkregen in de vorige stap (of bekend van de installatie van MongoDB op afzonderlijke servers):
peers='mongo-old-mongodb-replicaset-0.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017'We zijn klaar om een nieuwe MongoDB-installatie te creëren:
helm install . --name mongo-new --namespace mongo-newWe wachten tot alle pods zijn opgestart (als er veel gegevens zijn, kan dit uren duren):

Nu maken we exec in de nieuwe pod en bekijken we de lijst met databases:
kubectl --namespace=mongo-new exec -ti mongo-new-mongodb-replicaset-0 mongo 
Twee MongoDB-clusters zijn samengevoegd tot één, bestaande uit 6 knooppunten.
Op dit moment kunnen we de applicatie al naar het nieuwe cluster schakelen, maar er zijn nog een paar stappen om de migratie te voltooien.
Uit het bestand init/on-start.sh verwijderen we de door ons toegevoegde regel in de nieuwe installatie:
peers='mongo-old-mongodb-replicaset-0.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017'Laten we nu in de oude master van het cluster gaan en deze "afzetten" — dan zal er een nieuwe master in het cluster worden aangewezen. We gaan naar de pod met de MongoDB-master:
kubectl --namespace=mongo-old exec -ti mongo-old-mongodb-replicaset-0 mongo
use admin
db.auth('mongo','password')Vervolgens veranderen we de prioriteiten van de knooppunten en wijzigen we de master:
cfg = rs.conf()
cfg.members[5].priority = 2
rs.reconfig(cfg)
rs.stepDown(120)De huidige knoop is geen master meer — er zullen verkiezingen voor een nieuwe plaatsvinden. Aangezien we de prioriteiten hebben gewijzigd, wordt de gewenste knoop de master.
NB: Standaard hebben alle MongoDB-knooppunten een prioriteit van 1. We verhogen de prioriteit van de gewenste knoop tot 2. Zo wordt er zeker een lid van het nieuwe cluster de master. .
We schakelen de oude MongoDB-installatie uit en gaan vervolgens naar de nieuwe master om de oude knooppunten te verwijderen:
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")Daarna kan de migratie als voltooid worden beschouwd: we zijn succesvol overgestapt van de oude MongoDB-cluster naar de nieuwe!
Conclusies
Het beschreven schema is praktisch geschikt voor alle situaties waarin MongoDB moet worden verplaatst of gewoon naar een nieuw cluster moet worden verhuisd.
Een van de belangrijkste aspecten van de migratie is de noodzaak om de IP-adressen van de nieuwe pods door te geven aan de servers van de oude MongoDB-installatie, als deze zich buiten K8s bevindt, en de juiste naamgeving in DNS te zorgen (of /etc/hosts). In dit voorbeeld waren deze stappen niet nodig, omdat de migratie plaatsvond tussen verschillende namespaces van hetzelfde Kubernetes-cluster.
P.S.
Lees ook op onze blog:
- «»;
- «»;
- «».
Bron: habr.com
