Server auf neuen VPS migrieren: Anleitung
Migrieren Sie einen Live-Server mit Inventar, Neuaufbau statt Klonen, Datenbank-Dump, früher DNS-TTL-Senkung und getesteter Umschaltung ohne unnötige Ausfallzeit.
Migration eines Servers auf einen neuen VPS als geübter Umschaltvorgang
Behandeln Sie die Migration eines Servers auf einen neuen VPS als geübten Umschaltvorgang und nicht als reinen Kopiervorgang. Bauen Sie den neuen Server von Grund auf neu auf, synchronisieren Sie die Daten zweimal und stellen Sie unter der eigenen IP-Adresse des neuen Servers dessen Funktionsfähigkeit unter Beweis, bevor Sie DNS ändern. Schalten Sie anschließend die DNS-Einträge um und lassen Sie den alten Server weiterlaufen, bis Sie sicher sind, dass alles funktioniert. Das Kopieren der Daten ist der einfache Teil. Die Reihenfolge der Arbeitsschritte entscheidet darüber, ob die Migration problemlos oder kostspielig verläuft.
Diese Anleitung behandelt einen einzelnen Linux-Server mit einer Webanwendung, einer Datenbank und einem TLS-Zertifikat (Transport Layer Security). Damit sind die meisten Setups mit einem einzelnen Server abgedeckt. Es sind zwei Hosts beteiligt. Deshalb gibt jedes Beispiel in einem Kommentar an, auf welchem Host es ausgeführt wird. Die Adressen stammen aus den Dokumentationsbereichen: 198.51.100.10 ist der alte Server, 203.0.113.20 ist der neue Server.
Lesen Sie das vollständige Runbook, bevor Sie beginnen. Der erste Schritt, das Absenken der DNS-TTL, muss mehrere Tage vor dem Schritt erfolgen, auf den es tatsächlich ankommt.
Bestandsaufnahme vor dem Aufbau
Sie können keinen Server neu aufbauen, den Sie nicht beschrieben haben. Nehmen Sie sich eine Stunde Zeit und dokumentieren Sie, welche Aufgaben der alte Server übernimmt. Nach einer Migration fällt immer genau das aus, woran niemand gedacht hat: ein Cron-Job, eine Firewall-Ausnahme oder eine Umgebungsdatei außerhalb des Anwendungsverzeichnisses.
Führen Sie diese Befehle auf dem alten Server aus. Bewahren Sie die Ausgabe an einem Ort auf, den Sie vom neuen Server aus erreichen können.
# old server: packages you asked for, not the dependencies they pulled in
apt-mark showmanual > ~/inv-packages.txt
# old server: what runs now, and what starts at boot
systemctl list-units --type=service --state=running --no-pager > ~/inv-services.txt
systemctl list-unit-files --state=enabled --no-pager >> ~/inv-services.txt
systemctl list-timers --all --no-pager > ~/inv-timers.txt
# old server: what is listening, on which address and port
sudo ss -tulpn > ~/inv-ports.txt
# old server: human accounts, skipping the system ones
awk -F: '$3 >= 1000 && $3 < 65534 {print $1, $3, $6, $7}' /etc/passwdapt-mark showmanual ist die sinnvollere Liste, weil sie alle Pakete erfasst, die als Abhängigkeiten installiert wurden. Eine vollständige dpkg --get-selections auf einem fünf Jahre alten Server umfasst zweitausend Zeilen und sagt nichts über die Absicht hinter der Installation aus.
Geplante Aufgaben können an zwei Stellen liegen. Prüfen Sie daher beide. Einen Job, der nur monatlich ausgeführt wird, entdecken Sie sonst erst sechs Wochen nach der Migration.
# old server: per-user crontabs, then the system drop-ins
for u in $(cut -d: -f1 /etc/passwd); do sudo crontab -lu "$u" 2>/dev/null | sed "s/^/$u: /"; done
sudo ls -la /etc/cron.d /etc/cron.daily /etc/cron.hourlyPrüfen Sie anschließend die Bestandteile, die keine gewöhnlichen Dateien sind: Firewall-Regeln, Zertifikate, Datenbanken und die tatsächlich zu übertragende Datenmenge.
# old server
sudo ufw status verbose # or: sudo nft list ruleset
sudo certbot certificates
sudo -u postgres psql -c '\l' # or: sudo mysql -e 'SHOW DATABASES;'
sudo du -xh --max-depth=1 / | sort -hcertbot certificates gibt den Namen jedes Zertifikats, die abgedeckten Domains, das Ablaufdatum und die Pfade der Dateien auf dem Datenträger aus. Diese Ausgabe ist Ihre TLS-Checkliste. du -x bleibt in einem Dateisystem. Daher durchläuft der Befehl kein eingebundenes Backup-Volume und meldet keine zehnmal zu große Zahl.
Zwei Punkte liegen außerhalb des Servers und werden jedes Mal vergessen. Erstens alle Drittanbieter, die die IP-Adresse Ihres Servers in einer Allowlist führen: ein Zahlungs-Gateway, eine verwaltete Datenbank, ein SMTP-Relay oder eine Partner-API. Der neue Server hat eine neue Adresse. Daher müssen Sie bei diesen Allowlists die neue IP vor dem Umschalten hinzufügen, nicht danach. Zweitens DNS-Einträge, die Sie nicht selbst erstellt haben, etwa ein MX-Eintrag oder ein SPF-Eintrag, der die alte IP-Adresse als Text enthält.
Warum Sie das alte Root-Dateisystem neu erstellen, statt es zu klonen
Das vollständige Klonen eines Root-Dateisystems auf den neuen VPS wirkt schneller. Das ist es auch – bis es nicht mehr funktioniert. Ein Root-Dateisystem, das jahrelang produktiv genutzt wurde, enthält manuell bearbeitete Konfigurationen, die niemand dokumentiert hat, Pakete aus einem Repository, das nicht mehr existiert, sowie eine Boot-Konfiguration, die für die virtuelle Hardware der alten Plattform erstellt wurde. Sie übernehmen alles, einschließlich des Grundes für die Migration.
Eine Neuerstellung dauert am ersten Tag länger und ist danach jeden Tag günstiger. Sie installieren die aktuelle Version, wenden Ihre grundlegende Härtung an und kopieren anschließend nur die Daten: das Anwendungsverzeichnis, die Site-Konfigurationen, den Datenbank-Dump, die Zertifikate und die Benutzer-Uploads. Alles, was Sie nicht erklären können, wird nicht übernommen. Richten Sie den neuen Server so ein, wie Sie jeden Server einrichten würden: mit den ersten zehn Minuten auf einem neuen VPS. Fügen Sie anschließend die Dienste aus dem Inventar einzeln hinzu und prüfen Sie jeden Dienst, bevor Sie mit dem nächsten fortfahren.
Wenn ein Image- oder Snapshot-Restore die richtige Entscheidung ist
Es gibt eine begründete Ausnahme vom Neuaufbau. Wenn der alte Server nicht bootet oder die Anwendung nicht mehr aus dem Quellcode neu erstellt werden kann, ist das Wiederherstellen eines Provider-Images oder Snapshots die pragmatische Lösung. Diese Lösung hat klare Grenzen: Sie funktioniert innerhalb eines Providers und häufig nur innerhalb einer Planfamilie, weil die wiederhergestellte Festplatte die virtuellen Geräte und die Netzwerknamen dieser Plattform erwartet.
Ein Snapshot eines laufenden Systems weist außerdem dasselbe Konsistenzproblem auf wie jede andere dateibasierte Kopie einer aktiven Datenbank. Betrachten Sie die Image-Wiederherstellung als Wiederherstellungsweg und nicht als Migrationsplan. Lesen Sie warum ein Snapshot nicht dasselbe wie ein Backup ist, bevor Sie darauf einen Plan aufbauen.
So werden die Dateien übertragen: rsync über SSH
Führen Sie rsync auf dem alten Server aus und übertragen Sie die Daten auf den neuen Server. Das Push-Verfahren ist meist einfacher, weil die Daten bereits auf dem alten Server liegen und dort vollständig unter sudo gelesen werden können.
# old server: dry run first, and read what it says it will do
sudo rsync -aHAX --dry-run --itemize-changes \
-e 'ssh -i /root/.ssh/id_ed25519' \
/srv/app/ deploy@203.0.113.20:/srv/app/
# old server: the real bulk pass
sudo rsync -aHAX --info=progress2 \
-e 'ssh -i /root/.ssh/id_ed25519' \
/srv/app/ deploy@203.0.113.20:/srv/app/Die Optionen sind wichtig. -a übernimmt Berechtigungen, Zeitstempel, symbolische Links und Eigentümer. -H erhält Hardlinks als Hardlinks, anstatt sie in separate Kopien aufzulösen. -A kopiert POSIX-ACLs (Access Control Lists), und -X kopiert erweiterte Attribute. Ohne diese beiden Optionen kann sich eine scheinbar identische Datei anders verhalten, weil SELinux-Labels und ACLs in erweiterten Attributen gespeichert werden und sie sonst nirgends erfasst sind.
Hier führen zwei Details zu den meisten Fehlern.
Der abschließende Schrägstrich bestimmt, wo die Daten landen. /srv/app/ bezeichnet den Inhalt dieses Verzeichnisses. /srv/app bezeichnet das Verzeichnis selbst. Bei einem Fehler entsteht auf dem neuen Server /srv/app/app. Die Anwendung startet dann und meldet fehlende Dateien, weil die konfigurierten Pfade jetzt eine Ebene zu kurz sind.
Unter sudo bezeichnet die Tilde das Home-Verzeichnis von root. Wenn Sie -e 'ssh -i ~/.ssh/id_ed25519' innerhalb eines sudo rsync angeben, wird nach dem Schlüssel in /root/.ssh gesucht, nicht im eigenen Home-Verzeichnis. Befindet sich der Schlüssel dort nicht, gibt SSH Permission denied (publickey) aus, rsync gibt rsync: connection unexpectedly closed aus und beendet sich mit einem Status ungleich null. Geben Sie den vollständigen Pfad zum Schlüssel an. Wenn diese Authentifizierungsmeldung nach der Korrektur des Pfads weiterhin erscheint, hat der Fehler bei der Publickey-Authentifizierung nur wenige mögliche Ursachen. Als Nächstes sollten Sie die Verzeichnisberechtigungen auf dem neuen Server prüfen.
Für die Eigentümer müssen Sie eine Entscheidung treffen. Wenn rsync als root ausgeführt wird, ordnet es Eigentümer und Gruppe standardmäßig anhand des Namens zu. Eine Datei, die auf dem alten Server www-data gehört, gehört auf dem neuen Server dann www-data, auch wenn sich die numerische UID (User ID) unterscheidet. Für einen Neuaufbau ist das normalerweise richtig. Fügen Sie --numeric-ids nur hinzu, wenn Sie ein Dateisystem kopieren, dessen Konten auf dem Ziel nicht vorhanden sind. Prüfen Sie das Ergebnis anschließend mit ls -ln, weil eine Datei, deren UID keinem Konto zugeordnet ist, als reine Zahl angezeigt wird und jeder Dienst, der sie liest, den Zugriff verweigert bekommt.
Führen Sie den umfangreichen Kopiervorgang mehrere Tage vorher aus, während der alte Server noch Netzwerkverkehr bedient. Wiederholen Sie ihn beliebig oft: rsync überträgt nur geänderte Daten, daher dauert der zweite Durchlauf Minuten statt Stunden. Der letzte Durchlauf im Umschaltfenster erhält zusätzlich --delete, damit Dateien, die auf dem alten Server gelöscht wurden, auch auf dem neuen Server verschwinden.
# old server: final pass, inside the window, after the app has stopped writing
sudo rsync -aHAX --delete --info=progress2 \
-e 'ssh -i /root/.ssh/id_ed25519' \
/srv/app/ deploy@203.0.113.20:/srv/app/--delete löscht am Ziel Dateien, die an der Quelle nicht mehr vorhanden sind. Ein falscher Quellpfad zusammen mit --delete leert daher das Zielverzeichnis. Führen Sie den Befehl jedes Mal zuerst mit --dry-run aus. Lange Übertragungen brechen außerdem ab, wenn die SSH-Sitzung Ihres Laptops getrennt wird. Starten Sie sie deshalb auf dem alten Server innerhalb von tmux oder screen. Fügen Sie --bwlimit=20M hinzu, wenn die Kopie die Verbindung auslastet, während der alte Server weiterhin Benutzer bedient.
So wird die Datenbank verschoben: ein nativer Dump
Eine Datenbank ist kein Verzeichnis aus Dateien, auch wenn sie so aussieht. Sie besteht aus Dateien, dem Zustand im Arbeitsspeicher und einem Write-Ahead-Log. Konsistent ist sie nur zu den Zeitpunkten, die die Datenbank selbst festlegt. Verwenden Sie das dafür vorgesehene Tool.
PostgreSQL benötigt zwei Dumps, weil Rollen clusterweit gelten und pg_dump diese nicht enthält:
# old server
sudo -u postgres pg_dumpall --globals-only -f /var/backups/globals.sql
sudo -u postgres pg_dump -Fc -f /var/backups/appdb.dump appdb# new server: restore in this order
sudo -u postgres psql -f /var/backups/globals.sql
sudo -u postgres createdb -O appuser appdb
sudo -u postgres pg_restore -d appdb --no-owner /var/backups/appdb.dumpWenn Sie globals.sql überspringen, werden alle Tabellen wiederhergestellt, aber keine Anwendungsrolle kann sie lesen. Die GRANT-Anweisungen verweisen dann auf einen Benutzer, der nicht existiert. -Fc schreibt das benutzerdefinierte Archivformat. Dieses kann nur pg_restore lesen und ermöglicht später die Wiederherstellung ausgewählter Tabellen. Stellen Sie das Archiv in derselben oder einer neueren Major-Version wieder her. Eine Wiederherstellung in eine ältere Version, beispielsweise von 17 auf 16, wird nicht unterstützt. pg_restore lehnt das Archiv mit einem Fehler wegen einer nicht unterstützten Version im Dateikopf ab, bevor es etwas schreibt.
MySQL und MariaDB verwenden einen Befehl mit vier Optionen, die standardmäßig nicht aktiviert sind:
# old server
sudo mysqldump --single-transaction --routines --triggers --events \
--databases appdb > /var/backups/appdb.sql# new server
sudo mysql < /var/backups/appdb.sql--single-transaction erstellt einen konsistenten Snapshot, ohne Schreibvorgänge zu blockieren. Das gilt jedoch nur für InnoDB-Tabellen. Eine MyISAM-Tabelle in derselben Datenbank wird ohne diese Garantie kopiert. Prüfen Sie daher die verwendeten Storage-Engines, bevor Sie dem Dump vertrauen. --routines, --triggers und --events sind standardmäßig deaktiviert. Ein einfacher Dump stellt daher Ihre Daten wieder her, lässt gespeicherte Prozeduren und geplante Events jedoch unbemerkt zurück. Datenbankbenutzer und ihre Berechtigungen befinden sich in der Systemdatenbank mysql. Ein --databases appdb-Dump umfasst diese Datenbank nie. Erstellen Sie die Benutzer und Berechtigungen daher auf dem neuen Server mit CREATE USER und GRANT neu. MariaDB 11 liefert dasselbe Tool als mariadb-dump aus und behält mysqldump als symbolischen Link bei. Ab August 2026 funktionieren daher beide Namen.
SQLite besteht aus einer einzelnen Datei. Wenn Sie diese kopieren, während die Anwendung schreibt, erhalten Sie eine inkonsistente Datei. Dafür gibt es einen eigenen sicheren Weg:
# old server
sqlite3 /var/lib/app/app.db ".backup '/var/backups/app.db'"Unabhängig von der Engine sollten Sie den Dump prüfen, bevor Sie ihm vertrauen. Ein Dump, der abgebrochen wurde, weil der Datenträger vollgelaufen ist, wird ohne Fehlermeldung wiederhergestellt, bis zu der Stelle, an der er abgeschnitten wurde.
# old server: a complete mysqldump ends with a line reading "-- Dump completed on ..."
tail -n 3 /var/backups/appdb.sql
# new server: after restore, count rows in a table whose size you know
sudo mysql -e 'SELECT COUNT(*) FROM appdb.orders;'Warum Sie eine laufende Datenbank nicht mit rsync kopieren können
rsync kopiert Dateien einzeln. Eine laufende Datenbank schreibt gleichzeitig in mehrere Dateien. Wenn rsync die letzte Datei erreicht, ist die erste bereits nicht mehr aktuell. Die Kopie enthält Seiten aus unterschiedlichen Zeitpunkten. Diesen Zustand hatte die Datenbank nie. Das Ergebnis ist entweder ein Server, der den Start verweigert, oder im schlimmsten Fall ein Server, der startet, eine Woche lang korrekte Antworten liefert und dann ausfällt, sobald eine Abfrage die beschädigte Seite erreicht. Dazwischen gibt es keine Warnung.
Es gibt zwei sichere Möglichkeiten, die Dateien selbst zu übertragen. Stoppen Sie die Datenbank, kopieren Sie die Dateien und starten Sie die Datenbank anschließend wieder: Das ist korrekt und einfach, verursacht aber eine Downtime für die Dauer des Kopiervorgangs. Alternativ verwenden Sie das für eine physische Kopie eines laufenden Servers vorgesehene Tool. Für PostgreSQL ist das pg_basebackup. Es koordiniert sich mit dem Server, sodass die Kopie konsistent ist:
# new server: pull a physical copy from the old one
pg_basebackup -h 198.51.100.10 -U replicator -D /var/lib/postgresql/16/main -X stream -PDafür benötigen Sie eine Rolle mit dem Attribut REPLICATION sowie einen passenden Eintrag pg_hba.conf auf dem alten Server. Der Einrichtungsaufwand ist daher höher als bei einem Dump. Das lohnt sich, wenn die Datenbank so groß ist, dass ein Dump und Restore nicht in Ihr Wartungsfenster passen. Bei einer normalen Migration von einem einzelnen Server ist ein Dump die bessere Wahl.
Zertifikate vor der Umstellung neu erstellen, nicht danach
Ein TLS-Zertifikat ist an den Domainnamen gebunden, nicht an die IP-Adresse. Die Zertifikatsdatei selbst lässt sich daher problemlos übertragen. Die Erneuerung lässt sich jedoch nicht ohne Weiteres übertragen. Die standardmäßige HTTP-01-Challenge von Certbot fordert die Zertifizierungsstelle auf, eine Datei über Port 80 unter dem zu zertifizierenden Namen abzurufen. Solange DNS auf den alten Server zeigt, landet dieser Abruf dort und die Erneuerung auf dem neuen Server schlägt fehl.
Die erste Möglichkeit besteht darin, die vorhandenen Zertifikate und ihren Erneuerungsstatus zu kopieren. Sie bleiben bis zu ihrem Ablaufdatum gültig, unabhängig davon, auf welchem Server sie liegen.
# old server
sudo rsync -aHAX -e 'ssh -i /root/.ssh/id_ed25519' \
/etc/letsencrypt/ root@203.0.113.20:/etc/letsencrypt/Jede Datei unter /etc/letsencrypt/renewal/ enthält den Namen des Authenticator-Plugins, mit dem das Zertifikat ausgestellt wurde. Installieren Sie daher dasselbe Plugin auf dem neuen Server (beispielsweise python3-certbot-nginx). Andernfalls schlägt die erste Erneuerung mit einer Meldung über einen unbekannten Authenticator fehl. Testen Sie, ob die Erneuerung funktioniert, bevor Sie sich darauf verlassen:
# new server, after DNS has moved
sudo certbot renew --dry-runDie zweite Möglichkeit besteht darin, auf dem neuen Server ein neues Zertifikat mit der DNS-01-Challenge auszustellen. Diese weist die Kontrolle über einen TXT-Eintrag nach und verwendet Port 80 nie. Das funktioniert bereits vor der Migration, solange der Name noch auf den alten Server aufgelöst wird. Diese Lösung ist daher die bessere Wahl, wenn Sie Ihren DNS-Provider automatisiert verwalten können. Zertifikate mit der DNS-01-Challenge ausstellen beschreibt die Einrichtung des Plugins und der Zugangsdaten.
Prüfen Sie in beiden Fällen, welches Zertifikat der neue Server tatsächlich ausliefert, ohne DNS zu ändern:
# your laptop
echo | openssl s_client -connect 203.0.113.20:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -subject -dates -issuer-servername sendet SNI (Server Name Indication). Dadurch wählt der Webserver den richtigen virtuellen Host aus. Wenn Sie -servername weglassen, erhalten Sie das Standardzertifikat für diese IP-Adresse und eine Zertifikatsabweichung, die wie ein echtes Problem aussieht, aber keines ist.
TTL mehrere Tage vor dem Umschalten senken
DNS ist eine häufige Fehlerquelle, selbst bei einer sorgfältig geplanten Migration. Die Verzögerung ist fest eingebaut und lässt sich am Tag des Umschaltens nicht verkürzen. Ein Resolver, der Ihren A-Record zwischengespeichert hat, liefert ihn für die Dauer des übergebenen TTL-Werts (Time to Live) weiter aus. Wenn Sie den TTL-Wert jetzt senken, ändert das für einen Resolver nichts, der den Record vor zehn Minuten noch mit dem alten Wert zwischengespeichert hat: Er behält den alten Wert für den verbleibenden Zeitraum des alten TTL-Werts und übernimmt erst danach den neuen, kürzeren Wert. Senken Sie den TTL-Wert daher mindestens eine vollständige alte TTL-Periode vor dem Umschalten. Ein Tag Vorlauf ist die komfortable Variante. Wenn diese Abläufe für Sie neu sind, bietet die Übersicht zu Records, Resolvern und Caching den nötigen Hintergrund.
Die folgenden Zahlen sind aus dem TTL-Wert berechnet und nicht gemessen.
The data behind this chart
[
{
"label": "TTL 3600 s (common default)",
"ttl_seconds": 3600,
"worst_case_stale_minutes": 60
},
{
"label": "TTL 900 s",
"ttl_seconds": 900,
"worst_case_stale_minutes": 15
},
{
"label": "TTL 300 s (lowered for cutover)",
"ttl_seconds": 300,
"worst_case_stale_minutes": 5
},
{
"label": "TTL 60 s (short window)",
"ttl_seconds": 60,
"worst_case_stale_minutes": 1
}
]Ein Record mit einem TTL-Wert von 3600 Sekunden kann Benutzer nach der Änderung noch 60 Minuten lang an die alte IP-Adresse weiterleiten. Senken Sie den Wert auf 300 Sekunden, sinkt dieser ungünstigste Fall auf 5 Minuten. Betrachten Sie diese Zahlen als Mindestwerte und nicht als Zusage. Einige Resolver verwenden einen eigenen Mindestwert für TTL und ignorieren kürzere Angaben. Außerdem cachen manche Anwendungs-Runtimes eine aufgelöste Adresse für die gesamte Lebensdauer des Prozesses. Ein Client, der vor Ihrer Änderung gestartet wurde, führt daher möglicherweise erst nach einem Neustart wieder eine Abfrage durch.
Lesen Sie beim Prüfen des neuen TTL-Werts die autoritative Antwort und nicht den eigenen Cache:
# your laptop: ask the zone's own nameserver, so no cache is involved
dig +short NS example.com
dig +noall +answer @$(dig +short NS example.com | head -n1) example.com ADas zweite Feld dieser Antwortzeile ist der TTL-Wert in Sekunden. Prüfen Sie anschließend auch die Records, die häufig vergessen werden: den AAAA-Record, wenn der alte Server IPv6 hatte, den Namen www, wenn er ein separater A-Record statt eines CNAME ist, jeden MX-Record, der auf den Server selbst zeigt, einen SPF-Record mit der alten IP-Adresse sowie den Reverse-DNS-(PTR-)Record der neuen Adresse. Setzen Sie den PTR-Record vor dem Umschalten über das Control Panel Ihres Providers, wenn der Server E-Mails versendet. Empfangende Mailserver prüfen diesen Record. Ein fehlender PTR-Record führt sonst noch Stunden später zu abgewiesenen E-Mails, obwohl alles andere zunächst korrekt aussieht.
Den neuen Server vor der DNS-Umstellung über seine IP-Adresse prüfen
Sie können die gesamte Anwendung auf dem neuen Server testen, während DNS noch auf den alten Server zeigt. Überschreiben Sie die Namensauflösung für eine einzelne Anfrage:
# your laptop: force one name to the new IP, for this request only
curl -sS --resolve example.com:443:203.0.113.20 \
-o /dev/null -w '%{http_code} %{ssl_verify_result}\n' https://example.com/--resolve ändert nur das Ziel der Verbindung. Das TLS-Zertifikat wird weiterhin gegen den tatsächlichen Namen geprüft. Damit testen Sie sowohl das Zertifikat als auch den Dienst. %{ssl_verify_result} gibt 0 aus, wenn die Zertifikatskette erfolgreich geprüft wurde.
Um die Website im Browser zu testen, überschreiben Sie die Namensauflösung für das gesamte Gerät. Fügen Sie dazu auf Ihrem Laptop eine Zeile zu /etc/hosts hinzu oder unter Windows zu C:\Windows\System32\drivers\etc\hosts:
203.0.113.20 example.com www.example.comDurchlaufen Sie die Anwendung anschließend so, wie es ein Benutzer tun würde. Melden Sie sich an. Laden Sie eine Seite, die Daten aus der Datenbank liest. Senden Sie ein Formular ab, das Daten in die Datenbank schreibt. Laden Sie eine Datei hoch und prüfen Sie, ob sie auf dem Datenträger abgelegt wird. Lösen Sie den Versand einer E-Mail aus und prüfen Sie, ob sie ankommt. Ausgehendes SMTP von einer neuen IP-Adresse führt häufig zu unerwarteten Problemen. Entfernen Sie die hosts-Zeile, sobald Sie fertig sind. Wenn sie bestehen bleibt, verbringen Sie möglicherweise eine Stunde mit der Fehlersuche an einer Website, die für alle anderen problemlos erreichbar ist.
Die Umschaltung Schritt für Schritt
- Einige Tage vorher: Senken Sie die TTL, führen Sie den vollständigen rsync-Lauf aus, richten Sie den neuen Server ein und testen Sie ihn hinter einer hosts-Überschreibung.
- Am Tag der Umschaltung, vor dem Wartungsfenster: Fügen Sie die neue IP-Adresse jeder Allowlist von Drittanbietern hinzu. Stellen Sie außerdem sicher, dass der Backup-Job des neuen Servers konfiguriert ist und auf Ihr Repository verweist.
- Öffnen Sie das Wartungsfenster: Versetzen Sie die Anwendung auf dem alten Server in den Wartungsmodus, damit sie keine Schreibvorgänge mehr annimmt.
- Erstellen Sie den finalen Datenbank-Dump. Führen Sie anschließend den letzten rsync-Lauf mit
--deleteaus. - Stellen Sie den Dump auf dem neuen Server wieder her. Starten Sie anschließend die Dienste.
- Testen Sie erneut über
--resolveund die hosts-Überschreibung. Führen Sie dabei auch einen echten Schreibvorgang aus. - Ändern Sie die A- und AAAA-Records auf die neue IP-Adresse.
- Überwachen Sie beide Server. Das Access-Log des alten Servers zeigt, wer noch dort ankommt. Diese Zahl sollte innerhalb der TTL gegen null sinken.
- Deaktivieren Sie die Wartungsseite.
- Lassen Sie den alten Server mindestens eine Woche weiterlaufen. Nehmen Sie in dieser Zeit keine Änderungen daran vor.
Den Schritt mit dem Wartungsmodus überspringen viele. Er schützt Sie jedoch vor Problemen. Sobald die neue Datenbank einen Schreibvorgang angenommen hat, bedeutet ein Rollback entweder den Verlust dieses Schreibvorgangs oder das Dumpen der neuen Datenbank und das Zurückladen in die alte Datenbank. Ein schreibgeschütztes Fenster von wenigen Minuten ist unproblematisch. Zwei Datenbanken, in die gleichzeitig Schreibvorgänge erfolgt sind, erfordern dagegen eine tagelange manuelle Zusammenführung.
Der Rollback-Plan
Ein Rollback besteht aus einer Aktion: Ändern Sie die DNS-Einträge zurück auf 198.51.100.10. Das funktioniert nur aufgrund von vier Maßnahmen, die Sie zuvor durchgeführt haben.
- Der alte Server läuft weiterhin. Seine Dienste sind aktiv und seine Daten sind intakt. Sie haben dort Schreibvorgänge gestoppt, den Server aber nicht außer Betrieb genommen.
- Die TTL ist weiterhin niedrig. Dadurch ist der Rückweg genauso schnell wie der Hinweg.
- Sie haben die neue IP-Adresse zu den Allowlists von Drittanbietern hinzugefügt, statt die alte zu ersetzen. Wenn Sie die alte Adresse entfernen, schlägt der Rollback am Payment-Gateway fehl.
- Auf dem neuen Server wurden keine Schreibvorgänge durchgeführt, die Sie nicht zuordnen können. Bisher stammen die einzigen Schreibvorgänge von Ihren eigenen Testtransaktionen.
Legen Sie vor Beginn des Wartungsfensters fest, wann ein Rollback ausgelöst wird. Zwei Auslöser reichen aus: ein Fehler, den Sie innerhalb einer festgelegten Anzahl von Minuten nicht diagnostizieren können, und jeder Datenverlust. Wenn Sie diese Kriterien im Voraus dokumentieren, verhindern Sie eine Stunde voller Vermutungen, durch die aus einem zehnminütigen Ausfall ein langer Ausfall wird.
Migration erfolgreich nachweisen
Eine Migration ist nicht abgeschlossen, wenn die Website geladen wird. Prüfen Sie die Punkte, die erst später ausfallen.
# new server
systemctl --failed
journalctl -p err -b --no-pager | tail -n 40
sudo certbot certificates
sudo systemctl list-timers --all --no-pagersystemctl --failed reporting 0 loaded units listed ist das gewünschte Ergebnis. certbot certificates sollte die erwarteten Ablaufdaten anzeigen, und list-timers sollte jeden geplanten Job aus Ihrem Inventar mit einer tatsächlichen nächsten Ausführungszeit anzeigen, nicht mit einem leeren Wert.
Starten Sie den neuen Server anschließend einmal absichtlich neu, während Sie den Vorgang beobachten. Ein Dienst, den jemand von Hand gestartet und nie aktiviert hat, funktioniert bis zum ersten ungeplanten Reboot um drei Uhr morgens einwandfrei.
# new server
sudo reboot
# your laptop, once it comes back
curl -sS -o /dev/null -w '%{http_code}\n' https://example.com/Wenn die Anwendung in Containern läuft, hat diese Falle eine andere Ausprägung, denn ein Compose-Stack benötigt eine explizite Restart-Policy, damit er nach einem Reboot wieder startet.
Die letzte Prüfung wird am leichtesten aufgeschoben und ist zugleich die wichtigste: der Backup-Job. Eine Migration, die mit einem Server ohne Backup endet, tauscht ein Risiko gegen ein anderes. Führen Sie das Backup auf dem neuen Server von Hand aus. Stellen Sie anschließend eine einzelne Datei daraus in ein temporäres Verzeichnis wieder her. Ein Restic-Repository mit einer tatsächlich getesteten Wiederherstellung ist die Variante, die im Bedarfsfall hilft. Wenn Sie den alten und den neuen Server eine Woche lang parallel betreiben, verhindert eine konsistente Methode für den Zugriff auf und die Konfiguration jedes Hosts, dass die beiden Systeme auseinanderlaufen, während beide aktiv sind.
Nach dem Umzug: der alte Server und die letzten Aufgaben
Behalten Sie den alten Server ein bis zwei Wochen. Er kostet einen weiteren Monatsbetrag für einen Tarif, den Sie ohnehin kündigen wollten, und ist Ihre einzige Möglichkeit für ein Rollback. Erledigen Sie anschließend die übrigen Aufgaben.
- Wenn Sie denselben Hostnamen in Ihrem
~/.ssh/configfür den neuen Server wiederverwenden, erhalten Sie bei der ersten VerbindungWARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!, weil dieser Name jetzt mit einem anderen Host-Key antwortet. Löschen Sie den veralteten Eintrag mitssh-keygen -R example.com, sobald Sie sicher wissen, warum er sich geändert hat. Löschen Sie ihn nicht reflexartig, denn dieselbe Warnung weist auch auf einen Abfangangriff hin. Eine Migration ist außerdem ein guter Zeitpunkt, um zu prüfen, welche Schlüssel auf welche Systeme zugreifen können. Genau dafür ist SSH-Schlüsselverwaltung in einer kleinen Serverflotte gedacht. - Erstellen Sie einen letzten Snapshot oder ein letztes Backup des alten Servers und speichern Sie es an einem Ort, der nicht beim alten Provider liegt.
- Entfernen Sie die alte IP-Adresse aus den Monitoring-Prüfungen, den SPF-Einträgen und den Allowlists von Drittanbietern. Halten Sie dabei diese Reihenfolge ein und erledigen Sie dies als letzten Schritt.
- Kündigen Sie den alten Tarif erst, nachdem bestätigt wurde, dass diese letzte Kopie an einem anderen Ort lesbar ist.
FAQ
Wie lange dauert die Migration eines Servers auf einen neuen VPS?
Die für Benutzer sichtbare Ausfallzeit umfasst normalerweise den letzten Datenbank-Dump, den letzten rsync-Durchlauf und den Dienststart. Bei einer kleinen Anwendung dauert das zehn bis dreißig Minuten. Die Migration insgesamt benötigt mehr Zeit, weil die DNS-TTL mindestens eine alte TTL-Zeiteinheit vor dem Wechsel gesenkt werden muss. Ein Vorlauf von einem Tag ist sicherer. Planen Sie auch das Kopieren der umfangreichen Daten mehrere Tage im Voraus. Es läuft gegen einen aktiven Server. Bei einer späteren Wiederholung werden nur die Änderungen seit dem letzten Durchlauf übertragen.
Kann ich eine laufende MySQL- oder PostgreSQL-Datenbank mit rsync kopieren, statt einen Dump zu erstellen?
Nein. rsync kopiert Datei für Datei, während die Datenbank gleichzeitig in mehrere Dateien schreibt. Die Kopie enthält dadurch Seiten aus unterschiedlichen Zeitpunkten und stellt einen Zustand dar, den die Datenbank nie hatte. Der Dienst verweigert möglicherweise den Start oder startet und schlägt später fehl, sobald eine Abfrage eine beschädigte Seite erreicht. Verwenden Sie pg_dump mit pg_dumpall --globals-only oder mysqldump --single-transaction. Alternativ stoppen Sie zuerst die Datenbank und kopieren anschließend die Dateien. Bei einem großen PostgreSQL-Cluster erstellt pg_basebackup eine konsistente physische Kopie eines laufenden Servers.
Wie teste ich den neuen VPS, bevor ich den DNS-Eintrag ändere?
Überschreiben Sie die Namensauflösung auf Ihrem eigenen Rechner. Für eine einzelne Anfrage leitet curl --resolve example.com:443:203.0.113.20 https://example.com/ die Verbindung an die neue IP-Adresse weiter und prüft das Zertifikat weiterhin gegen den echten Namen. Für einen Browser-Test fügen Sie 203.0.113.20 example.com auf Ihrem Laptop zu /etc/hosts hinzu. Testen Sie einen Login, das Lesen aus der Datenbank, das Speichern eines Formulars und den Upload einer Datei. Entfernen Sie anschließend die Zeile. Um nur das Zertifikat zu prüfen, führen Sie openssl s_client -connect 203.0.113.20:443 -servername example.com aus.
Welche TTL sollte ich setzen, und wann sollte ich sie senken?
Senken Sie die A- und AAAA-Einträge auf 300 Sekunden. Tun Sie dies mindestens eine vollständige alte TTL-Zeiteinheit vor dem Wechsel. Ein Resolver, der den Eintrag vor Ihrer Änderung zwischengespeichert hat, verwendet den alten Wert für den Rest der alten TTL. Wenn die alte TTL 86400 betrug, bringt eine Senkung eine Stunde vorher daher nichts. Setzen Sie die TTL einige Tage nach der Migration wieder auf den normalen Wert, sobald das Zugriffsprotokoll des alten Servers keine Einträge mehr enthält.
Sollte ich das TLS-Zertifikat kopieren oder auf dem neuen Server ein neues ausstellen?
Beides ist möglich. Durch das Kopieren von /etc/letsencrypt/ bleibt das Zertifikat bis zu seinem bestehenden Ablaufdatum gültig. Sie müssen jedoch dasselbe certbot-Authentifizierungs-Plugin auf dem neuen Server installieren. Andernfalls schlägt die erste Erneuerung fehl. Führen Sie daher nach der DNS-Umstellung certbot renew --dry-run aus, um dies zu bestätigen. Ein neues Zertifikat ist sauberer, wenn Sie die DNS-01-Challenge verwenden können. Sie weist die Kontrolle über einen TXT-Eintrag nach und funktioniert, bevor DNS auf den neuen Server zeigt. Die HTTP-01-Challenge kann auf dem neuen Server erst verwendet werden, nachdem DNS umgestellt wurde, weil die Validierungsanfrage andernfalls den alten Server erreichen würde.