Raspberry Pi: Live Backup der SD Karte anlegen

Raspberry Pi: Live Backup der SD Karte anlegen

letzte Aktualisierung: 7. September 2020
#

Ein Raspberry Pi kann vielfältige Aufgaben übernehmen. Einige Projekte kommen mit wenigen Handgriffen aus bis alles läuft und in manchen steckt viel Zeit, Energie und Gehirnschmalz. Wie bei allen anderen Daten auch, ist hier ein Backup das A&O. Die Automatisierung des eigenen Heimes soll natürlich auch im Fehlerfall genauso schnell wieder zum Laufen gebracht werden wie der geplante Videoabend mit Kodi.

Bei einigen Projekten reicht es die Config-Dateien regelmäßig zu sichern. Aber gerade wenn die Einrichtung und Installation der Programme einiges an Zeit kostet, lohnt es sich hier auch in regelmäßigen Abständen ein Vollbackup anzulegen. Um den Betrieb der kleinen Server nicht allzu lange zu stören, bietet sich ein Live-Backup an. Linux stellt dafür die bekannten Befehl dd zur Verfügung. Da hierbei eine 1:1 Kopie der SD Karte angelegt wird, wird bei 32GB, 64GB … schnell mal eine ganze Menge Speicherplatz fällig. Außerdem erhöht sich natürlich bei größeren Images auch die Wiederherstellungszeit. Um dies zu umgehen nutzen wir das Script “pishrink” von Drewsif, dass die Aufgabe der Verkleinerung übernimmt.

Das shrinken benötigt allerdings eine Menge Ressourcen, so dass das Script erst an einem Raspberry Pi 4 genutzt werden sollte. Selbst da benötigt es für 32GB noch rund 2h.

Voraussetzungen

  • Installation von Mutt – The Mutt Mail User Agent
  • Download von PiShrink
  • Konfiguration der fstab Datei zur Einbindung eines externen Datenträgers zur Speicherung des Images

Installation von Mutt

  • sudo apt-get update && sudo apt-get install mutt

Einrichtung von PiShrink

  • ich lade das Scripte unter /home/pi/
  • wget https://raw.githubusercontent.com/Drewsif/PiShrink/master/pishrink.sh
  • chmod +x pishrink.sh – Script ausführbar machen

Externe Festplatte vorbereiten

  • mit sudo blkid finden wird die Bezeichnung unserer Festplatte heraus, in meinem Fall sda2
  • mkdir backup – legt das Verzeichnis /home/pi/backup an, das wir später als Mountpunkt nutzen
  • Eintrag in der Datei fstab ergänzen, damit die externe Platte bei jedem Neustart, bzw. bei Ausführung unseres Backupscriptes gemountet wird
    sudo nano /etc/fstab
  • Zeile ergänzen
    /dev/sda2 home/pi/backup ntfs defaults,nofail,x-systemd.device-timeout=5 0 2

Backupscript

Das Backup übernimmt ein Script und regelt dabei die 1:1 Kopie, die Verkleinerung und Mailbenachrichtigung über den Verlauf des Backups. Ich habe dafür das Script von Stefan Strobel genommen und an meine Bedürfnisse angepasst.

#!/bin/bash
# by strobelstefan.org
# 2019-10-23
# Version: 2.0
# https://strobelstefan.org/?p=5985
#
# This script creates a full clone of your Raspberry Pi´s SD card.
#

###################################
# Define Variables
###################################

# Storage device as defined in your /etc/fstab.
mountpoint='/home/pi/backup/'

# Path were the image of your SD card should be saved to
STORAGEPATH="/home/pi/backup/imagebackup"

# E-Mail Address
EMAIL="info@mail.de"

# Image name
IMAGENAME="raspi"

#Log File location and name
LOGFILE="/var/log/"$HOSTNAME_${IMAGENAME}_"backup-image.log"

###################################
# This removes your old log file
###################################
# This removes your old log file.
# When you run the script the first time an error will be displayed,
# because no log file is in the defined path.
rm ${LOGFILE}

###################################
# MOUNTPOINT Section - Check Mount point Availability
###################################
# It checks if your mount point is accessible by your RPi.
# This is a crucial step, if the storage is not available the clone process of the SD card$
# Process
# 1. Check if mount point is accessible
# 2. If YES go to DELETION Section
# 3.1 If NO, try to mount storage device as defined in /etc/fstab
# 3.2 If mount is again not successful exit script, no further action will be conducted

if [ "$(findmnt ${mountpoint})" ] ;
    then
        echo $(date +%Y-%m-%d_%H-%M-%S) " - Mount point accessible by your "$HOSTNAME >> ${LOGFILE}
    else
        echo $(date +%Y-%m-%d_%H-%M-%S) " - Mount point was not accessible, try to mount it now as defined in your /etc/fstab" >> ${LOGFILE}

    #This command mounts all storages defined in /etc/fstab
    mount -a
 
    if [ $? != 0 ]
        then
            echo $(date +%Y-%m-%d_%H-%M-%S) " - Mount of storage in first try successfully completed" >> ${LOGFILE}
        sleep 5
            mount -a
        if [ $? != 0 ]
        then
            echo $(date +%Y-%m-%d_%H-%M-%S) " - Backup FAILED! Was not able to mount your storage device. Stop backup process. You have to check it manually." >> ${LOGFILE}
            echo "Sent backup status via e-mail" | mutt ${EMAIL} -a ${LOGFILE} -s $HOSTNAME" - Backup FAILED" >> ${LOGFILE}
        exit
        fi
    fi
fi

##################################################################
# DELETION Section - Remove old Images from Storage Device
##################################################################
# Use this command with CAUTION!
# This will help you to automatically remove old images from your storage device to avoid that your
# storage will run out of disk space

echo $(date +%Y-%m-%d_%H-%M-%S) " - Start to delete files older than defined time " >> ${LOGFILE}

