Snapshots von Servern anfertigen (dd über ssh)

Snapshots von Servern anfertigen (dd über ssh)

Ein Snapshot ist ein Abbild einer Festplatte oder eines Systems, das zu einem gewissen Zeitpunkt erstellt wurde. Snapshots können je nach Umgebung "online" (also im laufenden Betrieb) oder "offline" angefertigt werden. Offline-Snapshots sind prinzipiell zu bevorzugen, da sie einen konsistenten Datenbestand sicherstellen. Snapshots werden häufig als Backups genutzt, wenngleich es dabei sehr wichtig ist, dass der Snapshot auf anderer Hardware oder besser noch an einem anderen Ort als das Ursprungs-System aufbewahrt wird.

Nicht bei jedem Server-Anbieter gibt es die Möglichkeit Snapshots anfertigen zu lassen. Bei physischer Hardware sind Snapshots getrennt von der eigentlichen Hardware rein strukturell kaum möglich. Viele VPS- bzw. Cloud-Anbieter bieten passende Oberflächen zum Erstellen und teilweise auch Exportieren von Snapshots an. So lassen sich bei zum Beispiel bei netcup mit wenig Aufwand Snapshots erstellen, exportieren, importieren und wieder einspielen. In der Hetzner Cloud ist das Erstellen und Einspielen von Snapshots möglich, nicht aber das ex- oder importieren. Wer einen Snapshot offsite lagern oder sogar dauerhaft archivieren möchte kommt um diese Export- bzw. Importfunktion nicht herum.

Snapshots lassen sich in der Hetzner Cloud sehr leicht anlegen, leider aber nicht exportieren.
Snapshots lassen sich in der Hetzner Cloud sehr leicht anlegen, leider aber nicht exportieren.

Snapshot mit dd über ssh

Falls die Exportfunktion oder gar Snapshots generell nicht möglich sind, gibt es eine einfache Variante zum Erstellen von Snapshots: angenommen wir möchten einen Snapshot von Server A auf Server B speichern. Server A ist ein virtueller Server mit einer Festplatte (/dev/sda). Zum Anfertigen des Snapshots loggen wir uns per SSH auf Server B ein. Dann starten wir auf Server A ein Rescue-System mit SSH-Server. Das kann ein Rescue-System des Serveranbieters sein oder auch eine Live-Distribution. Häufig ist ersteres mit wenigen Klicks erledigt.

Hetzner Cloud-Server im Rescue-System gebootet.
Hetzner Cloud-Server im Rescue-System gebootet.

Anschließend führen wir auf Server B folgenden Befehl aus:

$ ssh USER@IP "dd bs=4M if=QUELL-FESTPLATTE | zstd -" | dd bs=4M of=ZIELDATEI.zst

Folgende Werte müssen angepasst werden:
- USER : SSH-Nutzer, üblicherweise root
- IP : IP-Adresse von Server A
- QUELL-FESTPLATTE : zu sichernder Datenträger von Server A (meist /dev/sda)
- ZIELDATEI : Zieldatei auf Server B, z.B. image.img.zst

In unserem Beispiel würde der Befehl mit Beispielwerten so aussehen:

$ ssh root@192.168.178.10 "dd bs=4M if=/dev/sda | zstd -" | dd bs=4M of=image.img.zst

Diese Zeile bewirkt dabei folgendes: Server B loggt sich per SSH auf Server A (192.168.178.10) ein und führt dort den Befehl dd bs=4M if=/dev/sda | zs- aus. Durch diesen Befehl wird der Datenträger /dev/sda ausgelesen, mit zstd komprimiert und über SSH an den Zielserver (Server B) übertragen. Auf dem Server B wird der eingehende Datenstrom dann mit dd bs=4M of=image.img.zst in die Datei image.img.zst gespeichert.

Snapshot-Erstellung mit dd über ssh. Im Screenshot wird noch gzip verwendet. Die aktuelle Empfehlung wäre zstd.
Snapshot-Erstellung mit dd über ssh. Im Screenshot wird noch gzip verwendet. Die aktuelle Empfehlung wäre zstd.

Nicht wundern: der Prozess dauert eine Weile und es gibt keine Fortschrittsanzeige. Der Abschluss der Übertragung wird mit einer kurzen Auflistung der kopierten Datenmengen bestätigt.

Auf dem Quellsystem wurden die vollen 20 GB des Datenträgers gelesen, durch die Kompression (kombiniert mit viel freiem Speicher) wurden letztlich aber nur ~ 600 MB übertragen.
Auf dem Quellsystem wurden die vollen 20 GB des Datenträgers gelesen, durch die Kompression (kombiniert mit viel freiem Speicher) wurden letztlich aber nur ~ 600 MB übertragen.

Da dd direkt auf Blockebene arbeitet, kann ein Snapshot völlig unabhängig vom Datei- oder Betriebssystem auf Server A angelegt werden. Dies bedeutet allerdings auch, dass bei einem Datenträger mit 120 GB Größe entsprechend 120 GB ausgelesen und übertragen werden müssen. Deshalb komprimieren wir mit zstd die Daten vor der Übertragung, was insbesondere bei freiem Speicher sehr effektiv ist!  Hier wird die Standardkompression genutzt, die ein gutes Verhältnis zwischen Kompressionsgrad und Ressourcenverbrauch bietet. Bei der Wahl einer stärkeren Kompression sollte auf genügend CPU-Ressourcen geachtet werden, da dies den Prozess sonst wieder stark ausbremsen kann!

Falls der Server mehr als einen Datenträger hat, muss der Befehl entsprechend angepasst für jeden Datenträger ausgeführt werden.

Servermigration mit dd über ssh

Das Vorgehen kann übrigens nicht nur genutzt werden, um Snapshots in Dateiform anzulegen, sondern auch um komplette Server zu migrieren. Hierbei muss darauf geachtet werden, dass der Datenträger auf Server B mindestens so groß ist wie der Datenträger von Server A. Die Partition und das Dateisystem lassen sich nachträglich dann leicht mit Gparted vergrößern. Weitere Details finden sich im Blogartikel "Servermigration mit dd über SSH".

Update 24.04.2024

Aus aktueller Sicht ist die Nutzung von zstd statt gzip empfehlenswert. Die Commands und Texte wurden dahingehend angepasst.