Erschwerte Migration von MongoDB nach Kubernetes

Erschwerte Migration von MongoDB nach Kubernetes

Dieser Artikel setzt unser neuestes Material zur Migration von RabbitMQ fort und widmet sich MongoDB. Da wir zahlreiche Kubernetes- und MongoDB-Cluster betreuen, sind wir auf die natürliche Notwendigkeit gestoßen, Daten von einer Installation in eine andere zu migrieren, ohne dabei Ausfallzeiten zu verursachen. Die Hauptszenarien sind unverändert: Migration von MongoDB von einem virtuellen oder physischen Server nach Kubernetes oder die Migration von MongoDB innerhalb eines Kubernetes-Clusters (von einem Namespace in einen anderen).

Unser Ansatz ist für Situationen gedacht, in denen ein alter MongoDB-Cluster (zum Beispiel aus 3 Knoten und entweder bereits in K8s oder auf alten Servern) funktioniert und mit einer Anwendung arbeitet, die in Kubernetes gehostet wird:

Erschwerte Migration von MongoDB nach Kubernetes

Wie werden wir einen solchen Cluster in eine neue Produktionsumgebung in Kubernetes überführen?

Theorie

Der allgemeine Migrationsalgorithmus ähnelt dem, der für RabbitMQ beschrieben wurde.

Es ist wichtig zu beachten, dass für einen Umzug die Server mit MongoDB und Kubernetes im selben Netzwerk sein müssen. Die Knoten des MongoDB-Clusters kommunizieren über die IP-Adressen der alten Server (wo sich die alten MongoDB-Installationen befinden) und die DNS-Namen der MongoDB-Pods in K8s. Daher müssen auf den physischen Servern (mit den alten Installationen) Routen zu den Pods eingerichtet werden, und sie sollten so konfiguriert werden, dass sie einen in Kubernetes betriebenen DNS-Server verwenden (oder die benötigten Namen in /etc/hosts, obwohl es im Allgemeinen besser ist, solche Möglichkeiten zu vermeiden).

Der nächste Schritt besteht darin, den MongoDB-Cluster in den Kubernetes-Pods hochzufahren. In unserem Fall besteht der DB-Cluster aus 3 Knoten, und jeder Knoten befindet sich in einem separaten K8s-Pod – die Anzahl kann jedoch variieren. In der ConfigMap muss die Adresse des MongoDB-Masters aus der alten Installation angegeben werden: Die Knoten von MongoDB in den Pods in K8s beginnen dann sofort mit der Synchronisation mit ihm.

Nachdem alle Pods gestartet sind, bildet sich ein MongoDB-Cluster aus 6 Knoten:

Erschwerte Migration von MongoDB nach Kubernetes

Bitte beachten Sie, dass die Pods lange zum Hochfahren brauchen, da jeder Pod nacheinander gestartet wird und beim Start Daten mit dem Master synchronisiert.

Danach können Sie die Anwendung auf die neuen MongoDB-Server umschalten:

Erschwerte Migration von MongoDB nach Kubernetes

Dann bleibt nur noch, die alten Knoten aus dem MongoDB-Cluster zu entfernen, und der Umzug kann als abgeschlossen betrachtet werden:

Erschwerte Migration von MongoDB nach Kubernetes

Dieses Schema wenden wir häufig in der Produktion an und haben es zu Ihrem Vorteil im Rahmen des Moduls konzipiert, addon-operator (dieses Tool haben wir vor kurzem angekündigt), was es ermöglicht, Standardkonfigurationen von MongoDB über viele Cluster zu verteilen. Die Veröffentlichung unserer Module planen wir in Kürze, während wir Ihnen vorerst separate Anleitungen zur Verfügung stellen, mit denen Sie die vorgeschlagene Lösung in Aktion testen können, ohne den Addon-Operator zu verwenden.

Praktisch testen

Anforderungen

Details:

  • Kubernetes-Cluster (minikube ist auch geeignet);
  • Ein MongoDB-Cluster (kann sowohl auf Bare Metal bereitgestellt als auch als herkömmlicher Cluster in Kubernetes aus dem offiziellen Helm-Chart erstellt werden).

Im folgenden Beispiel wird der alte MongoDB-Cluster als mongo-old bezeichnet und im selben Kubernetes-Cluster installiert, in dem wir später auch den neuen installieren werden (mongo-new).

Wir bereiten den alten Cluster vor

1. Zum Beispiel, um das beschriebene Schema in Aktion zu demonstrieren, erstellen wir einen "alten" (d.h. migrationsbedürftigen) MongoDB-Cluster direkt in Kubernetes (tatsächlich kann er auch auf separaten Servern außerhalb von K8s laufen). Dazu laden wir das Helm-Chart herunter:

helm fetch --untar stable/mongodb-replicaset

