Backup eines Raspberry Pi im laufenden Betrieb

Ich habe eine ganze Weile nach einer guten Backuplösung für meinen Raspberry Pi gesucht. Da das kleine Ding jetzt schon allerhand Aufgaben übernimmt (DMS-System, Internetradio, Funksteckdosen schalten, usw.), wurde ein automatisches Backup immer wichtiger. Bei einem anderen System habe ich einfach im laufenden Betrieb mit dd die gesamte Karte geclont, aber das ist nicht so optimal, weil hier schnell mal fehlerhafte Dateien entstehen, wenn wärend des Backups Daten in das zu sichernde Filesystem geschrieben werden. Bei meiner Internetsuche bin ich dann auf raspiBackup gestoßen. Das Script bietet eine vielzahl an Backupmöglichkeiten. Ich habe mich für die rsync Variante entschieden, weil ich die Sicherung auf mein QNAP NAS mache. Da hier auch ein Linuxsystem läuft, kann ich, so der Plan, leichter auf eventuell benötigte Dateien im Backup zugreifen. Ob das aufgeht, wird sich zeigen, wenn alles getestet wurde. Ich schreibe Haupsächlich alles nieder, um später einen Anhaltspunkt zu haben, wie ich z.B. bei einer erneuten Installation vorgehe. Ein anderer nicht zu vernachlässigender Grund ist die Notwendigkeit bei einem Restore nicht erst lange suchen zu müssen, sondern direkt mit der Rücksicherung loszulegen.

Update:

Leider funktionert raspiBackup weder auf meinem NAS, Dreambox noch auf der Fritzbox. Da dies alles embedded Systeme sind, ist die Software speziell auf die jeweilige Hardware abgestimmt. Es wäre sehr viel Glück gewesen, wenn raspiBackup auf diesen Systemen funktioniert hätte. Aber versuchen kann man es ja. 🙂 Deßhalb werde ich von einer SD Karte mit Raspbian inkl. raspiBackup ein dd Image erzeugen und auf meinem NAS ablegen. (event. miniban) Sollte dann wirklich der ernstfall eintreten, kann ich ohne Internet das gesicherte dd Image auf eine kleine SD-Karte schreiben und dann das Backup vom NAS auf die Ersatz SD-Karte wiederherstellen.

Installation der nötigen Pakete

Bevor wir loslegen können, müssen einige Pakete installiert werden. Ich benutze aptitude als Paketverwaltung. Solltet ihr apt-get verwenden, einfach austauschen.

aptitude update
aptitude install rsync curl dosfstools parted

1. Vorbereitung

Download und eine kurze Abfrage der wichtigsten Parameter. Bei diesem Installscript wird raspiBackup direkt in /usr/local/bin installiert und die erstellte Konfigurationsdatei nach /usr/local/etc/ kopiert.

curl -L -O https://www.linux-tips-and-tricks.de/raspiBackupInstall.sh && bash raspiBackupInstall.sh

2. Wrapperscript speichern und anpassen

Um noch ein paar andere Aufgaben vor und nach dem Backup komfortabel zu erledigen, bietet der Entwickler ein s.g. Wrapperscript an. Eigentlich ist das nur ein Shellscript von dem wiederum das Backup mit raspiBackup angeschoben wird. Ich habe in dem Script ein paar kleine Änderungen eingepflegt. Unter anderem lasse ich einige Dienste vor dem Backup stoppen, ein MySQL Backup machen und nach erfolgreichem Backup die Deamons wieder hochfahen. Die Zeilen 22, 23, 70, 71 und die letzten im Script mit den Services (systemctr) sollten noch auf eine andere Umgebung angepasst werden.

UPDATE: Ich hatte erst ein Samba Share als Ziel für die Sicherung ausgewählt. Natürlich werden da keine Berechtigungen, User bzw. Usergruppen gespeichert. Daher habe ich mich für ein NFS Share entschieden. Die Einrichtung auf dem NAS ging ähnlich schnell und jetzt werden auch die passenden Rechte gesetzt. Dies ist nur bei der Backupmethode rsync nötig. Bei den anderen (dd und tar) kann man einen Samba Share benutzen.

#!/bin/bash

# Sample script to wrap raspiBackup.sh in order
# to mount and unmount the backup device
# and start and stop services

# (C) 2013,2016 - framp at linux-tips-and-tricks dot de

