Kann ein Raspberry Pi verwendet werden, um ein Backup von sich selbst zu erstellen?


78

Diese Frage beantwortet die Frage, wie ich einen externen Computer verwende, um ein Backup meines RPi zu erstellen.

Ich frage mich, ob ich ein Backup-Image der derzeit verwendeten SD-Karte erstellen und in eine Datei auf einem USB-Speichergerät kopieren kann. Ist das möglich? Wenn nicht, gibt es eine Möglichkeit, ein Backup eines RPi zu erstellen, ohne einen anderen Computer einzubeziehen?


2
Sicher, aber überspringen Sie / tmp, / run, / proc, / sys, / dev und / mnt. Sie müssen kein Image erstellen. Sie benötigen ein Backup, von dem Sie ein Image erstellen oder aktualisieren können. Also nicht benutzen dd, reinschauen rsync.
Goldlöckchen

1
@goldilocks Ich würde es lieben, wenn Sie diesen Kommentar zu einer vollständigeren Antwort zusammenfassen und den Sicherungs- und Wiederherstellungsprozess erläutern würden, den Sie beabsichtigen.
Eric Wilson

Fertig - Entschuldigung, ich habe ein paar Tage gebraucht, um die Zeit zu finden.
Goldlöckchen

1
Wenn Ihr Zieldatenträger groß genug ist, ist ddes wahrscheinlich am schnellsten , das Dateisystem schreibgeschützt erneut bereitzustellen und eine Kopie mit einer geeigneten Blockgröße zu erstellen, um eine "neue" Kopie zu erstellen. Es ist wahrscheinlich eine schlechte Idee, eine Datei für Datei auf Flash- / SD-Medien zu kopieren.
Chris Stratton

Antworten:


86

Hier ist eine Einführung in die Verwendung rsyncfür die Sicherung auf dem Pi. Sobald das erste Backup erstellt wurde, ist es viel schneller, es auf dem neuesten Stand zu halten, als das gesamte Image ständig zu rippen. Sie können dies auf einer lokalen Festplatte oder über ein Netzwerk tun.

Sie möchten eigentlich keine vollständige Kopie eines laufenden Systems als Backup, da einige der angeblich im Dateisystem vorhandenen Daten nur zur Laufzeit vorhanden sind. Wenn Sie dies in ein Backup aufnehmen und später ein Image daraus erstellen, kann dies zu Problemen für Sie führen.

Es gibt auch einige andere Ausnahmen. rsynckann eine Liste von ( Glob- ) Mustern akzeptieren , die ausgeschlossen werden sollen, und diese können aus einer Datei gelesen werden. Gehen wir also zunächst durch, was in einer solchen Datei enthalten sein soll. Beachten Sie, dass die Einträge von der Form sind /directory/*und nicht /directory. Das liegt daran, dass wir wollen, dass sie existieren, aber wir wollen nichts in sie kopieren.

/proc/*
/sys/*

Diese existieren nicht wirklich auf der Festplatte. Sie sind eine Schnittstelle zum Kernel, der sie im Speicher erstellt und verwaltet . Wenn Sie diese kopieren und dann wieder in ein System kopieren und es booten, ist dies (bestenfalls) bedeutungslos, da der Kernel diese als Mount-Punkte für die Schnittstellen verwendet Versuchen Sie es in einem Verzeichnis mit Daten. Es funktioniert und richtet keinen Schaden an, aber auf das Material, das sich im Verzeichnis befand, kann jetzt nicht mehr zugegriffen werden.]

Beachten Sie, dass der /sysund der /procEinhängepunkt unbedingt vorhanden sein müssen. Sie sollten aber nichts enthalten. Nächster:

/dev/*

Das devVerzeichnis ist nicht ganz dasselbe wie procund sysdoch für unsere Zwecke. Wenn Sie der Meinung sind, dass Sie dies speichern sollten, damit Sie dieselben Geräteknoten in Ihrem Backup haben können, liegen Sie falsch . Mach dir keine Sorgen. Nicht kopieren dev. Vor langer Zeit hat Linux so funktioniert, aber es funktioniert nicht mehr.

/boot/*

Dies ist eine Art Sonderfall bei den meisten (vielleicht allen) Pi-spezifischen Distributionen wie Raspbian. Es ist eigentlich ein Einhängepunkt für die erste vfat-Partition. Wir werden das separat behandeln. Was auch immer Sie tun, kümmern Sie sich nicht darum, es hier einzubeziehen, denn es ist wieder ein Mount Point.

/tmp/*
/run/*

/runbefindet sich im Allgemeinen auch nicht auf der Festplatte, sondern im Speicher. Vielleicht /tmpkönnte es auch so sein (dies würde ein bisschen SD-Karten-Action sparen), aber auf jeden Fall sind dies, wie die Namen andeuten, keine Orte zum Speichern persistenter Daten. Anwendungen, die sie verwenden, erwarten, dass sie bei jedem Start gelöscht werden.

/mnt/*
/media/*

Dies ist insbesondere dann wichtig, wenn Sie eine Sicherung auf einer Festplatte oder einem USB-Stick planen und das Gerät sich in /mntoder befindet /media(bei der automatischen Bereitstellung wird normalerweise das letztere verwendet), da Sie den Speicherort dieser Geräte im Dateisystem nicht ausschließen Erstellen Sie eine Schleife, die den Inhalt des Laufwerks in sich selbst sichert, bis der Speicherplatz erschöpft ist. Ich denke, es rsync könnte klug genug sein, etwas so Dummes zu entdecken, aber ich versuche zu vermeiden, die Prämisse zu testen.

Zur eigentlichen Sicherung: Erstellen Sie ein Verzeichnis, in das Sie auf der lokal gemounteten Festplatte, einem USB-Gerät usw. Sicherungskopien erstellen möchten - z. B. "pi_backup". Sie können alternativ über ssh(siehe unten) oder über ein im Netzwerk eingehängtes Dateisystem an einen Remotestandort sichern. Dies wird jedoch wahrscheinlich beim ersten Mal eine Weile dauern.

Wenn die Datei, die die auszuschließende Liste enthält, /rsync-exclude.txt1 ist und sich auf Ihrem Laufwerk befindet /mnt/usbhd, führen Sie die eigentliche Sicherung durch:

rsync -aHv --delete --exclude-from=/rsync-exclude.txt / /mnt/usbhd/pi_backup/

Beachten Sie, dass ein abschließender Schrägstrich angezeigt wirdpi_backup/ .

Dies wird eine Weile dauern und eine Menge Ausgabe produzieren (wenn Sie dies stattdessen in einem Protokoll untersuchen möchten, fügen Sie es an > rsync.log). --deleteist beim ersten Mal bedeutungslos, aber um das Backup auf dem neuesten Stand zu halten, verwenden Sie es. Auf diese Weise wird sichergestellt, dass Inhalte, die Sie später auf dem Pi gelöscht haben, auch aus Ihrer Sicherung entfernt werden. Das asetzt die Rekursion in Verzeichnisse und stellt sicher, dass alle Dateiattribute übereinstimmen. -Hist, um harte Links 2 zu erhalten , vist für ausführliche, weshalb Sie eine Ausgabe erhalten (sonst rsyncist ruhig). Sehen Sie man rsyncfür mehr.

Es gibt eine Verknüpfung, mit der Sie die --exclude-fromDatei überspringen können . Wenn Sie sicher sind, dass sich alle Dinge, die Sie nicht kopieren möchten ( /tmpusw.), auf separaten Dateisystemen befinden, können Sie einfach Folgendes verwenden:

rsync -axHv --delete-during / /mnt/usbhd/pi_backup/

-xwurde eingefügt. Dies ist die Kurzform von --one-file-system, die angibt, rsynckeine Dateisystemgrenzen zu überschreiten. Persönlich bevorzuge ich die --exclude-from, aber auf zB Standard Raspbian, --one-file-systemwird gut funktionieren. Sie können beide verwenden, wenn Sie -xvorsichtig sein möchten : D

Das ist kein vollständiges Backup. Es reicht aus, wenn Sie nichts eingegeben haben und das Backup in bootOrdnung ist, um das System wiederherzustellen, indem Sie die Karte in einen Computer stecken und ausführen:

rsync -av --delete-during /mnt/usbhd/pi_backup/ /mnt/sdcard_partition2/

Sie können dies auch mit einer Karte tun, auf der sich ein neues Bild befindet (vorausgesetzt, es ist dasselbe wie Ihr Basisbild), obwohl dies ein wenig ineffizient ist, wenn Sie das Bild erstellen müssen (da Sie dann das meiste davon überschreiben). Sie können auch eine andere SD-Karte über einen USB-Adapter mit einem solchen Image anschließen und die oben beschriebene Methode verwenden, um eine doppelte Karte zu erhalten.

Wenn Sie Daten /boot(z. B. einen benutzerdefinierten Kernel) /boot/config.txthinzugefügt haben, möchten Sie diese ebenfalls sichern (ziemlich einfach - da steckt nicht viel dahinter). Tun Sie es einfach separat und wenn Sie wiederherstellen, wird das Zeug in der ersten Partition gespeichert.

Sehen Sie hier, ob Sie ein leeres Bild im Raspbian-Stil erstellen möchten, in das Sie dann ein Backup erstellen können . Sie können eine ähnliche Methode verwenden, um eine leere Karte im Raspbian-Stil zu erstellen. Statt mit einer .imgDatei zu arbeiten, haben Sie es beispielsweise mit einem realen Gerät /dev/sdbzu tun. Sie müssen also nur die Partitionstabelle mit fdiskund dann erstellen Format /dev/sdb1und sdb2(oder was auch immer) mit mkfs.

Das Kopieren des gesamten Bildes ist jedoch einfacher! Warum sich damit beschäftigen?

Es ist nicht so schwer; Ich habe in 10 Minuten eine leere Karte wiederhergestellt (formatiert nach dem letzten Link). Ja, es ddist einfacher , nur das Ganze zu verwenden (wenn Sie Dinge wie verwirrende Wörter finden ...), ABER es dauert jedes Mal eine Weile, wenn Sie Ihr Backup aktualisieren möchten, da Sie jedes Mal 100% davon ausführen müssen. Unter Verwendung rsync, sobald eine Sicherung vorhanden ist , ist es die Aktualisierung viel viel schneller, so dass Sie dies einrichten können schmerzfrei jeden Tag über cron passieren. Auch über ein Netzwerk. Alle sechs Stunden. Je öfter Sie es tun, desto weniger Zeit wird es dauern.

rsync über ssh

Hier ist ein Beispiel:

rsync [options] --rsh="ssh [ssh options]" root@[the pi ip]:/ /backup/rpi/

"Optionen" wäre z. B. -av --delete --exclude-from=/rsync-exclude.txtund "ssh-Optionen" ist das, was Sie normalerweise verwenden (wenn überhaupt). Sie müssen Root - Zugriff haben über sshdiese für die Zwecke einer Systemsicherung zu tun (festgelegt PermitRootLogin=yesin /etc/ssh/sshd_configund starten Sie den Server).


1 Sie sollten diese Datei behalten. Sie können Kommentare in Zeilen einfügen, die mit #oder beginnen ;. Dies kann den eigentlichen rsyncBefehl enthalten, der später kopiert werden kann, damit Sie sich nicht jedes Mal daran erinnern müssen.

2 Danke an Kris für den Hinweis, das rsyncgeht nicht automatisch.


Goldlöckchen. Das sieht nach einer großartigen Verwendung von Rysync aus. Gibt es eine Chance, es für uns in ein Drehbuch zu rollen?
totalitäre

Anstatt alle Mountpunkte manuell auszuschließen, warum nicht mkdir /tmp/backupable && mount --bind / /tmp/backupableund rsync das? Dies hat auch den Vorteil, dass alle Daten gesichert werden, die an Orten gespeichert sind, die von etwas "beschattet" werden, das dort angebracht ist.
18.

@ n.st Gute Idee (lol)! Ich habe den Vorschlag in die Frage geändert, obwohl ich immer noch denke, dass die Verwendung --exclude-fromeine bessere Idee ist. Wenn Sie Zeit haben, können Sie dies als separate Antwort aufschreiben, Sie haben meine Stimme und ich kann darauf verweisen. Diese Antwort ist langatmig genug.
Goldlöckchen

1
@IgorGanapolsky Es wird beabsichtigt, kein Bild zu erstellen (lesen Sie den Teil "Aber das Kopieren des gesamten Bildes ist einfacher! Warum sollte man sich darum kümmern ?" ). Diese Methode ist nicht nur einfacher und schneller zu warten, sondern auch flexibler. Wenn Sie es später verwenden möchten, um eine zu erstellen .img, können Sie; dies und das soll helfen zu erklären, wie sie strukturiert sind und erstellt werden können.
Goldlöckchen

1
Lesen Sie den Abschnitt "Das ist keine vollständige Sicherung ..." . Im Grunde ist es genau dasselbe in umgekehrter Richtung. Dies kann bei einigen Konzepten hilfreich sein, bei denen Menschen häufig verwirrt sind.
Goldlöckchen

24

Ein funktionierendes Skript aus der Raspberry Community, das von einem Mitglied dort erstellt wurde.

Sie können den Code beliebig oft wiederverwenden und optimieren. Er ist gut dokumentiert und selbsterklärend.

#!/bin/bash

# Setting up directories
SUBDIR=raspberrypi_backups
DIR=/hdd/$SUBDIR

echo "Starting RaspberryPI backup process!"

# First check if pv package is installed, if not, install it first
PACKAGESTATUS=`dpkg -s pv | grep Status`;

if [[ $PACKAGESTATUS == S* ]]
   then
      echo "Package 'pv' is installed."
   else
      echo "Package 'pv' is NOT installed."
      echo "Installing package 'pv'. Please wait..."
      apt-get -y install pv
fi

# Check if backup directory exists
if [ ! -d "$DIR" ];
   then
      echo "Backup directory $DIR doesn't exist, creating it now!"
      mkdir $DIR
fi

# Create a filename with datestamp for our current backup (without .img suffix)
OFILE="$DIR/backup_$(date +%Y%m%d_%H%M%S)"

# Create final filename, with suffix
OFILEFINAL=$OFILE.img

# First sync disks
sync; sync

# Shut down some services before starting backup process
echo "Stopping some services before backup."
service apache2 stop
service mysql stop
service cron stop

# Begin the backup process, should take about 1 hour from 8Gb SD card to HDD
echo "Backing up SD card to USB HDD."
echo "This will take some time depending on your SD card size and read performance. Please wait..."
SDSIZE=`blockdev --getsize64 /dev/mmcblk0`;
pv -tpreb /dev/mmcblk0 -s $SDSIZE | dd of=$OFILE bs=1M conv=sync,noerror iflag=fullblock

# Wait for DD to finish and catch result
RESULT=$?

# Start services again that where shutdown before backup process
echo "Start the stopped services again."
service apache2 start
service mysql start
service cron start

# If command has completed successfully, delete previous backups and exit
if [ $RESULT = 0 ];
   then
      echo "Successful backup, previous backup files will be deleted."
      rm -f $DIR/backup_*.tar.gz
      mv $OFILE $OFILEFINAL
      echo "Backup is being tarred. Please wait..."
      tar zcf $OFILEFINAL.tar.gz $OFILEFINAL
      rm -rf $OFILEFINAL
      echo "RaspberryPI backup process completed! FILE: $OFILEFINAL.tar.gz"
      exit 0
# Else remove attempted backup file
   else
      echo "Backup failed! Previous backup files untouched."
      echo "Please check there is sufficient space on the HDD."
      rm -f $OFILE
      echo "RaspberryPI backup process failed!"
      exit 1
fi

Erwägen Sie, dem ursprünglichen Forum Kommentare hinzuzufügen oder eine eigene Version zu veröffentlichen, um den Inhalt zu verbessern. Nimm ein bisschen, gib ein bisschen.

* Und vielen Dank für die Rückgabe von AndersW (Click for GIT-Skript)


2
Was passiert, wenn sich das Dateisystem (Löschen von Dateien, Hinzufügen neuer Dateien) während des Backups ändert?
Keiki

2
Ich habe mehrere Datenträger gesichert, während sie mit rsync ausgeführt werden, und ich konnte aus diesen Dateisicherungen häufig genau das abrufen, was ich benötige. Im Allgemeinen kann ein Unix-Dateisystem jedoch nicht perfekt kopiert werden (mit jedem vorhandenen und korrekten Bit), während das Dateisystem angehängt ist (*). Eine Kopie, die beim Mounten des Systems erstellt wurde, wird manchmal als "Dirty Copy" bezeichnet. Es können verschiedene Maßnahmen ergriffen werden, um die Qualität einer fehlerhaften Kopie zu verbessern (wie im obigen Skript zum Ausschalten von cron und mysql), aber es kann nicht perfekt sein. Prost! * - Ich irre mich, es hängt vom Dateisystem ab.
Tai Viinikka

1
Sie können sich die von Debian empfohlenen Backup-Dienstprogramme ansehen und sehen, ob Pi einen Port von ihnen hat. rsnapshotklingt vielversprechend
Piotr Kula

1
@TaiViinikka Du brauchst keine perfekte Kopie. Sie benötigen einen Teilkopie , die (schnell und einfach) sein kann , auf dem ursprünglichen Basisbild wieder eingeführt. ist der Weg zu gehen; Wenn ich morgen Zeit habe, werde ich eine Antwort hinzufügen. ist auch eine Untersuchung wert. rsyncrsnapshot
Goldlöckchen

3
Basierend auf der obigen Antwort von ppumkins habe ich das 'dd'-Skript mit den neuesten Kommentaren im Original-Thread synchronisiert und selbst einige kleinere Verbesserungen hinzugefügt. Das Endergebnis finden Sie hier: < github.com/aweijnitz/pi_backup >. Bitte zögern Sie nicht, Verbesserungen hinzuzufügen und mir Pull-Anfragen zu senden.
AndersW

14

Ich habe die Antwort von @goldilocks auf rsync für die Sicherung auf dem pi angepasst. Ich sichere auf einer ext4Partition auf einer Festplatte, die auf dem Pi montiert ist. Wenn die Festplatte nicht gemountet ist, kopiert rsync in das Mount-Verzeichnis (bis die SD-Karte voll ist). Ist die Festplatte nicht im rwModus gemountet, werden zahlreiche Fehlermeldungen ausgegeben. Beides ist nicht wünschenswert, daher überprüfe ich, ob meine Partition im rwModus gemountet ist, bevor ich fortfahre .

HINWEIS 03.03.2015 Ich habe meine Antwort so geändert, dass Hardlinks korrekt kopiert werden. Das Original funktionierte, konvertierte aber viele Hardlinks in Dateien. Dies verschwendet nicht nur Speicherplatz, sondern beeinträchtigt auch viele Verwendungen, bei denen davon ausgegangen wird, dass die Hardlinks vorhanden sind. (Mein aktuelles Bild hat 869 Links, viele davon in Raspbian selbst.)

Mein Skript dazu folgt. (Meine Partition ist PiDatagemountet auf/mnt/PiData

#!/bin/bash
# script to synchronise Pi files to backup
BACKUP_MOUNTED=$(mount | awk '/PiData/ {print $6}' | grep "rw")
if [ $BACKUP_MOUNTED ]; then
    echo $BACKUP_MOUNTED
    echo "Commencing Backup"
    rsync -avH --delete-during --delete-excluded --exclude-from=/usr/bin/rsync-exclude.txt / /mnt/PiData/PiBackup/
else
    echo "Backup drive not available or not writable"
fi

Wiederherstellen (oder Aktualisieren eines anderen Pi) mit den folgenden Schritten:

sudo rsync -avH /mnt/PiData/PiBackup/ /

Ich habe das verbessert rsync-exclude.txt, um unnötige Dateien zu beseitigen.

Die erste Gruppe sind die von @goldilocks https://raspberrypi.stackexchange.com/users/5538/ dokumentierten Verzeichnisse.

Die zweite Gruppe sind die Dateien und Verzeichnisse, die von OS X erstellt werden, wenn ich mit AFP (Apple Filing Protocol) auf meinen Pi zugreife. (Diese sind unter OS X normalerweise unsichtbar, unter Raspbian jedoch nicht. Auf jeden Fall ist kein Backup erforderlich.) Auch wenn Sie AFP niemals verwenden, richten diese keinen Schaden an.

Die dritte Gruppe sind Dateien, die nicht gesichert werden müssen (und auf keinen Fall auf einen anderen Pi kopiert werden dürfen). Beispiele fake-hwclock.data, RPi-Monitor-Berichte. Sie werden wahrscheinlich andere haben.

/proc/*
/sys/*
/dev/*
/boot/*
/tmp/*
/run/*
/mnt/*

.Trashes
._.Trashes
.fseventsd
.Spotlight-V100
.DS_Store
.AppleDesktop
.AppleDB
Network Trash Folder
Temporary Items

.bash_history
/etc/fake-hwclock.data
/var/lib/rpimonitor/stat/

1
Gibt es eine Möglichkeit, diese Ausgabe zu einer IMG- Datei zu machen ?
IgorGanapolsky

@IgorGanapolsky Nun, da alle wichtigen Dateien vorhanden sind (mit Ausnahme der Startdateien), ist es natürlich möglich, aber wenn Sie ein Image möchten, machen Sie ein Image. Sie sollten in einem neuen Beitrag keine neuen Fragen stellen, keine Kommentare.
Milliways

@Milliways warum sollten wir nicht "sudo rsync ..." verwenden? Gibt es einige Dateien, die möglicherweise nicht synchronisiert werden können?
Smilia

6

Ich habe drei Pis in meinem lokalen Netz und muss sie regelmäßig mit cron sichern, wenn sie in Betrieb sind. Aus diesem Grund habe ich ein Skript erstellt, mit dem Sie dd-, tar- und rsync-Backups erstellen und wiederherstellen können. Ich bevorzuge rsync für meine Backups, aber andere Leute bevorzugen dd oder tar. Es wird bereits von vielen Leuten benutzt. Hoffe, es ist auch für andere nützlich :-) raspibackup - Raspberry erstellt Backups von sich selbst


1
Nein, Entschuldigung: Es ist unverantwortlich, den Benutzer zu bitten, ein über HTTP heruntergeladenes Skript (als root!) Auszuführen. Bitte verteilen Sie dieses Skript über einen sicheren Kanal.
Clément

1
Ich denke nicht, dass es vom Thema abweicht und root oder nicht wichtig ist. Der Punkt ist, dass Software über einen sicheren Kanal verteilt werden sollte und Ihre Antwort schlechte Sicherheitspraktiken fördert.
Clément

1
Das wäre ein großer Schritt nach vorne, ja :)
Clément

2
Zu beachten ist, dass die Zustellung über HTTPS in diesem Fall keine zusätzliche Sicherheit bietet! Sie laden immer noch ein Skript aus dem Internet herunter und führen es aus. Der sichere Prozess besteht darin, das Skript herunterzuladen (http / https ist irrelevant), das Skript in einem Editor zu öffnen und von oben nach unten zu lesen und es auf Unregelmäßigkeiten und Unsicherheiten zu überprüfen. Nur wenn Sie zufrieden sind, sollten Sie es ausführen. Framp könnte ein Hacker für alle von uns wissen und Lieferung über https würde ihn nur in diesem Fall zum Lächeln bringen :) (Übrigens, das ist kein Vorwurf Framp!)
Julian Knight

2
Ich stimme mit Ihnen ein. Aus diesem Grund gibt es zwei Möglichkeiten beschrieben , wie das Skript installieren: 1. Verwenden Sie die installerScript 2. Laden Sie es manuell, überprüfen Sie den Code und dann manuell installieren
framp

3

Hier ist unser stabiles Tool für solche Zwecke: https://github.com/aktos-io/aktos-dcs-tools

Dieses Tool wird auf schriftliche make sshVerbindungen make backup-root, make mount-rootvon entfernten Orten im Kopf zuerst, und dann werden die lokalen Sitzungen hinzugefügt. So werden lokale Sicherungen, direkte Remote-Sicherungen und Proxy-Remote-Sicherungen unterstützt. Backups werden inkrementell erstellt (nur Diffs werden übertragen) und Backup-Verzeichnisse sind eigenständig (wählen Sie einfach ein Verzeichnis / eine Version zum Wiederherstellen aus, jedes Verzeichnis verfügt über ein vollständiges Backup). Natürlich haben Sie Versionen (backup.last-0 ist die neueste). Sie können den Sicherungsvorgang jederzeit unterbrechen und später fortsetzen.

Hier sind die Anweisungen für Ihr spezielles Problem:

 ssh to-your-raspberry
 cd /mnt/usb0/my-rpi-backups
 git clone https://github.com/ceremcem/aktos-dcs-tools backup-tools
 ln -s backup-tools/Makefile .

 ./backup-tools/configure # you do not need to make any settings for local sessions, just save the default 

 # just for the first time
 make set-local-session  # a flag file is created
 make init               # snapshots directory is created

 # anytime you want to back up
 make backup-root        # backup with rsync

BEARBEITEN

Jetzt wurde ein neues Ziel hinzugefügt: Sie können mit einem Befehl eine physische SD-Karte aus Ihren Backups erstellen:

make create-disk-from-last-backup

Befolgen Sie die Anweisungen, erstellen Sie Ihre SD-Karte und starten Sie RaspberryPi mit dieser neu erstellten SD-Karte.


1

Hier ist ein völlig anderer Ansatz. Sie können mit LVM ( L großartigem Puzzle - V olume M anager) , um konsistenten Backups zu machen. Neben anderen Verbesserungen wie dem einfachen Hinzufügen, Erweitern und Reduzieren des Speichers oder dem Wiederherstellen eines früheren Status des Betriebssystems aus einem Snapshot können Sie auch Sicherungen erstellen. Sie müssen sich keine Gedanken über dynamisch geänderte Dateien während der Sicherung machen, indem Sie Dateisysteme auf schreibgeschützt setzen, bestimmte Verzeichnisse ausschließen oder etwas anderes. Mit LVM erstellen Sie einfach einen Snapshot, hängen diesen Snapshot ein und sichern ihn mit der von Ihnen bevorzugten Methode. Sie können mit eine Kopie erstellen, mit cp -aeinen Spiegel erstellen, mit rsyncein Archiv erstellen taroder mit ein Bild erstellendd. Angenommen, Sie haben ein Sicherungsgerät aktiviert /mnt/usbhd/pi_backup/, können Sie beispielsweise Folgendes tun:

rpi ~$ sudo lvcreate --snapshot --name rpi_snap --size 1G rpi_vg/root_lv
rpi ~$ sudo mkdir /mnt/snapshot
rpi ~$ sudo mount /dev/mapper/rpi_vg-rpi_snap /mnt/snapshot

# make backups
rpi ~$ sudo cp -a /mnt/snapshot/ /mnt/usbhd/pi_backup/
rpi ~$ sudo rsync -aH --delete /mnt/snapshot/ /mnt/usbhd/pi_backup/
rpi ~$ sudo tar -czf /mnt/usbhd/pi_backup/backup.tar.gz -V "Backup of my Raspberry Pi" -C /mnt/snapshot/ ./
rpi ~$ sudo dd if=/mnt/snapshot/ of=/mnt/usbhd/pi_backup/backup.img bs=4M

rpi ~$ sudo umount /mnt/snapshot/
rpi ~$ sudo lvremove rpi_vg/rpi_snap

Das Einrichten von LVM ist nur einmal mit geringem Aufwand möglich . Wie das geht, können Sie unter Einfache Backups und Snapshots eines laufenden Systems mit LVM nachlesen .


0

Ich habe ein Backup-Tool gefunden , das installierbare Images erstellt.

Es hat auch Dienstprogramme zum Mounten und Verkleinern von Bildern.

Dies kann für andere nützlich sein

Die dazugehörige Dokumentation ist sehr kurz, daher stelle ich Folgendes fest:

  1. Extrahieren Sie die Dienstprogramme in ein beliebiges Verzeichnis und machen Sie Skripte ausführbar.
  2. Mounten Sie eine ext4formatierte Partition auf Ihrem Pi in /mntoder /media(jedes Format, das große Dateien zulässt und von Pi unterstützt wird, z. B. exFAT oder ein Netzwerklaufwerk, kann verwendet werden).
  3. Bei der ersten Ausführung werden Sie aufgefordert, einen Namen für das Backup-Image einzugeben, z /mnt/Image/BusterBackup.img
  4. Sie werden aufgefordert, eine Image ROOT-Dateisystemgröße (in MB) anzugeben. Diese kann für die kleinstmögliche Größe 0 oder für die vollständige Sicherung leer sein.
  5. Bei nachfolgenden Läufen geben Sie den Pfad des Backup-Images ein, das schrittweise aktualisiert werden soll.
An example of the commands I used:-
# Mount USB
sudo mount /dev/sda1 /mnt/Image/
# Update backup
sudo image-utils/image-backup /mnt/Image/BusterBackup.img
# Mount backup
sudo image-utils/image-mount /mnt/Image/BusterBackup.img  MountedImages
When done, run:
sudo umount MountedImages; sudo losetup -d /dev/loop0
# Compress backup
sudo sh -c "gzip -9c /mnt/Image/BusterBackup.img  > Images/BusterBackup.img.gz"

Ich habe das Original leicht modifiziert (um Mountpunkte zu kopieren), Partitionsversätze und -größen korrekt zu berechnen und ein paar Kommentare hinzugefügt.

#!/bin/bash
# Original https://raspberrypi.org/forums/viewtopic.php?p=1528736
# 2019-09-26    Modified to set size of boot sector

trap '{ stty sane; echo ""; errexit "Aborted"; }' SIGINT SIGTERM

ADDBLK=0

# Set BOOT_SIZE_MB to the Desired boot sector size (in MB) - should be multiple of 4MB
BOOT_SIZE_MB=256
BOOTSIZEM=$BOOT_SIZE_MB'M'

BOOTBEG=8192
BOOT_SIZE="$((BOOT_SIZE_MB * 1024 * 1024))"
ROUND_SIZE="$((4 * 1024 * 1024))"
# Ensure root sector starts on an Erase Block Boundary (4MB)
ROOTBEG=$(((BOOT_SIZE + ROUND_SIZE -1) / ROUND_SIZE * ROUND_SIZE / 512 + BOOTBEG))

MNTPATH="/tmp/img-backup-mnt"

ONEMB=$((1024 * 1024))

# create BOOT loop device
mkloop1()
{
  local INFO1=""
  local SIZE1=0
  local START1=0

  sync
  INFO1="$(sfdisk -d "${IMGFILE}")"
  START1=$(grep type=c <<< "${INFO1}" | sed -n 's|^.*start=\s\+\([0-9]\+\).*$|\1|p')
  SIZE1=$(grep type=c <<< "${INFO1}" | sed -n 's|^.*size=\s\+\([0-9]\+\).*$|\1|p')
  LOOP1="$(losetup -f --show -o $((${START1} * 512)) --sizelimit $((${SIZE1} * 512)) "${IMGFILE}")"
  if [ $? -ne 0 ]; then
    errexit "Unable to create BOOT loop device"
  fi
}

rmloop1()
{
  if [ "${LOOP1}" != "" ]; then
    sync
    losetup -d "${LOOP1}"
    LOOP1=""
 fi
}

# create ROOT loop device
mkloop2()
{
  local INFO2=""
  local SIZE2=0
  local START2=0

  sync
  INFO2="$(sfdisk -d "${IMGFILE}")"
  START2=$(grep type=83 <<< "${INFO2}" | sed -n 's|^.*start=\s\+\([0-9]\+\).*$|\1|p')
  SIZE2=$(grep type=83 <<< "${INFO2}" | sed -n 's|^.*size=\s\+\([0-9]\+\).*$|\1|p')
  LOOP2="$(losetup -f --show -o $((${START2} * 512)) --sizelimit $((${SIZE2} * 512)) "${IMGFILE}")"
  if [ $? -ne 0 ]; then
    errexit "Unable to create ROOT loop device"
  fi
}

rmloop2()
{
  if [ "${LOOP2}" != "" ]; then
    sync
    losetup -d "${LOOP2}"
    LOOP2=""
  fi
}

# Mount Image partitions
mntimg()
{
  MNTED=TRUE
  if [ ! -d "${MNTPATH}/" ]; then
    mkdir "${MNTPATH}/"
    if [ $? -ne 0 ]; then
      errexit "Unable to make ROOT partition mount point"
    fi
  fi
  mkloop2
  mount "${LOOP2}" "${MNTPATH}/"
  if [ $? -ne 0 ]; then
    errexit "Unable to mount image ROOT partition"
  fi
  if [ ! -d "${MNTPATH}/boot/" ]; then
    mkdir -p "${MNTPATH}/boot/"
    if [ $? -ne 0 ]; then
      errexit "Unable to make BOOT partition mount point"
    fi
  fi
  mkloop1
  mount "${LOOP1}" "${MNTPATH}/boot/"
  if [ $? -ne 0 ]; then
    errexit "Unable to mount image BOOT partition"
  fi
}

umntimg()
{
  umount "${MNTPATH}/boot/"
  if [ $? -ne 0 ]; then
    errexit "Unable to unmount image BOOT partition"
  fi
  rmloop1
  umount "${MNTPATH}/"
  if [ $? -ne 0 ]; then
    errexit "Unable to unmount image ROOT partition"
  fi
  rmloop2
  rm -r "${MNTPATH}/"
  MNTED=FALSE
}

errexit()
{
  echo ""
  echo "$1"
  echo ""
  if [ "${MNTED}" = "TRUE" ]; then
    umount "${MNTPATH}/boot/" &> /dev/null
    umount "${MNTPATH}/" &> /dev/null
    rm -rf "${MNTPATH}/" &> /dev/null
  fi
  rmloop1
  rmloop2
  exit 1
}

LOOP1=""
LOOP2=""
MNTED=FALSE

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

if [ $(id -u) -ne 0 ]; then
  errexit "$0 must be run as root user"
fi

PGMNAME="$(basename $0)"
for PID in $(pidof -x -o %PPID "${PGMNAME}"); do
  if [ ${PID} -ne $$ ]; then
    errexit "${PGMNAME} is already running"
  fi
done

rsync --version &> /dev/null
if [ $? -ne 0 ]; then
  errexit "rsync not installed (run: apt-get install rsync)"
fi

if command -v systemctl > /dev/null && systemctl | grep -q '\-\.mount'; then
  SYSTEMD=1
elif [ -f /etc/init.d/cron ] && [ ! -h /etc/init.d/cron ]; then
  SYSTEMD=0
else
  errexit "Unrecognized init system"
fi

if [ ${SYSTEMD} -eq 1 ]; then
  ROOT_PART="$(mount | sed -n 's|^/dev/\(.*\) on / .*|\1|p')"
else
  if [ ! -h /dev/root ]; then
    errexit "/dev/root does not exist or is not a symlink"
  fi
  ROOT_PART="$(readlink /dev/root)"
fi

ROOT_TYPE=$(blkid "/dev/${ROOT_PART}" | sed -n 's|^.*TYPE="\(\S\+\)".*|\1|p')

ROOT_DEV="${ROOT_PART:0:(${#ROOT_PART} - 1)}"
if [ "${ROOT_DEV}" = "mmcblk0p" ]; then
  ROOT_DEV="${ROOT_DEV:0:(${#ROOT_DEV} - 1)}"
fi

PTUUID="$(blkid "/dev/${ROOT_DEV}" | sed -n 's|^.*PTUUID="\(\S\+\)".*|\1|p')"

DEVSIZE=$(blockdev --getsize64 "/dev/${ROOT_PART}")
BLKSIZE=$(blockdev --getbsz "/dev/${ROOT_PART}")
BLKCNT=$((${DEVSIZE} / ${BLKSIZE}))
INFO="$(df | grep /dev/root)"
DFKSIZE=$(awk '{print $2}' <<< "${INFO}")
DFKFREE=$(awk '{print $4}' <<< "${INFO}")
ROOTSIZE=$((${BLKCNT} * ${BLKSIZE}))
ROOTUSED=$(((${DFKSIZE} - ${DFKFREE}) * 1024))
IRFSMIN=$(((${ROOTUSED} + (${ADDBLK} * ${BLKSIZE}) + (${ONEMB} - 1)) / ${ONEMB}))
IRFSMAX=$(((${ROOTSIZE} + (${ONEMB} - 1)) / ${ONEMB}))

IMGFILE="$1"
if [ "${IMGFILE}" = "" ]; then
# Create Image file
  while :
  do
    echo ""
    read -r -e -i "${IMGFILE}" -p "Image file to create? " IMGFILE
    if [ "${IMGFILE}" = "" ]; then
      continue
    elif [[ ! "${IMGFILE}" =~ ^/mnt/.*$ && ! "${IMGFILE}" =~ ^/media/.*$ ]]; then
      echo ""
      echo "${IMGFILE} does not begin with /mnt/ or /media/"
      continue
    fi
    if [ -d "${IMGFILE}" ]; then
      echo ""
      echo "${IMGFILE} is a directory"
    elif [ -f "${IMGFILE}" ]; then
      echo ""
      echo -n "${IMGFILE} already exists, Ok to delete (y/n)? "
      while read -r -n 1 -s answer; do
        if [[ "${answer}" = [yYnN] ]]; then
          echo "${answer}"
          if [[ "${answer}" = [yY] ]]; then
            break 2
          else
            break 1
          fi
        fi
      done
    else
      break
    fi
  done
  IRFSSIZE=""
  while :
  do
    echo ""
    read -r -e -i "${IRFSSIZE}" -p "Image ROOT filesystem size (MB) [${IRFSMAX}]? " IRFSSIZE
    if [ "${IRFSSIZE}" = "" ]; then
      IRFSSIZE=${IRFSMAX}
      break
    elif [ ${IRFSSIZE} -ge ${IRFSMIN} ]; then
      break
    else
      echo ""
      echo "Requested image ROOT filesystem size (${IRFSSIZE}) is too small (Minimum = ${IRFSMIN})"
      IRFSSIZE=${IRFSMIN}
    fi
  done
  echo ""
  echo -n "Create ${IMGFILE} [${IRFSSIZE} MB] (y/n)? "
  while read -r -n 1 -s answer; do
    if [[ "${answer}" = [yYnN] ]]; then
      echo "${answer}"
      if [[ "${answer}" = [yY] ]]; then
        break
      else
        errexit "Aborted"
      fi
    fi
  done
  if [ -f "${IMGFILE}" ]; then
    rm "${IMGFILE}"
    if [ $? -ne 0 ]; then
      errexit "Unable to delete existing image file"
    fi
  fi
  ROOTEND=$((${ROOTBEG} + ((${IRFSSIZE} * ${ONEMB}) / 512) - 1))
  truncate -s $(((${ROOTEND} + 1) * 512)) "${IMGFILE}"
  if [ $? -ne 0 ]; then
    errexit "Unable to create image file"
  fi
# create image/partitions
  sync
  fdisk "${IMGFILE}" <<EOF > /dev/null
p
n
p
1
${BOOTBEG}
+${BOOTSIZEM}
t
c
p
n
p
2
${ROOTBEG}
${ROOTEND}
p
w
EOF

  mkloop1
  mkloop2
  mkfs.vfat "${LOOP1}" > /dev/null
  if [ $? -ne 0 ]; then
    errexit "Unable to create image BOOT filesystem"
  fi
  dosfsck "${LOOP1}" > /dev/null
  if [ $? -ne 0 ]; then
    errexit "Image BOOT filesystem appears corrupted"
  fi
  if [ "${ROOT_TYPE}" = "f2fs" ]; then
    mkfs.f2fs "${LOOP2}" > /dev/null
  else
    mkfs.ext4 -q -b ${BLKSIZE} "${LOOP2}" > /dev/null
  fi
  if [ $? -ne 0 ]; then
    errexit "Unable to create image ROOT filesystem"
  fi
  rmloop2
  rmloop1
# Initialise image PARTUUID
  fdisk "${IMGFILE}" <<EOF > /dev/null
p
x
i
0x${PTUUID}
r
p
w
EOF
# Create empty directories in image root partition
  mntimg
  mkdir "${MNTPATH}/dev/" "${MNTPATH}/media/" "${MNTPATH}/mnt/" "${MNTPATH}/proc/" "${MNTPATH}/run/" "${MNTPATH}/sys/" "${MNTPATH}/tmp/"
  if [ $? -ne 0 ]; then
    errexit "Unable to create image directories"
  fi
  chmod a+rwxt "${MNTPATH}/tmp/"
  umntimg
  echo ""
  echo "Starting full backup (for incremental backups, run: $0 ${IMGFILE})"
# END of create image/partitions
else

# Check existing Image
  if [[ ! "${IMGFILE}" =~ ^/mnt/.*$ && ! "${IMGFILE}" =~ ^/media/.*$ ]]; then
    errexit "${IMGFILE} does not begin with /mnt/ or /media/"
  fi
  if [ -d "${IMGFILE}" ]; then
    errexit "${IMGFILE} is a directory"
  elif [ ! -f "${IMGFILE}" ]; then
    errexit "${IMGFILE} not found"
  fi
  echo "Starting incremental backup to ${IMGFILE}"
fi

# rsync root partition
mntimg
sync
rsync -aDH --partial --numeric-ids --delete --force --exclude "${MNTPATH}" --exclude '/dev' --exclude '/media' --exclude '/mnt/*/*' --exclude '/proc' --exclude '/run' --exclude '/sys' \
--exclude '/tmp' --exclude 'lost\+found' --exclude '/etc/udev/rules.d/70-persistent-net.rules' --exclude '/var/lib/asterisk/astdb.sqlite3-journal' / "${MNTPATH}/"
if [[ $? -ne 0 && $? -ne 24 ]]; then
  errexit "Unable to create backup"
fi
sync
umntimg

-1

Öffnen Sie das Terminal und geben Sie 'lsblk -f' ein.
Dies sollte alle angeschlossenen Speichergeräte anzeigen.
Geben Sie dann 'dd if = / dev / [der Name Ihrer SD-Karte] bs = 1M' ein.
Dies wird eine Weile dauern, daher möchten Sie es möglicherweise im Hintergrund ausführen.
Genau so sichern Sie Ihre SD-Karte unter Linux.


Das sichert ALLES, auch unnötige und unerwünschte Dateien.
IgorGanapolsky

3
Dies führt zu einer inkonsistenten Sicherung, da sich auf einem laufenden System während der Sicherung Änderungen ergeben.
Ingo
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.