… und bearbeiten es ein wenig, um die Authentifizierung einzurichten:

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

Außerdem kann man in values.yaml Zertifikate und vieles mehr konfigurieren.

2. Installieren wir das Chart:

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

Nach dieser Installation wird eine Test-"alte" MongoDB-Instanz gestartet:

kubectl --namespace=mongo-old get pods

Erschwerte Migration von MongoDB nach Kubernetes

Betreten wir den Pod mit dem Master und erstellen eine Testdatenbank:

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

Erschwerte Migration von MongoDB nach Kubernetes

Beim Betreten verschiedener Pods habe ich herausgefunden, dass der Master mongo-old-mongodb-replicaset-0ist. Allerdings gibt es nach der Installation des Helm-Charts einen Befehl, um zu bestimmen, MASTER_POD. In meinem Fall (für mongo-old von 3 Knoten) sieht er so aus:

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

Die Vorbereitung der alten MongoDB-Installation, deren Daten migriert werden, ist abgeschlossen.

Migration des MongoDB-Clusters

Nun werden wir eine neue MongoDB-Installation in Kubernetes bereitstellen, die vom Anwendung im Produktionsbetrieb genutzt wird.

NB: Bitte beachten Sie, dass die gleiche Version von MongoDB verwendet werden muss wie zuvor. Andernfalls besteht das Risiko von Kompatibilitätsproblemen.

Analog zum vorherigen Abschnitt (in dem wir die "alte" MongoDB-Installation simuliert haben), verwenden wir das bereits erwähnte Helm-Chart (mit dem Befehl helm fetch) und richten die Authentifizierung sowie andere Parameter ein, sofern diese verwendet werden. Zusätzlich werden wir die Datei init/on-start.sh, vorübergehend so anpassen, dass wir in Zeile 165 die Adresse des Masters ergänzen, die wir in der vorherigen Phase erhalten haben (oder die Ihnen von der MongoDB-Installation auf separaten Servern bekannt ist):

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

Wir sind bereit, die neue MongoDB-Installation zu erstellen:

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

Warten Sie, bis alle Pods gestartet sind (wenn es viele Daten gibt, kann deren Start mehrere Stunden in Anspruch nehmen):

Erschwerte Migration von MongoDB nach Kubernetes

Jetzt führen wir exec in den neuen Pod aus und schauen uns die Liste der Datenbanken an:

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

Erschwerte Migration von MongoDB nach Kubernetes

Zwei MongoDB-Cluster wurden zu einem Cluster mit 6 Knoten zusammengeführt.

Aktuell kann die Anwendung bereits auf den neuen Cluster umgeschaltet werden, aber es bleiben noch einige Schritte, um die Migration abzuschließen.

Aus der Datei init/on-start.sh entfernen wir in der neuen Installation die von uns hinzugefügte Zeile:

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

Jetzt gehen wir in den alten Master-Cluster und „stürzen“ ihn — dann wird ein neuer Master im Cluster festgelegt. Melden Sie sich im Pod mit dem MongoDB-Master an:

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

Nachdem wir das gemacht haben, ändern wir die Prioritäten der Knoten und wechseln den Master:

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

Der aktuelle Knoten ist kein Master mehr — es werden Wahlen für einen neuen durchgeführt. Da wir die Prioritäten geändert haben, wird der gewünschte Knoten Master.

NB: Standardmäßig hat jeder MongoDB-Knoten eine Priorität von 1. Oben erhöhen wir die Priorität für den gewünschten Knoten auf 2. Damit wird sicher der Mitglied des neuen Clusters der Master. Weitere Informationen zu diesen Mechanismen in MongoDB finden Sie in Dokumentation..

Wir deaktivieren die alte MongoDB-Installation, nachdem wir in den Master des neuen Clusters gegangen sind, und löschen die alten Knoten:

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")

Nach diesem Schritt können wir die Migration als abgeschlossen betrachten: Wir haben erfolgreich von dem alten MongoDB-Cluster auf das neue umgeschaltet!

Ergebnisse

Das beschriebene Verfahren ist nahezu für alle Situationen geeignet, in denen eine MongoDB-Migration oder der Umzug zu einem neuen Cluster erforderlich ist.

Der Hauptpunkt beim Transfer ist, dass die IP-Adressen der neuen Pods an die Server der alten MongoDB-Installation weitergeleitet werden müssen, sofern sich diese außerhalb von K8s befindet, sowie deren korrekte Benennung im DNS (oder /etc/hosts). In diesem Beispiel waren diese Schritte nicht erforderlich, da die Migration zwischen verschiedenen Namespaces des gleichen Kubernetes-Clusters stattfand.

P.S.

Lesen Sie auch in unserem Blog:

Quelle: habr.com

Kaufen Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Server 🔥 Kaufen Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Server | ProHoster