MYSELF=${0##*/}
MYNAME=${MYSELF%.*}
VERSION="0.2.0"

GIT_DATE="$Date: 2016-06-28 20:44:54 +0200$"
GIT_DATE_ONLY=${GIT_DATE/: /}
GIT_DATE_ONLY=$(cut -f 2 -d ' ' <<< $GIT_DATE)
GIT_TIME_ONLY=$(cut -f 3 -d ' ' <<< $GIT_DATE)
GIT_COMMIT="$Sha1: 0a8ecaa$"
GIT_COMMIT_ONLY=$(cut -f 2 -d ' ' <<< $GIT_COMMIT | sed 's/\$//')

GIT_CODEVERSION="$MYSELF $VERSION, $GIT_DATE_ONLY/$GIT_TIME_ONLY - $GIT_COMMIT_ONLY"

BACKUP_MOUNT_POINT="/media/nas/Public"                                                  # ===> adapt to your environment
BACKUP_PATH="$BACKUP_MOUNT_POINT/Programm.Images/rpi/backup/rsync-wz"                   # ===> adapt to your environment

# add pathes if not already set (usually not set in crontab)

if [[ -e /bin/egrep ]]; then
        PATHES="/bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin"
        for p in $PATHES; do
                if ! /bin/egrep "^$p|:$p" <<< "$PATH" 2>&1 1>/dev/null; then
                        [[ -z "$PATH" ]] && export PATH="$p" || export PATH="$p:$PATH"
                fi
        done
fi

function trapWithArg() { # function trap1 trap2 ... trapn
        local func
    func="$1" ; shift
    for sig ; do
        trap "$func $sig" "$sig"
    done
}

function isMounted() {
        local path
        path=$1
        while [[ $path != "" ]]; do
                if mountpoint -q $path; then
                        return 0
        fi
        path=${path%/*}
        done
    return 1
}

function cleanup() { # trap
        if (( ! $WAS_MOUNTED )); then
                echo "--- Unmounting $BACKUP_MOUNT_POINT"
                umount $BACKUP_MOUNT_POINT
        fi
}
# main program

trapWithArg cleanup SIGINT SIGTERM EXIT

# check if mountpoint is mounted
if ! isMounted $BACKUP_MOUNT_POINT; then
        WAS_MOUNTED=0
        echo "--- Mounting $BACKUP_MOUNT_POINT"
#        mount.cifs //192.168.xxx.xxx/Freigabe $BACKUP_MOUNT_POINT -o user=foo,password=bar
        mount.nfs 192.168.xxx.xxx:/backup $BACKUP_MOUNT_POINT

        if ! isMounted $BACKUP_MOUNT_POINT; then
                echo "Nas ist nicht erreichbar"
                exit 1
        fi
else
        # was already mounted, don't unmount it at script end
        WAS_MOUNTED=1
        echo "--- $BACKUP_MOUNT_POINT already mounted"
fi

# now stop all active services

echo "Try to stop all active services now.!!"

systemctl stop samba
systemctl stop lighttpd

##mysqlbackup
/usr/sbin/automysqlbackup

systemctl stop mysql
systemctl stop exim4

echo "Dienste gestoppt"

# create backup
raspiBackup.sh -p $BACKUP_PATH                   # ===> insert all additional parameters or use /usr/local/etc/raspiBackup.conf to pass all parameters

# now start all services again in reverse order
echo "Now start all services again in reverse order"

systemctl start exim4
systemctl start mysql
systemctl start lighttpd
systemctl start samba

echo "Dienste gestartet."

# $BACKUP_MOUNT_POINT unmounted when script terminates only if it was mounted by this script

 

Das sollte es gewesen sein. Wenn das Script ausgeführt wird, sollte der Raspberry Pi gesichert werden. Mit einem Eintrag in der crontab wird das Script bei mir regelmäßig Montags um 3:10 Uhr ausgeführt.

# m h dom mon dow user  command
10 3    * * 1   root    /usr/local/bin/raspiBackupWrapper.sh >> /dev/null

Da es bei dem Test der Wiederherstellung einige Probleme mit einer zu kleinen SD-Karte gab, hab ich noch einen anderen Artikel dazu geschrieben.

 

3 Kommentare zu „Backup eines Raspberry Pi im laufenden Betrieb“

  1. Moin,

    Update:
    Leider funktionert raspiBackup weder auf meinem NAS, Dreambox noch auf der Fritzbox.

    Das kann ich so nicht unkommentiert stehen lassen. Du schreibst Du hast beim Erstellen von Backups mit raspiBackup Fehler bekommen. Das passiert immer wieder. Aber warum hast Du die Fehler nicht berichtet? Ich bin immer bereit nach der Ursache zu suchen und zu helfen. Sollte ein Fehler in raspiBackup vorliegen fixe ich ihn natürlich. Es kommt aber aus Erfahrung sehr häufig vor, dass der Fehler nicht durch raspiBackup verursacht wird sondern Konfigurations- oder Verständnisprobleme dazu führen.

    Ich würde mich gerne detailierter über die Fehler per eMail mit Dir austauschen.

    Cu framp

  2. Hallo framp,

    ich glaube nicht, dass es ein Fehler von raspiBackup ist, daher keine Info an dich. Bei dem zitierten Update auf dem Blog, ging es nur um die Wiederherstellung eines Pi-Backups auf einem vorhanden Linuxsystem bei mir zu Hause. Die Genannten sind alles Embedded Systeme und haben daher nicht alle Programme installiert, die raspiBackup benötigt. Des Weiteren denke ich, dass hier auch die verschiedenen Versionen der einzelnen Programme mit rein spielen (bestimmte Parameter in dieser Version nicht verfügbar), oder vielleicht auch an einer anderen Version der verwendeten Shell oder der Coreutils.
    Wie auch immer, das Script ist super und ich setze es regelmäßig auf den Pi’s ein. Für die Wiederherstellung habe ich ein einfaches Image (miniban) geflasht und dein Script installiert. Jetzt steht noch ein dd Backup der SD Karte an, um später für die Wiederherstellung gerüstet zu sein. 🙂

  3. Moin Kendy,

    vielen Dank für Deine Erläuterung. Das hört sich jetzt ganz anders an und ich kann auch verstehen, dass es bei embedded Systemen Probleme geben kann. raspiBackup ist für raspbian entwickelt und getestet.

    Leider bekommt man beim Lesen des Beitrages den Eindruck als hätte raspiBackup ein Problem. Deshalb musste ich mich hier per Kommentar einfach melden :-). Wäre nett wenn Du den Update oben so änderst dass er nicht mehr missverständlich ist oder einfach die Erläuterungen aus Deinem Kommentar dazufügst.

    Cu framp

    PS: Euer Blog gefällt mir 😉

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht.