
Dieser Artikel setzt unser
aktuelles RabbitMQ-Migrationsmaterial fort und ist MongoDB gewidmet. Da wir viele Kubernetes- und MongoDB-Cluster bedienen, müssen wir natürlich Daten von einer Installation zur anderen migrieren, ohne Ausfallzeiten. Die Hauptszenarien sind dieselben: Übertragung von MongoDB von einem virtuellen / eisernen Server auf Kubernetes oder Übertragung von MongoDB innerhalb eines Kubernetes-Clusters (von einem Namespace zu einem anderen).
Unser Rezept ist für Fälle gedacht, in denen der alte MongoDB-Cluster funktioniert (z. B. von 3 Knoten, die sich entweder bereits in K8s oder auf alten Servern befinden), mit denen eine in Kubernetes gehostete Anwendung funktioniert:

Wie werden wir einen solchen Cluster auf eine neue Produktion in Kubernetes übertragen?
Theorie
Der allgemeine Migrationsalgorithmus ähnelt dem in der Situation mit RabbitMQ beschriebenen.
Es ist wichtig zu beachten, dass Server mit MongoDB und Kubernetes sich im selben Netzwerk befinden müssen, um verschoben werden zu können. Die Knoten des MongoDB-Clusters kommunizieren über die IP-Adresse alter Server (auf denen sich die alten MongoDB-Installationen befinden) und die DNS-Namen der Pods von MongoDB in K8s miteinander. Daher ist es auf Eisenservern (mit alten Installationen) erforderlich, Routen an Pods weiterzuleiten und diese dann so zu konfigurieren, dass sie den in Kubernetes ausgeführten DNS-Server verwenden (oder die erforderlichen Namen in
/etc/hosts
registrieren, obwohl es im Allgemeinen besser ist, diese Möglichkeit zu vermeiden )
Der nächste Schritt besteht darin, den MongoDB-Cluster in Kubernetes-Pods zu erhöhen. In unserem Fall besteht der Datenbankcluster aus 3 Knoten, und jeder Knoten befindet sich in einem separaten Pod'8-K8. Die Anzahl kann jedoch unterschiedlich sein. In ConfigMap müssen Sie die Adresse des MongoDB-Masters aus der alten Installation angeben: Dann beginnen die MongoDB-Knoten in den Pods in K8s sofort mit der Synchronisierung.
Nachdem alle Pods hochgefahren sind, wird ein MongoDB-Cluster mit 6 Knoten gebildet:

Bitte beachten Sie, dass Pods für eine lange Zeit ansteigen, da jeder Pod der Reihe nach startet und zum Zeitpunkt des Starts die Daten des Assistenten synchronisiert.
Danach können Sie die Anwendung wechseln, um die neuen MongoDB-Server zu verwenden:

Und es bleiben nur die alten Knoten aus dem MongoDB-Cluster zu entfernen, wonach der Umzug als abgeschlossen betrachtet werden kann:

Wir verwenden dieses Schema häufig in der Produktion und haben es zur Vereinfachung in das
Addon-Operator- Modul implementiert (wir
haben dieses Dienstprogramm
kürzlich angekündigt ), mit dem wir typische MongoDB-Konfigurationen auf viele Cluster verteilen können. Wir planen, unsere Module in naher Zukunft zu veröffentlichen, aber jetzt präsentieren wir separate Anweisungen, mit denen Sie die vorgeschlagene Lösung in Aktion und ohne Verwendung des Addon-Operators testen können.
Wir versuchen es in der Praxis
Anforderungen
Details:
- Kubernetes Cluster (Minikube ist auch geeignet);
- MongoDB-Cluster (kann auf Bare-Metal-Basis bereitgestellt und als regulärer Cluster in Kubernetes aus der offiziellen Helm-Tabelle erstellt werden).
In dem unten beschriebenen Beispiel wird der alte Cluster mit MongoDB als
mongo-old
und im selben Kubernetes-Cluster installiert, wo wir in Zukunft den neuen (
mongo-new
) installieren werden.
Vorbereiten des alten Clusters
1. Für ein Beispiel, das das beschriebene Schema in Aktion demonstriert, erstellen wir einen „alten“ (dh migrationsabhängigen) MongoDB-Cluster direkt in Kubernetes (in Wirklichkeit kann er sich auch auf separaten Servern außerhalb von K8s befinden). Laden Sie dazu die Helmkarte herunter:
helm fetch --untar stable/mongodb-replicaset
... und bearbeiten Sie es ein wenig, indem Sie die Autorisierung einrichten:
auth: enabled: true adminUser: mongo adminPassword: pa33w0rd # metricsUser: metrics # metricsPassword: password # key: keycontent # existingKeySecret: # existingAdminSecret: # exisitingMetricsSecret:
Auch in
values.yaml
Sie Zertifikate und vieles mehr konfigurieren.
2. Stellen Sie das Diagramm ein:
helm install . --name mongo-old --namespace mongo-old
Danach wird die "alte" Testinstallation von MongoDB gestartet:
kubectl --namespace=mongo-old get pods

Lassen Sie uns mit seinem Master zum Pod gehen und eine Testbasis erstellen:
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

Als ich verschiedene Pods betrat, fand ich heraus, dass der Master
mongo-old-mongodb-replicaset-0
. Zur bequemeren Lösung dieses Problems wird jedoch nach der Installation des Helm-Diagramms ein Befehl zum Bestimmen von
MASTER_POD
angezeigt. In meinem Fall (für
mongo-old
von 3 Knoten) sieht es 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
Damit ist die Vorbereitung der alten MongoDB-Installation, deren Daten übertragen werden, fertig.
MongoDB-Cluster-Migration
Jetzt stellen wir die neue MongoDB-Installation bereit, die sich in Kubernetes befindet und von der Anwendung in der Produktion verwendet wird.
NB : Bitte beachten Sie, dass dieselbe Version von MongoDB wie zuvor verwendet werden sollte. Andernfalls besteht das Risiko von Kompatibilitätsproblemen.In Analogie zum vorherigen Abschnitt (in dem wir die „alte“ MongoDB-Installation imitiert haben) nehmen wir das bereits erwähnte Helm-Diagramm (mit dem Befehl
helm fetch
) und konfigurieren die Autorisierung sowie gegebenenfalls andere Parameter. Darüber hinaus reparieren wir die Datei
init/on-start.sh
, indem wir in Zeile 165 vorübergehend die Adresse des Assistenten hinzufügen, der im vorherigen Schritt erhalten wurde (oder Ihnen aus 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, eine neue MongoDB-Installation zu erstellen:
helm install . --name mongo-new --namespace mongo-new
Wir warten, bis alle Pods gestartet sind (wenn viele Daten vorhanden sind, kann der Start Stunden dauern):

Jetzt machen wir
exec
in einem neuen Pod und schauen uns die Liste der Basen an:
kubectl --namespace=mongo-new exec -ti mongo-new-mongodb-replicaset-0 mongo

Zwei MongoDB-Cluster werden zu einem zusammengefasst, der aus 6 Knoten besteht.
Im Moment können Sie die Anwendung bereits auf einen neuen Cluster umstellen, es bleiben jedoch noch einige Schritte, um die Migration abzuschließen.
Aus der
init/on-start.sh
in der neuen Installation entfernen wir die Zeile, die wir hinzugefügt haben:
peers='mongo-old-mongodb-replicaset-0.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017'
Gehen wir nun in den alten Master des Clusters und "stürzen" ihn - dann wird ein neuer Master im Cluster zugewiesen. Wir gehen mit dem MongoDB-Master in die Kapsel:
kubectl --namespace=mongo-old exec -ti mongo-old-mongodb-replicaset-0 mongo use admin db.auth('mongo','password')
Danach ändern wir die Prioritäten der Knoten und den Assistenten:
cfg = rs.conf() cfg.members[5].priority = 2 rs.reconfig(cfg) rs.stepDown(120)
Der aktuelle Knoten ist kein Master mehr - eine Neuwahl wird stattfinden. Wenn wir die Prioritäten ändern, wird der Knoten, den wir benötigen, zum Master.
NB : Standardmäßig haben alle MongoDB-Knoten eine Priorität von 1. Oben erhöhen wir die Priorität des benötigten Knotens auf 2. Somit wird ein Mitglied eines neuen Clusters definitiv ein gemeinsamer Meister. Weitere Informationen zur Funktionsweise dieser Mechanismen in MongoDB finden Sie in der Dokumentation .Deaktivieren Sie die alte MongoDB-Installation, rufen Sie den neuen Assistenten auf und löschen Sie 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")
Danach kann die Migration als abgeschlossen betrachtet werden: Wir haben erfolgreich vom alten MongoDB-Cluster zum neuen gewechselt!
Zusammenfassung
Das beschriebene Schema eignet sich für fast alle Fälle, in denen Sie MongoDB übertragen oder einfach in einen neuen Cluster wechseln müssen.
Möglicherweise besteht die Hauptnuance während der Übertragung darin, dass die IP-Adressen neuer Pods an die Server der alten MongoDB-Installation weitergeleitet werden müssen, wenn sie sich außerhalb von K8s befinden, und sie in DNS (oder
/etc/hosts
) korrekt benannt werden müssen. Im Beispiel waren diese Schritte nicht erforderlich, da die Migration zwischen verschiedenen Namespaces desselben Kubernetes-Clusters erfolgte.
PS
Lesen Sie auch in unserem Blog: