
Dieser Artikel setzt unser über die Migration von RabbitMQ fort und befasst sich mit MongoDB. Da wir zahlreiche Kubernetes- und MongoDB-Cluster betreuen, sind wir auf die natürliche Notwendigkeit gestoßen, Daten von einer Installation zur anderen zu migrieren, und das ohne Ausfallzeiten. Die Hauptszenarien sind wie zuvor: der Transfer von MongoDB von einem virtuellen/einer physischen Server in Kubernetes oder der Transfer von MongoDB innerhalb eines Kubernetes-Clusters (von einem Namespace zu einem anderen).
Unser Rezept ist für Fälle gedacht, in denen ein alter MongoDB-Cluster (zum Beispiel aus 3 Knoten, der sich bereits in K8s befindet oder auf alten Servern läuft) in Betrieb ist, mit dem eine Anwendung betrieben wird, die in Kubernetes gehostet wird:

Wie werden wir einen solchen Cluster in eine neue Produktion in Kubernetes übertragen?
Theorie
Der allgemeine Migrationsalgorithmus ähnelt dem, der in der Situation mit RabbitMQ beschrieben wurde.
Es ist wichtig zu beachten, dass es erforderlich ist, dass die Server mit MongoDB und Kubernetes im selben Netzwerk sind, um einen Umzug zu ermöglichen. Die Knoten des MongoDB-Clusters werden über die IP-Adressen der alten Server (auf denen sich die alten MongoDB-Installationen befinden) und über die DNS-Namen der Pods mit MongoDB in K8s miteinander kommunizieren. Daher müssen auf den physischen Servern (mit alten Installationen) die Routen zu den Pods durchgereicht und diese so konfiguriert werden, dass sie den DNS-Server verwenden, der in Kubernetes arbeitet (oder die benötigten Namen in /etc/hosts, obwohl es im Allgemeinen besser ist, diese Möglichkeit zu vermeiden).
Der nächste Schritt besteht darin, den MongoDB-Cluster in den Pods von Kubernetes zu starten. In unserem Fall besteht der DB-Cluster aus 3 Knoten, und jeder Knoten befindet sich in einem separaten K8s-Pod — die Anzahl kann jedoch auch anders sein. In der ConfigMap muss die IP-Adresse des Masters von MongoDB aus der alten Installation angegeben werden: Dann beginnen die MongoDB-Knoten, die sich in den Pods in K8s befinden, sofort mit der Synchronisation mit ihm.
Nachdem alle Pods gestartet sind, wird ein MongoDB-Cluster aus 6 Knoten gebildet:

Bitte beachten Sie, dass die Pods lange brauchen, um zu starten, da jeder Pod nacheinander gestartet wird und beim Start die Daten mit dem Master synchronisiert.
Danach kann die Anwendung auf die Verwendung der neuen MongoDB-Server umgeschaltet werden:

Und es bleibt nur noch, die alten Knoten aus dem MongoDB-Cluster zu entfernen, nach dem der Umzug als abgeschlossen angesehen werden kann:

Dieses Schema wenden wir häufig in der Produktion an, und zur Vereinfachung der Nutzung haben wir es im Rahmen des Moduls k (dieses Tool haben wir ), die es ermöglicht, Standardkonfigurationen von MongoDB über viele Cluster zu verteilen. Wir planen, unsere Module bald zu veröffentlichen, aber derzeit präsentieren wir einzelne Anleitungen, mit denen Sie die vorgeschlagene Lösung in Aktion ausprobieren können, ohne den addon-operator zu verwenden.
Praktischer Versuch
Anforderungen
Unterlagen:
- Kubernetes-Cluster (minikube ist auch geeignet);
- MongoDB-Cluster (kann sowohl auf bare metal bereitgestellt werden als auch als normaler Cluster in Kubernetes aus dem offiziellen Helm-Chart erstellt werden).
Im folgenden Beispiel wird der alte Cluster mit MongoDB genannt mongo-old und wird im selben Kubernetes-Cluster installiert, in dem wir später auch den neuen (mongo-new).
Alten Cluster vorbereiten
1. Für das Beispiel, das das beschriebene Schema in Aktion demonstriert, erstellen wir einen „alten“ (d.h. zu migrierenden) MongoDB-Cluster direkt in Kubernetes (in der Realität kann er sich auch auf separaten Servern außerhalb von K8s befinden). Dafür laden wir das Helm-Chart herunter:
helm fetch --untar stable/mongodb-replicaset… und bearbeiten es ein wenig, um die Autorisierung einzustellen:
auth:
enabled: true
adminUser: mongo
adminPassword: pa33w0rd
# metricsUser: metrics
# metricsPassword: password
# key: keycontent
# existingKeySecret:
# existingAdminSecret:
# exisitingMetricsSecret: Auch in values.yaml können Zertifikate und vieles mehr konfiguriert werden.
2. Installieren wir das Chart:
helm install . --name mongo-old --namespace mongo-oldDaraufhin wird eine Testinstallation von „mongo-old“ MongoDB gestartet:
kubectl --namespace=mongo-old get pods 
Wir gehen in 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 
Indem ich in verschiedene Pods gehe, habe ich herausgefunden, dass der Master mongo-old-mongodb-replicaset-0ist. Allerdings wird zur einfacheren Lösung dieses Problems nach der Installation des Helm-Charts ein Befehl ausgegeben, 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())"'; doneDamit ist die Vorbereitung der alten MongoDB-Installation, deren Daten übertragen werden, abgeschlossen.
Migration des MongoDB-Clusters
Jetzt werden wir eine neue MongoDB-Installation bereitstellen, die in Kubernetes laufen wird und von der Anwendung in der Produktion genutzt werden soll.
NB: Ich weise darauf hin, dass dieselbe Version von MongoDB verwendet werden sollte wie zuvor. Andernfalls besteht das Risiko, auf Kompatibilitätsprobleme zu stoßen.
Analog zum vorherigen Abschnitt (in dem wir die „alte“ MongoDB-Installation imitierten) nehmen wir das bereits erwähnte Helm-Chart (mit dem Befehl helm fetch) und richten die Authentifizierung sowie andere Parameter ein, sofern diese verwendet werden. Außerdem korrigieren wir die Datei init/on-start.sh, indem wir vorübergehend in der Zeile 165 die Adresse des Masters hinzufügen, die wir im vorherigen Schritt erhalten haben (oder die Ihnen von der Installation von MongoDB 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-newWarten Sie, bis alle Pods gestartet sind (wenn viele Daten vorhanden sind, kann der Start Stunden dauern):

Jetzt machen wir exec in einen neuen Pod und sehen uns die Liste der Datenbanken an:
kubectl --namespace=mongo-new exec -ti mongo-new-mongodb-replicaset-0 mongo 
Die beiden MongoDB-Cluster wurden zu einem Cluster mit 6 Knoten zusammengeführt.
Derzeit kann die Anwendung bereits auf den neuen Cluster umgeschaltet werden, aber es sind noch einige Schritte zur vollständigen Migration erforderlich.
Aus der Datei init/on-start.sh entfernen wir die von uns hinzugefügte Zeile in der neuen Installation:
peers='mongo-old-mongodb-replicaset-0.mongo-old-mongodb-replicaset.mongo-old.svc.cluster.local:27017'Jetzt gehen wir zum alten Master-Cluster und "stürzen" ihn — dann wird ein neuer Master im Cluster zugewiesen. Wir betreten den Pod mit dem MongoDB-Master:
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 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 stattfinden. Da wir die Prioritäten geändert haben, wird der gewünschte Knoten zum Master.
NB: Standardmäßig haben alle MongoDB-Knoten eine Priorität von 1. Hier erhöhen wir die Priorität des gewünschten Knotens auf 2. Auf diese Weise wird der Mitglied des neuen Clusters sicher zum Master. .
Wir werden die alte MongoDB-Installation deaktivieren und anschließend zum Master der neuen Umgebung gehen und die alten Knoten löschen:
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 kann die Migration als abgeschlossen angesehen werden: Wir haben erfolgreich vom alten MongoDB-Cluster auf den neuen umgeschaltet!
Ergebnisse
Das beschriebene Schema eignet sich praktisch für alle Fälle, in denen MongoDB übertragen oder einfach in einen neuen Cluster umgezogen werden muss.
Der Hauptpunkt beim Umzug ist die Notwendigkeit, die IP-Adressen der neuen Pods an die Server der alten MongoDB-Installation weiterzuleiten, 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 Namensbereichen desselben Kubernetes-Clusters erfolgte.
P.S.
Lesen Sie auch in unserem Blog:
- «»;
- «»;
- «».
Quelle: habr.com
