Mein Quick und Dirty Backup-Container


Quick und Dirty Backup-Strategien für Docker-Container: Vor- und Nachteile der Komprimierung

In der Welt der Datensicherung sind effektive Methoden zur Sicherstellung von Datenintegrität und -verfügbarkeit von größter Bedeutung. Dies gilt besonders für Docker-Container, bei denen spezifische Anforderungen an Konsistenz und Effizienz bestehen. In diesem Artikel werfen wir einen Blick auf eine Backup-Methode, die Docker-Container stoppt, Daten optional komprimiert und dann überträgt. Wir werden die Vor- und Nachteile dieser Methode analysieren und die Herausforderungen für kontinuierlich verfügbare Dienste beleuchten. Außerdem zeigen wir, wie das entsprechende Dockerfile und das Backup-Skript aussehen.
Link zu Github Quick und Dirty Backup Container

Die Backup-Methode im Überblick

Die Backup-Methode umfasst die folgenden Schritte:

  1. Stopp aller Docker-Container: Um eine konsistente Datensicherung zu gewährleisten, stoppen wir alle Docker-Container. Dies ist entscheidend für Datenbanken und andere Dienste, bei denen Konsistenz während der Sicherung erforderlich ist.

  2. Optionale Datenkomprimierung: Nach dem Stoppen der Container wird die Möglichkeit angeboten, die Daten in tar.gz-Archive zu packen. Diese Komprimierung kann die Datenmenge reduzieren, die übertragen werden muss, ist jedoch optional.

  3. Übertragung der Daten: Die Daten – ob komprimiert oder unkomprimiert – werden mit rsync auf den lokalen Server übertragen.

  4. Neustart der Docker-Container: Nach Abschluss der Sicherung werden die Docker-Container wieder gestartet.

  5. Sicherungslog: Ein Log-Eintrag dokumentiert den Erfolg des Backups.


Dockerfile und Backup-Skript

Hier ist das Dockerfile für die Backup-Lösung:

# Verwende das offizielle Ubuntu-Image
FROM ubuntu:20.04

# Installiere benötigte Pakete
RUN apt-get update && apt-get install -y \
    rsync \
    openssh-client \
    cron \
    nginx \
    && apt-get clean

# Füge den SSH-Schlüssel ins Image (ersetze dies durch den tatsächlichen Pfad)
COPY ./id_rsa /root/.ssh/id_rsa

# Setze die korrekten Berechtigungen für den SSH-Schlüssel
RUN chmod 600 /root/.ssh/id_rsa

# Kopiere das Backup-Skript und den Cronjob
COPY backup.sh /usr/local/bin/backup.sh
COPY crontab.txt /etc/cron.d/backup-cron
COPY log.sh /usr/local/bin/log.sh

# Mache die Skripte ausführbar
RUN chmod +x /usr/local/bin/backup.sh /usr/local/bin/log.sh

# Einrichten der Cronjob-Konfiguration
RUN crontab /etc/cron.d/backup-cron

# Kopiere die Nginx-Konfiguration
COPY nginx.conf /etc/nginx/nginx.conf

# Exponiere Port 80 für Nginx
EXPOSE 80

# Starte den Cron-Daemon und Nginx
CMD ["sh", "-c", "cron && nginx -g 'daemon off;'"]

Und hier ist das Backup-Skript (backup.sh):

#!/bin/bash

# SSH-Zugangsdaten
REMOTE_USER="root"
REMOTE_HOST="xxx.xxx.xxx.xxx"
REMOTE_PATHS=(
    "/home/root/docker/Nextcloudlife"
    "/home/root/docker/bludit"
    "/home/root/docker/proxy"
    "/home/root/docker/mailcow-dockerized"
    "/var/lib/docker/volumes"
)

# Lokales Verzeichnis für Backups
LOCAL_BACKUP_DIR="/shared/webserver"

# Stopp aller Docker-Container auf dem Remote-Server
echo "Stopping all Docker containers on $REMOTE_HOST..."
ssh -i /root/.ssh/id_rsa "$REMOTE_USER@$REMOTE_HOST" \
    "docker stop \$(docker ps -q)"

# Optional: Erstellen von tar.gz-Archiven auf dem Remote-Server
COMPRESS=false
if [ "$COMPRESS" = true ]; then
    echo "Compressing directories on $REMOTE_HOST..."
    for REMOTE_PATH in "${REMOTE_PATHS[@]}"; do
        REMOTE_BASENAME=$(basename "$REMOTE_PATH")
        ssh -i /root/.ssh/id_rsa "$REMOTE_USER@$REMOTE_HOST" \
            "tar -czf /tmp/${REMOTE_BASENAME}.tar.gz -C $(dirname "$REMOTE_PATH") $REMOTE_BASENAME"
    done
fi

# Übertragung der Daten
echo "Transferring data..."
for REMOTE_PATH in "${REMOTE_PATHS[@]}"; do
    REMOTE_BASENAME=$(basename "$REMOTE_PATH")
    if [ "$COMPRESS" = true ]; then
        rsync -avz --no-owner --no-group -e "ssh -i /root/.ssh/id_rsa" "$REMOTE_USER@$REMOTE_HOST:/tmp/${REMOTE_BASENAME}.tar.gz" "$LOCAL_BACKUP_DIR"
    else
        rsync -avz --no-owner --no-group -e "ssh -i /root/.ssh/id_rsa" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_PATH" "$LOCAL_BACKUP_DIR"
    fi
done

# Starten aller Docker-Container auf dem Remote-Server
echo "Starting all Docker containers on $REMOTE_HOST..."
ssh -i /root/.ssh/id_rsa "$REMOTE_USER@$REMOTE_HOST" \
    "docker start \$(docker ps -a -q)"

# Optional: Löschen der temporären tar.gz-Dateien auf dem Remote-Server
if [ "$COMPRESS" = true ]; then
    echo "Cleaning up compressed files on $REMOTE_HOST..."
    for REMOTE_PATH in "${REMOTE_PATHS[@]}"; do
        REMOTE_BASENAME=$(basename "$REMOTE_PATH")
        ssh -i /root/.ssh/id_rsa "$REMOTE_USER@$REMOTE_HOST" \
            "rm /tmp/${REMOTE_BASENAME}.tar.gz"
    done
fi

# Sicherungslog erstellen
echo "$(date) - Backup abgeschlossen" >> /var/log/backup.log

Vorteile der Backup-Methode

  1. Konsistenz durch Container-Stopp: Durch das Stoppen der Docker-Container wird sichergestellt, dass alle Daten konsistent gesichert werden. Dies ist besonders wichtig für Datenbanken, bei denen inkonsistente Daten zu Problemen führen können.

  2. Flexibilität bei der Datenkomprimierung: Die Möglichkeit, Daten vor der Übertragung zu komprimieren, kann die benötigte Bandbreite reduzieren und die Übertragungszeit verkürzen. Dies ist besonders nützlich bei großen Datenmengen.

  3. Automatisierung durch Cron: Ein Cronjob sorgt für eine regelmäßige und automatische Sicherung um Mitternacht, was den manuellen Aufwand minimiert und eine zuverlässige Backup-Routine sicherstellt.

Vor- und Nachteile der Datenkomprimierung

Vorteile der Komprimierung:

  • Reduzierte Übertragungsgröße: Durch das Erstellen von tar.gz-Archiven kann die Menge an Daten, die über das Netzwerk übertragen werden muss, erheblich reduziert werden. Dies kann bei großen Datenbeständen zu erheblichen Zeit- und Bandbreitenersparnissen führen.

  • Speicherplatzersparnis: Komprimierte Daten benötigen weniger Speicherplatz, was insbesondere bei begrenztem Speicherplatz auf dem Backup-Server vorteilhaft sein kann.

