Elasticsearch in Kubernetes migrieren

Für ein Kundenprojekt mussten wir kürzlich eine Menge Elasticsearch-Daten in eine Kubernetes-Umgebung überführen. Schauen wir uns genauer an, wie wir das gemacht haben und worauf zu achten ist.
Die Methoden
Bei der Suche nach Wegen zur Migration zwischen zwei Elasticsearch-Clustern stehen uns verschiedene Methoden zur Verfügung.
Reindexing
Reindexing ist der Prozess des Iterierens über bestehende Dokumente und des erneuten Einfügens. Das kann verwendet werden, um einen anderen Satz von Indexierungsparametern anzuwenden, den zugrunde liegenden Index zu aktualisieren oder die Dokumente in einen anderen Index zu verschieben. Das funktioniert auch bei einer Migration zwischen verschiedenen Clustern.
Bei der Wahl dieses Ansatzes sind folgende Einschränkungen zu beachten:
- Index-Mappings und Aliases müssen manuell migriert werden
- Belastet den Cluster stark, während jedes Dokument neu indiziert wird
- Index-basierte Einstellungen müssen manuell kopiert werden
Der Vorteil dieses Ansatzes ist seine Einfachheit. Er ermöglicht es auch, gleichzeitig ein Update der Index-Version durchzuführen.
Cluster zusammenführen
Diese Methode ist die einzige, die ohne Ausfallzeit funktioniert. Bei diesem Ansatz werden die neuen Cluster-Knoten dem bestehenden Cluster hinzugefügt, die alten Knoten geleert und nach dem Umstellen aller Anwendungen auf die neuen Knoten deprovisiert. Sie setzt voraus, dass eure Knoten bidirektional kommunizieren können, was je nach eurem Setup schwierig zu erreichen sein kann.
Snapshot/Restore
Durch die Nutzung der integrierten Snapshot/Restore-Funktion werden die Nachteile des Reindexing-Ansatzes eliminiert. Snapshots können entweder von einzelnen Indizes oder dem gesamten Cluster erstellt werden, was eine schrittweise Migration ermöglicht. Der Nachteil ist die Einrichtung eines funktionierenden Snapshot-Repositories. Das erfordert entweder gemeinsam genutzten Dateispeicher oder Software von Drittanbietern, die Objektspeicher-Fähigkeiten bereitstellt.
Drittanbieter-Tools
Bei der Suche nach Migrationsoptionen haben wir auch elastic-dump bewertet, das jedoch bei einigen Indizes nicht gut funktionierte. In unserem spezifischen Setup stellte es auch einen Netzwerk-Engpass dar, da Daten auf den Host kopiert werden, auf dem das Tool ausgeführt wird.
Der Prozess
Nach der Bewertung unserer Optionen und dem Testen ihrer Durchführbarkeit an einem kleineren Datensatz entschieden wir uns aus drei Gründen für den Snapshot/Restore-Ansatz:
- Wir haben bereits ein funktionierendes Snapshot-Setup
- Unsere Index-Einstellungen sind sehr komplex, was Reindexing ausschließt
- Das Datenlayout ermöglicht eine schrittweise Migration
Langsam vorgehen
Der Cluster, den wir migrieren möchten, enthält rund 605 GiB Daten. Das alles auf einmal zu migrieren würde sehr lange dauern, und da wir das nicht ohne Ausfallzeit tun können, sollten wir diese zumindest minimieren.
Unser großer Vorteil: Die fraglichen Daten sind nach Erstellungszeit in Indizes gruppiert und ändern sich nach der Erstellung nicht mehr. Das ermöglicht es uns, Schreibvorgänge auf alte Indizes weit im Voraus zu deaktivieren und sie vor der endgültigen Migration zu verschieben. Indem wir zuerst alte Indizes verschieben, können wir uns für die größten Datenmengen Zeit lassen und die endgültige Ausfallzeit reduzieren, da nur sehr wenige Indizes aktiv beschrieben werden.
Die Migration durchführen
Fangen wir an, Daten zu verschieben. Dazu müssen wir zunächst einen Snapshot davon erstellen. Vor dem Erstellen des Snapshots muss ein bestehendes Repository vorhanden sein. In unserem Fall steht uns auf allen Knoten ein verteiltes Volume zur Verfügung, das wir als Snapshot-Repository wählen.
Um den Snapshot zu erstellen, entweder ein grafisches Tool verwenden oder die entsprechende API-Anfrage direkt stellen:
curl -X PUT "localhost:9200/_snapshot/<repository_name>/migration_snapshot?wait_for_completion=true&pretty" -H 'Content-Type: application/json' -d' {} '
Das erstellt einen Snapshot namens migration_snapshot. Wenn eure Indizes sehr groß sind, solltet ihr in Betracht ziehen, den Parameter wait_for_completion=true zu entfernen und den Snapshot regelmäßig mit folgendem API-Aufruf zu überprüfen:
curl "http://localhost:9200/_snapshot/<repository_name>/_current"
Nachdem der Snapshot abgeschlossen ist, brauchen wir eine Möglichkeit, ihn zum neuen Cluster zu übertragen. Der einfachste Weg für uns war, den Inhalt des Backup-Verzeichnisses mit python -m http.server bereitzustellen. Wenn ein RWX-Volume verfügbar ist, ist das Mounten in alle Elasticsearch-Pods ebenfalls eine praktikable Option.
Um aus diesem Snapshot wiederherzustellen, muss der Cluster so konfiguriert sein, dass er den Remote-Host als gültigen Backup-Pfad erlaubt. Bei Verwendung des ECK-Operators sieht die Konfiguration etwa so aus:
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
name: example-cluster
spec:
# ...
nodeSets:
- name: default
config:
repositories.url.allowed_urls: 'http://<your-remote-endpoint-including-port>'
# ...
Sobald das ausgerollt ist, kann diese URL verwendet werden, um ein neues Snapshot-Repository zu erstellen.
curl -X PUT "localhost:9200/_snapshot/migration_repository?pretty" -H 'Content-Type: application/json' -d'
{
"type": "url",
"settings": {
"url": "http://<your-remote-endpoint-including-port>"
}
}
'
Wenn die Konfiguration korrekt angewendet wurde, erstellt das migration_repository, das auf den Remote-Endpunkt zeigt.
Um zu überprüfen, dass alles wie erwartet funktioniert, inspiziert ihr den Inhalt des Snapshot-Repos:
curl -X GET 'http://localhost:9200/_snapshot/migration_repository/*'
{
"snapshots": [
{
"snapshot": "migration_snapshot",
"uuid": "w1UH162UQkeDuQ0fVWyMGA",
"repository": "migration_repository",
"version_id": 7150299,
"version": "7.15.2",
"indices": [
"..."
],
"data_streams": [
],
"include_global_state": true,
"state": "SUCCESS",
"start_time": "2023-01-24T09:49:58.937Z",
"start_time_in_millis": 1674553798937,
"end_time": "2023-01-24T09:53:51.665Z",
"end_time_in_millis": 1674554031665,
"duration_in_millis": 232728,
"failures": [
],
"shards": {
"total": 833,
"failed": 0,
"successful": 833
},
},
],
"total": 1,
"remaining": 0
}
Großartig! Wenn ihr die alten Snapshots hier nicht seht, stellt sicher, dass die korrekten Dateien bereitgestellt werden. Die Datei index.latest sollte im Root-Verzeichnis liegen.
Der letzte Schritt ist das Importieren der Indizes dieses Snapshots:
curl -X POST "localhost:9200/_snapshot/migration_repository/migration_snapshot/_restore?wait_for_completion=true&pretty" -H 'Content-Type: application/json' -d'
{
"ignore_unavailable": true,
"include_global_state": true,
"include_aliases": true
}
'
Auch hier könnt ihr den Parameter wait_for_completion=true weglassen und den Fortschritt manuell überprüfen. Wenn ihr den Umfang begrenzen wollt, gebt einen indices-Schlüssel an.
Und fertig! Der Cluster beginnt, die Shards auf einen passenden Knoten zu verteilen, und euer neuer Cluster ist einsatzbereit.
Agent Hub
Gehen Sie über vereinzelte AI-Piloten hinaus und schaffen Sie eine sichere, skalierbare Grundlage für Agentic AI in Ihrer gesamten Organisation.
Zur Demo