# Uncomment if the files should be identified by days, file > 32 days than it gets deleted
find ${STORAGEPATH}/*.* -mtime +32 -exec rm -r {} \;

# Uncomment if you would like to use minutes file > 10080 minutes than it gets deleted
#find ${STORAGEPATH}/*.* -type f -mmin +43200 -exec rm {} \;

if [ $? != 0 ]
    then
        echo $(date +%Y-%m-%d_%H-%M-%S) " - Deletion of old image files successfully completed" >> ${LOGFILE}
     if [ $? != 0 ]
     then
        echo $(date +%Y-%m-%d_%H-%M-%S) " - Was not able to delete old image files. You have to check it manually." >> ${LOGFILE}
    break
    fi
fi
 
###################################
# Dienste beenden
###################################
# DB-Dienste etc. beenden, SmartHome nicht nutzbar

sudo service openhab2 stop
echo $(date +%Y-%m-%d_%H-%M-%S) " - OpenHAB2 beendet" >> ${LOGFILE}

###################################
# CLONE Section - Clone SD Card Image
###################################
# This line creates a full copy of the SD card and writes it as an image file to the defined patch
 
echo $(date +%Y-%m-%d_%H-%M-%S) " - Started to clone image" >> ${LOGFILE}
 
# Saves a plain img file on your storage device
sudo dd if=/dev/mmcblk0 of=${STORAGEPATH}/${IMAGENAME}_$(date +%Y-%m-%d).img bs=1MB
 
echo $(date +%Y-%m-%d_%H-%M-%S) " - Finished to clone image" >> ${LOGFILE}
 
###################################
# Dienste starten
###################################
# Startet beendete Dienste neu, SmartHome wieder möglich

sudo service openhab2 start
echo $(date +%Y-%m-%d_%H-%M-%S) " - openHAB2 gestartet" >> ${LOGFILE}

###################################
# Resize dd Image
###################################
# Resize image with pishrink
# Please see https://github.com/Drewsif/PiShrink for further details
# pishrink.sh must be located in the same directory as this script!
 
echo $(date +%Y-%m-%d_%H-%M-%S) " - Started to resize image" >> ${LOGFILE}
sudo /bin/bash /etc/scripts/pishrink.sh -d ${STORAGEPATH}/${IMAGENAME}_$(date +%Y-%m-%d).img ${STORAGEPATH}/${IMAGENAME}_$(date +%Y-%m-%d)-small.img
echo $(date +%Y-%m-%d_%H-%M-%S) " - Finished to resize big image" >> ${LOGFILE}

#Delete big image file
echo $(date +%Y-%m-%d_%H-%M-%S) " - Started to delete big image" >> ${LOGFILE}
sudo rm ${STORAGEPATH}/${IMAGENAME}_$(date +%Y-%m-%d).img
echo $(date +%Y-%m-%d_%H-%M-%S) " - Finished to delete big image" >> ${LOGFILE}
 
# Creates a compressed file of the resized image
# This command will create a compressed gz archive of the small image file.
# The small file will get deleted during the process if you would like to keep
# the small image file use the command gzip -k ${STORAGEPATH}/${IMAGENAME}_$(date +%Y-%m-%d)-small.img
# Before you change the compression process check your disk space size
 
echo $(date +%Y-%m-%d_%H-%M-%S) " - Started to compress small image" >> ${LOGFILE}
 
gzip -q ${STORAGEPATH}/${IMAGENAME}_$(date +%Y-%m-%d)-small.img
 
echo $(date +%Y-%m-%d_%H-%M-%S) " - Finished to compress small image" >> ${LOGFILE}
 
 
if [ $? != 0 ]
    then
        echo $(date +%Y-%m-%d_%H-%M-%S) " - Image file created" >> ${LOGFILE}
     if [ $? != 0 ]
    then
        echo $(date +%Y-%m-%d_%H-%M-%S) " - Was not able to create your image file. You have to check it manually." >> ${LOGFILE}
    break
    fi
fi
 
 
###################################
# UMOUNT Section - Unmount Storage Device
###################################
# This command unmounts the defined storage device.
# In the first try it will gently try to unmount, if the device is busy the command will force the unmount.
 
#if [ "$(umount ${mountpoint})" ] ; 
#    then
#        echo $(date +%Y-%m-%d_%H-%M-%S) " - Umounted #your storage device" >> ${LOGFILE}
#    else
#        echo $(date +%Y-%m-%d_%H-%M-%S) " - Umount of #storage device was not possible in first run, wait #for 30 seconds" >> ${LOGFILE}
#    sleep 30
#  
#    if [ $? != 0 ]
#        then
#            echo $(date +%Y-%m-%d_%H-%M-%S) " - #Umount was successful" >> ${LOGFILE}
#        sleep 5
#            umount ${mountpoint}
#        if [ $? != 0 ]
#        then
#            echo $(date +%Y-%m-%d_%H-%M-%S) " - #Umount successful" >> ${LOGFILE}
#        exit
#        fi
#    fi
#fi

# Skript finished
echo $(date +%Y-%m-%d_%H-%M-%S) " - Mission Accomplished!!! System is going for a reboot." >> ${LOGFILE}
 
# Send status via e-mail
echo "Sent backup status via e-mail" | mutt ${EMAIL} -a ${LOGFILE} pishrink.log -s $HOSTNAME" - Backup SUCCESSFULL" >> ${LOGFILE}
 
#Optional
# If you like to reboot your system, please uncomment
#sudo reboot
  • Script ausführbar machen
    sudo chmod +x backup-pi.sh
  • Für eine automatische Sicherung nutzen wir einen Crontab
    sudo crontab -e
  • Script eintragen und Startzeit festlegen. (z.B. jeden Ersten Tag im Monat um 02:00 Uhr)
    0 2 1 * * /bin/bash /home/pi/backup-pi.sh
    ┬ ┬ ┬ ┬ ┬
    │ │ │ │ │
    │ │ │ │ └───── Wochentag (0-7, Sonntag ist 0 oder 7)
    │ │ │ └────── Monat (1-12)
    │ │ └──────── Tag (1-31)
    │ └────────── Stunde (0-23)
    └──────────── Minute (0-59)

Quellen

Tags:
Nach oben