Nachteile der Komprimierung:

  • Verlust des Delta-Transfers: rsync ist besonders effizient, weil es nur die geänderten Teile von Dateien überträgt. Bei der Verwendung von tar wird jedoch immer das komplette Archiv übertragen, was die Übertragung bei häufigen Backups und vielen kleinen Änderungen weniger effizient macht.

  • Zusätzlicher Verarbeitungsschritt: Das Erstellen und Verwalten von Komprimierungsarchiven erfordert zusätzliche Verarbeitung auf dem Remote-Server, was zusätzlichen Aufwand und mögliche Fehlerquellen einführt.

Vor- und Nachteile der Verwendung von rsync

Vorteile von rsync:

  • Effiziente Delta-Übertragung: rsync überträgt nur die Änderungen seit dem letzten Backup, was die Datenübertragung erheblich effizienter macht, insbesondere bei großen Datenmengen und häufigen Backups.

  • Weniger Netzwerkbandbreite erforderlich: Durch die Delta-Übertragung wird nur der geänderte Teil der Daten übertragen, was Bandbreite spart und die Übertragungszeiten verkürzt.

Nachteile von rsync:

  • Keine integrierte Datenkomprimierung: Wenn keine Komprimierung verwendet wird, kann die Übertragung großer Datenmengen länger dauern und mehr Bandbreite beanspruchen.

Backup-Strategien für 24/7-Webseiten und -Dienste

Die oben beschriebene Backup-Methode ist hervorragend für Szenarien geeignet, in denen ein kurzfristiger Ausfall der Dienste akzeptabel ist, da sie erfordert, dass die Docker-Container während der Sicherung gestoppt werden. Für Dienste, die 24/7 verfügbar sein müssen – wie z.B. hochfrequentierte Webseiten oder kritische Unternehmensanwendungen – ist diese Methode jedoch oft nicht praktikabel.

Herausforderungen bei kontinuierlich verfügbaren Diensten:

  • Datenkonsistenz: Die Notwendigkeit, Docker-Container zu stoppen, um konsistente Backups zu gewährleisten, führt zu einem Ausfall der Dienste. Dies ist nicht akzeptabel für Anwendungen, die rund um die Uhr verfügbar sein müssen.

  • Komplexität der Sicherung: Für kontinuierlich verfügbare Dienste sind aufwändigere Backup-Strategien erforderlich, um Datenkonsistenz ohne Unterbrechungen zu gewährleisten.

Alternative Backup-Strategien:

  1. Datenbank-Dumps: Für Datenbanken kann ein regelmäßiger Dump der Datenbank eine gute Lösung sein. Die meisten Datenbanksysteme bieten Funktionen zur Erstellung konsistenter Snapshots, die ohne Unterbrechung der Dienste durchgeführt werden können.

  2. Docker-Volume-Backups: Statt die Container selbst zu stoppen, können Docker-Volumes gesichert werden. Hierbei werden die Daten, die von den Containern verwendet werden, direkt gesichert. Einige Tools ermöglichen es, Volumes konsistent zu sichern, ohne die Container stoppen zu müssen.

  3. Snapshots: Cloud-basierte oder lokale Speicherlösungen, die Snapshot-Funktionen bieten, können ebenfalls verwendet werden. Diese ermöglichen es, zu einem bestimmten Zeitpunkt konsistente Backups zu erstellen, ohne den Dienst zu unterbrechen.

Fazit

Die vorgestellte Backup-Methode bietet eine robuste Lösung für das Sichern von Docker-Containern, insbesondere wenn kurzfristige Dienstunterbrechungen akzeptabel sind. Für kontinuierlich verfügbare Dienste sind jedoch komplexere Backup-Strategien erforderlich, die keine Ausfallzeiten erfordern und konsistente Daten sichern. Die Wahl der besten Backup-Strategie hängt von den spezifischen Anforderungen der Anwendung ab, einschließlich der Notwendigkeit, kontinuierliche Verfügbarkeit zu gewährleisten und die Integrität der gesicherten Daten sicherzustellen.