Nach mehrmaligem Ändern der der Strategie, was wohl auch in Zukunft noch ein paar mal vorkommen wird, bin ich zu folgender Lösung gelangt.
Wenn ein Raidsystem verwendet wird, deckt man nur gerade ein einzelnes Ausfallszenario ab, nämlich das Ausfallen einer Festplatte. Bei Ausfall einer anderern Komponente im Server, beim Verlust der Daten durch eine Fehlmanipulation oder bei Datenverlust durch einen defekten Diskcontroller hilf ein Raid nicht.
Daher haben wir schon seit längerer Zeit jeweils zwei Server im Einsatz. Ein System ist der produktive Server im Einsatz. Der zweite Rechner wird nur als Datenspiegel verwendet und stellt keine eigenen Dienste zur Verfügung, ist aber für den vollen Einsatz vorbereitet. Zusammen mit den Daten stellt er ein identisches Abbild des produktiven Servers dar.
Die Daten werden nun täglich mit rsync auf das Backupsystem kopiert. Bei Bedarf kann das in bestimmten Bereichen auch mehrmals täglich erfolgen. Da während der Synchronisierung die Rechenlast und die Festplattenauslastung beträchtlich ist, ist es nicht sinnvoll die ganzen Daten während der Arbeitszeit zu kopieren, da sich dies störend im Betrieb bemerkbar macht.
Es wäre deshalb wünschenswert, die Daten ohne grossen Rechenaufwand permanent aktuell zu halten. Dies könnte mit einem Netzwerkraid wie DRDB erfolgen. Einzelne Dienste wie Cyrus, MySQL, Samba und OpenLDAP lassen sich mit Bordmitteln auf mehreren Servern synchron halten.
apt-get install rsync
Damit rsync ohne das Passwort nachzufragen Daten via SSH auf den Backupserver kopieren kann, muss auf diesem der Publickey vom Produktivserver als “vertrauenswürding” hinterlegt werden.
Zuerst für den aktuellen Benutzer, in unsererm Fall root ein RSA-Schlüsselpaar erstellen:
ssh-keygen -t rsa
Jetzt kopiert man den Publickey auf den Backupserver.
scp .ssh/id_rsa.pub backup:/root/
Und fügen ihn auf dem Backupserver zu den authorisierten Schlüsseln hinzu:
cat id_rsa.pub >> .ssh/authorized_keys
Jetzt müssen wir mit einem kleinen Script definieren, welche Verzeichnisse gesichert werden müssen. Da ich das Script mehr als Konfigurationsdatei betrachte, kopiere ich es unter /etc/backup/sync_daily
#!/bin/sh del='--delete' SERVER='backup' rsync -axve ssh $del /var/samba $SERVER:/var/ rsync -ave ssh $del /var/home $SERVER:/var/ rsync -ave ssh $del /var/spool/cyrus/mail $SERVER:/var/spool/cyrus/ rsync -ave ssh $del /var/lib/mysql $SERVER:/var/lib/ rsync -ave ssh $del /var/lib/samba $SERVER:/var/lib/ rsync -ave ssh $del /var/lib/cyrus $SERVER:/var/lib/ rsync -ave ssh $del /var/lib/ldap $SERVER:/var/lib/ rsync -ave ssh $del /var/www $SERVER:/var/ rsync -ave ssh $del /etc $SERVER:/var/mirror/
Der Parameter –delete bestimmt, ob nicht mehr vorhandene Originaldateien auf dem Backupserver auch gelöscht werden sollen oder nicht.
Damit die Sicherung automatisch und regelmässig durchgeführt wird, machen wir noch einen Eintrag für den cron.
/etc/cron.d/backup
5 2 * * * root /etc/backup/sync-daily
Dies bewirkt ein täglicher Aufruf der Scripts um 2:05.
Daten können auch automatisch auf ein USB-Device gesichert werden. Dafür habe ich einen eigenen Abschnitt angelegt.
usbbackup
apt-get install dirvishRsync sichert die Daten zuverlässig. Aber es berücksichtigt den Faktor Mensch noch zu wenig. Die meisten Datenverluste entstehen durch eine Fehlmanipulation durch den Anwender. Wenn eine Datei versehentlich gelöscht wurde, wird ihre Kopie spätestens am nächsten Morgen um 2:05 auch gelöscht. Oder wenn der Inhalt einer Datei so verändert wurde, dass man die Daten nicht mehr verwenden kann, wird die korrekte Datei natürlich auch mit der jetzt zerstörten überschrieben. Meistens bemerkt man solche Vorgänge erst, wenn es bereits zu spät ist.
Um dem zu begegnen habe ich in der Vergangenheit jeweils nach dem Synchronisieren die an diesem Tage veränderten Daten als Differenzsicherung in .tgz Dateien abgelegt. Falls allerding jeweils eine bestimmte Datei wieder gefunden werden musste, gestaltete sich dies als äusserst umständlich.
Hier kommt Dirvish ins Spiel. Dieses Programm erstellt, ebenfalls mit Hilfe von rsync zu definierten Zeitpunkten einen Snapshot der Daten. Das heisst, jeder “Schnappschuss” enthält jeweils alle Dateien, wie sie zu dem entsprechenden Zeitpunkt waren. Wir haben also eine Zeitachse über alle Dateien hinweg und müssen nicht danach suchen. Wir können den Zustand einer Datei zu dem entsprechenden Zeitpunkt auslesen, als die Datei noch integer war.
Durch das klevere Vorgehen von Dirvish werden allerdings nicht alle Daten n-mal aufbewahrt, sondern nur die jeweils geänderten Datein benötigen zusätzlichen Speicherplatz.
Dirvish benötigt eine Bank, also ein Verzeichnis, in welches die Daten gespeichert werden sollen. Zusätzlich benötigt man für jedes zu sichernde Verzeichnis einen Tresor (Vault), ein weiteres Unterverzeichnis mit zugehöriger Konfigurationsdatei.
- /var/backups/dirvish (Bank)
|
-- ./samba (Vault1)
|
-- ./dirvish (Konfiguration)
|
-- ./default.conf (Konfigurationsdatei)
|
-- ./20070323 (Snapshot 1)
|
-- ./20070324 (Snapshot 2)
|
-- ./20070325 (Snapshot 3)
|
-- ./home (Vault2)
|
-- ./dirvish (Konfiguration)
|
-- ./default.conf (Konfigurationsdatei)
|
-- ./20070323 (Snapshot 1)
|
-- ./20070324 (Snapshot 2)
|
-- ./20070325 (Snapshot 3)
Um die Sache noch ein wenig unübersichtlicher zu machen, werden die eigentlichen Daten innerhalb des Snapshots nochmals in ein Unterverzeichnis gepackt. Das macht es ein wenig unübersichtlich, wenn man mehrere Vaults hat. Daher habe ich noch ein Script erstellt, welches mir jeweils nach der Sicherung noch eine Benutzerfreundliche Dateistruktur für jeden Sicherungsvorgang erstellt.
Die Hauptkonfigurationsdatei befindet sich im Verzeichnis /etc/dirvish.
/etc/dirvish/master.conf
bank:
/var/backups/dirvish
exclude:
*~
Runall:
cyrus
etc
home
ldap
mail
mysql
postgrey
root
samba
sambaconf
www
expire-default: +30 days
expire-rule:
# MIN HR DOM MON DOW STRFTIME_FMT
* * 1 * * +1 year
Der Abschnitt bank definiert das Verzeichnis, in dem alle Daten gespeichert werden. Unter “exclude:” können Regeln für den generellen ausschluss von Dateien oder Verzeichnissen angegeben werden.
Danach folgt eine Liste mit allen Vaults, welche regelmässig gesichert werden müssen.
Mit expire-default wird das “Verfalldatum” der Vaults angegeben. Also der Zeitpunkt bestimmt an dem die Daten wieder gelöscht werden. Im Beispiel nach 30 Tagen.
Mit expire-rule kann man noch Ausnahmen für die Löschregel definieren. Hier werden alle Sicherungen vom 1. jeden Monats ein Jahr lang aufbewahrt.
Jetzt folgen noch die genauen Angaben für die einzelnen Vaults. Für jeden Vault existiert eine konfigurationsdatei innerhalb des entsprechenden Verzeichnisses innerhalb der Bank. Damit sind alle Konfigurationsdateien schön verteilt gespeichert. Ich halte das für wenig übersichtlich, daher werden wir alle Konfigurationsdateien unter /etc/dirvish speichern und mit einem Symlink in das jeweilige Verzeichnis linken.
/etc/dirvish/home.conf
client: backup
tree: /var/home
xdev: true
index: gzip
image-default: %Y%m%d
exclude:
*/Cache/*
*/Cache.Trash/*
ln -s /etc/dirvish/home.conf /var/backups/dirvish/home/dirvish/default.conf
Mit client: wird der Herkunftsrechner definiert. Wenn die Sicherung auf dem gleichen Rechner erfolgen soll, ist es wichtig den genauen Namen, welcher mit hostname ermittelt werden kann, zu verwenden. Ansonsten wird auch lokal eine verschlüsselte ssh-Verbindung aufgebaut. Leider kann man hier nicht localhost angeben. Die Entwickler werden wohl schon wissen warum sie das nicht zulassen :(. Es ist zwar einfach innerhalb des Pearlskripts /usr/sbin/dirvish die entsprechende Korrektur selber vorzunehmen. Aber nach einem Update wird die Datei wieder überschrieben und das Backup funktioniert nicht mehr einwandfrei. Daher habe ich mich vorläufig dagegen entschieden.
tree: gibt den Herkunftsort an. Mit xdev: true wird bestimmt, dass beim Sichern das Dateisystem nicht verlassen wird. Das ist wichtig, weil man nie weiss, ob noch Netzwerklaufwerke gemountet sind. Sonst werden diese auch gleich mit eingeschlossen.
index: gzip definiert den Typ der Indexdatei als gezippt.
image-default: bestimmt die Namen der jeweiligen Snapshotverzeichnisse.
exclude: kennen wir schon aus der Masterdatei. Hier trifft der Ausschluss allerdings nur auf das aktuelle Vault zu.
Da wir vorher die Daten schon selber mit rsync auf den Backuprechner kopiert haben, findet die Sicherung nur lokal statt. Wir können leider die Sicherung nicht durch Dirvish erledigen lassen, da die Struktur in der Bank gewahrt werden muss. Daher muss man den zusätzlichen Speicherplatzbedarf für die Bank in Kauf nehmen. Würden sich die Daten nur innerhalb der Bank befinden, könnte man von einem ungeführen Speicherplatzbedarf von 1.5x ausgehen. Da wir aber auch noch die Originalverzeichnise vorliegen haben benötigen wir für alle Daten den 2.5 fachen Speicherplatz. Diese Angaben sind Schätzungen!
Bevor die ersten Snapshots angelegt werden, müssen die Tresore initialisiert werden. Dabei werden alle Daten einmal vollständig in die Vaults kopiert.
/usr/sbin/dirvish --vault home --init
Das muss für jeden Tresor einmal durchgeführt werden.
Um Tresore einfacher anlegen zu können habe ich ein kleinses Skript geschrieben:
#!/bin/bash
confdir="/etc/dirvish"
. /etc/default/corvent
if [ -z $bank ] ; then
bank="/var/backups/dirvish"
fi
if [ -z $3 ] ; then
client=`hostname`
else
client=$3
fi
echo $1 >> $confdir/vaultlist
conf="$confdir/$1.conf"
echo "client: $client" > $conf
echo "tree: $2" >> $conf
echo "xdev: true" >> $conf
echo "index: gzip" >> $conf
echo "image-default: %Y%m%d" >> $conf
echo "#exclude:" >> $conf
echo "# *.tgz" >> $conf
mkdir -p $bank/$1/dirvish
ln -s $conf $bank/$1/dirvish/default.conf
Der Aufruf erfolgt mit ./createvault vault_name src_dir [server]
Wenn der Servername weggelassen wird, findet die Sicherung lokal statt. Der vault-Eintrag innerhalb master.conf muss danach allerding noch von Hand vorgenommen werden.
Eintrag in master.conf automatisch anlegen.
Um die Verzeichnisstruktur angenehmer darzustellen, habe ich ein weiteres Skript erstellt:
#!/bin/bash
base="/var/samba/backup"
. /etc/default/corvent
if [ -z $bank ] ; then
bank="/var/backups/dirvish"
fi
rm -r $base/*
for i in `find $bank/etc -maxdepth 1 -type d -name "2*" -printf "%f\n"` ; do
echo $i
mkdir -p $base/$i
while read v ; do
ln -s $bank/$v/$i/tree $base/$i/$v
done < vaultlist
done
Damit die Sicherung mit Dirvish jeweils nach dem rsync geschieht, muss der cron Eintrag verändert werden:
/etc/cron.d/dirvish
5 3 * * * root /etc/dirvish/backup
Ich setze voraus, dass ein Vault mit dem Namen etc existiert.
Die Sicherung erfolgt also eine Stunde nach dem rsync, welcher vom Server her ausgeführt wird.
Beachte, dass ich auch das Skript ausgewechselt habe, damit ich jeweils auch gleich die lesbare Dateistruktur anlegen kann.
#!/bin/bash /usr/sbin/dirvish-expire --quiet && /usr/sbin/dirvish-runall --quiet rc=$? /etc/dirvish/nicedir exit $rc