Bacula
Baustelle: Dieser Artikel ist eine Baustelle. Das heißt, jemand hat sich dieses Artikels angenommen und überarbeitet ihn gerade. |
Einführung
Bacula ist eine professionelle Backuplösung die mehr und mehr auch in grösseren Firmen benutzt wird. Da ich persönlich leider nur oberflächige Tutorials gefunden habe und dazu auch diese auch immer recht simpel gehalten sind, wollte ich hier ein etwas anderes Tutorial schreiben.
Wir installieren Bacula 2.2.4 (aktuell ist 5.0.1) mit Support für PostgresSQL, werden dort ein 3Clients hinzufügen und anschliessend ein Zeitplan erstellen.
Wenn man sich die Konfigurationsdateien von Bacula anschaut, sehen diese sehr verwirrend undurchsichtig aus, aber der erste Blick täuscht, nach relativ kurzer Einarbeit kann man dort schnell erste Erfolge erzielen.
Vorbereitungen
Als erstes installieren wir die nötigen Pakete:
bacula-director-pgsql bacula-sd-pgsql bacula-console bacula-fd postgresql
normalerweise sollte die Installation ohne Probleme durchlaufen. Während der Installation erstellt Bacula auch gleich die nötige Tabelle Bacula mit den nötigen user bacula. Der Backupserver(bsvr) sollte eine feste IP-Adresse haben und die einzelnen Server die gebackupt werden sollte dies auch haben.
Backupstrategie
Methode1 ist die "Standardmethode" von Bacula, dort legt man sogenannte Pools an in jedem Pool sind mehrere Festplatten.
- Beispiel1:
- 5Festplatten für Inkrementelle Backups
- 5Festplatten für Fullbackups
- 5Festplatten für Differentielle Backups
Bacula schreibt dann ein Pool voll und meckert dann entweder das eine neue Platte hinzugefüggt werden muss, oder man sagt ihm das Bacula dann von vorne anfangen darf zu überschreiben. In meinen Augen hat dies aber den nachteil wenn zum Beispiel bei einem Fullbackup mittlerweile 3Fullbackups auf einer Platte drauf sind (Bsp: die letzten 3Wochen) und diese Platte dann kaputt geht, hat man den Salat, deswegen zieh ich hier Methode 2 vor.
Methode2 diese Methode wird auch im weiteren Verlauf benutzt. Bei dieser Methode kommt pro Werktag eine andere Platte benutzt, dabei wird von Mo-Do ein Inkrementelles Backup geführt und am 1-5Freitag des Monats jeweils ein Freitagsplatte[1-5] benutzt und dann auch noch eine 4Quartalsplatten, dies hat den Vorteil das wenn eine Platte Crasht immer vom Tag davor nehmen kann bzw vom letzten Freitag und so alles auf einen halbwegs aktuellen Stand hat. Ein weiterer Vorteil ist das man die Platten in einem Safe lagern kann, der Nachteil dieser Methode ist aber das der Admin jeden Tag zum Backupserver gehen muss um die Platten zu tauschen, ausser man schliesst alle Platten gleich an.
Festplatten einlesen
Ziel hier ist es die Festplatten "ein zu lesen" für Bacula. Die Festplatte wird eingestöpselt, sie wird erkannt und automatisch ins entsprechende Verzeichnis gemountet. Dies geschieht anhand der UUID und von UDEV.
- Fetplatte entsprechend Formatieren, hier ext3
- mit blkid herausfinden welche UUID die Festplatte/Partition hat
blkid -c /dev/null
- eine UDEV-Regel anlegen und die Daten eintragen. die Regel könne wie folgt aussehen:
#Dienstagsplatte:
ENV(ID_FS_UUID)=="5a31eae6-51f2-438b-90e3-7a2153ccde03", RUN+="/bin/mount /dev/disk/by-uuid/5a31eae6-51f2-438b-90e3-7a2153ccde03 /backup"
#Mittwochsplatte:
ENV(ID_FS_UUID)=="990c7840-4f88-4d54-829f-d6fdf1c474c1", RUN+="/bin/mount /dev/disk/by-uuid/990c7840-4f88-4d54-829f-d6fdf1c474c1 /backup"
#Donnerstagsplatte:
ENV(ID_FS_UUID)=="3383b962-8821-4910-a43e-4f82c0a7d90a", RUN+="/bin/mount /dev/disk/by-uuid/3383b962-8821-4910-a43e-4f82c0a7d90a /backup"
#Freitag3platte:
ENV(ID_FS_UUID)=="8750d5bd-5882-40cf-9240-18bc283cf09f", RUN+="/bin/mount /dev/disk/by-uuid/8750d5bd-5882-40cf-9240-18bc283cf09f /backup"
die Datei heisst 70-backuphdd.rules und wird nach /etc/udev/rules.d/ kopiert.
- Achtung das Verzechnis muss schon existieren!!
- Anschliessend sollte man das ganze probieren und schauen ob es auch funktioniert, falls es nicht geht kann man mit das ganze beobachten wo es hakt bzw ab wann es nicht geht.
udevadm monitor
Konfiguration
Konfigurationsdateien
Die Konfiguraionsdateien befinden sich in /etc/bacula/ die beiden wichtigsten Dateien sind
bacula-dir.conf #Config-datei für den Director (der entscheidet was wann wo und wie zu machen ist) bacula-sd.conf #Config-datei für den Storage-Daemon (dort wird eingestellt wo was gesichert wird)
Es gibt noch 2 andere Configurationsdateien:
bacula-fd.conf #Config-datei für den file-daemon (dieser Überreicht die daten zu dem Server) bconsole.conf #Config-datei ist für die console um bacula zu steuern
Dienstname | Konfigurationsdatei | Beschreibung |
---|---|---|
Director | bacula-dir.conf | Steuert die anderen Daemons von Bacula. Enthält die einzelnen Jobs und die Zeitsteuerung etc |
Storage | bacula-sd.conf] | Organisiert die einzelnen Speichermedien (Tape, Festpplatte, DVD-LW, etc) |
File | bacula-fd.conf | File-Daemon muss auf den zu Sichernden Rechnern istalliert werden, er liefert die Daten aus |
console | bconsole.conf | Einstellungen für die Console von Bacula, man kann dort Bacula steuern, Jobs starten/stoppen, Dateien wiederherstellen etc |
Es gib eine sehr gute englische Dokumentation zu Bacula, diese findet man hier
bacular-dir.conf
Hier erkläre ich die einzelnen Abschnitte der Konfigurationsdatei
Im ersten abschnitt werden allgemeine Angaben zum
Director { # define myself
Name = backupsrv #Name des Directors wird für den FileDaemon gebraucht
DIRport = 9101 # Der Port auf den Bacula lauschen soll
QueryFile = "/etc/bacula/scripts/query.sql" #wird benötigt
WorkingDirectory = "/var/lib/bacula"
PidDirectory = "/var/run/bacula"
Maximum Concurrent Jobs = 1 #wieviel Jobs gleichzeit laufen dürfen, um so mehr es sind umso länger kann die Wiederherstellung dauern
Password = "geheim1" # das Konsolenpassword
Messages = Daemon
DirAddress = 192.168.200.23
}
JobDefs= jobdefault, alle angaben die hier gemacht werden müssen in den anderen Jobs nur dann angegeben werden wenn sie einen anderen Wert bekommen soll, oder man lässt den Wert hier weg, man MUSS ihn aber dort dann später in den einzelnen Jobs angeben
JobDefs {
Name = "DefaultJob"
Type = Backup #welche Art ausgeführt werden soll (Backup, Restore, gibt noch mehr siehe Doku)
Level = Differential #Wie gesichert werden soll (Full, Differential, Incremental, für mehr siehe Doku)
Schedule = "WeeklyCycle" #Welcher Zeitplan genutzt wird
Storage = File #Welches Storage genutzt werden soll
Messages = Standard
Pool = Default #Welcher Pool genutzt werden soll
Priority = 10 #Mit welcher Priorität soll der Job ausgeführt werden (1=hohe Prio; 10=niedrige Prio)
}
hier werden der Übersicht halber die einzelnen Server in eine extra Datei gepackt, wie solche eine Datei aussieht wird später gezeigt
#hier werden die einzelnen configs der server eingebudnen
@/etc/bacula/conf.d/datensrv
@/etc/bacula/conf.d/mailsrv
@/etc/bacula/conf.d/datenbanksrv
@/etc/bacula/conf.d/asterisksrv
hier wird die Datenbank von Bacula gesichert, dies geschieht nach der Hauptsicherung
Job {
Name = "BackupCatalog" #Name des Jobs
JobDefs = "DefaultJob"
Client = "backupsrv" #Wie der Client heisst der gesichert wird, ist frei wählbar
Level = Full
FileSet="Catalog"
Schedule = "WeeklyCycleAfterBackup"
# This creates an ASCII copy of the catalog
# WARNING!!! Passing the password via the command line is insecure.
# see comments in make_catalog_backup for details.
# hier wird die bacula-Datenbank gesichert VOR dem Job gesichert: SKRIPT Datenbankname Benutzername Passwort Server
RunBeforeJob = "/etc/bacula/scripts/make_catalog_backup bacula bacula bacula localhost"
# hier wird die Datenbank/Katalog nach dem Backup wieder gelöscht
RunAfterJob = "/etc/bacula/scripts/delete_catalog_backup"
RunAfterJob = "/bin/umount /backup" #da dies der letzt Job ist, wird danach die Festplatte ungemountet
Write Bootstrap = "/var/lib/bacula/BackupCatalog.bsr"
Priority = 11 # höhere Prio wird also nach den anderen backups ausgeführt
}
Standard Job um Daten wieder her zu stellen
Job {
Name = "RestoreFiles"
Type = Restore
Client=backupsrv #auf welchem Client es wieder her gestellt werden soll
FileSet="Full Set" #Welches Daten wieder her gestellt werden sollen, wird im Fullset genau angegeben
Storage = File
Pool = Default
Messages = Standard
Where = /restore #Wo die Daten wieder her gestellt werden sollen
}
Das Fileset gibt an was alles gesichert werden soll und welche Dateinen/Ordner nicht gesichert werden sollen
FileSet {
Name = "Full Set" #Name des Filesets
Include {
Options {
signature = MD5 #Wie geprüft werden soll ob die Daten korrekt sind
}
File = /home/ #was gesichert werden soll
}
Exclude { #Welche Daten alle nicht gesichert werden sollen
File = /proc
File = /tmp
File = /.journal
File = /.fsck
}
}
Wann die Jobs ausgeführt werden sollen die als Drecktive "WeeklyCycle" drin hat
# die Zeitplanung
Schedule {
Name = "WeeklyCycle" #Name des Schedule, frei wählbar
# Level=wie gesichert werden soll, Pool=welcher FestplattenPool genommen werden soll, wann gesichert wird
Run = Level=Differential Pool=MoPool Monday at 20:10 # es wird Montags um 20:10 gesichert
Run = Level=Differential Pool=DiPool Tuesday at 20:10
Run = Level=Differential Pool=MiPool Wednesday at 20:10
Run = Level=Differential Pool=DoPool Thursday at 20:10
Run = Level=Full Pool=Fr1Pool 1st Friday at 20:10 #es wird jeden 1Freiag des Monats um 20:10 auf Fr1 gesichert
Run = Level=Full Pool=Fr2Pool 2nd Friday at 20:10
Run = Level=Full Pool=Fr3Pool 3rd Friday at 20:10
Run = Level=Full Pool=Fr4Pool 4th Friday at 20:10
#um zusätzlich noch jedes Quartal eine Fullsicherung gemacht werden soll, sieht so aus:
# Run = Level=Full Pool=Quartal1 on jan 1 at 21:00
# Run = Level=Full Pool=Quartal2 on apr 1 at 21:00
# Run = Level=Full Pool=Quartal3 on jul 1 at 21:00
# Run = Level=Full Pool=Quartal4 on oct 1 at 21:00
}
Hier wird der Catalog, also die Bacula-DB, gesichert
# Catalog-backup, wird benoetigt um Daten wieder her zu stellen
Schedule {
Name = "WeeklyCycleAfterBackup"
Run = Level=Differential Pool=MoPool Monday at 20:10
Run = Level=Differential Pool=DiPool Tuesday at 20:10
Run = Level=Differential Pool=MiPool Wednesday at 20:10
Run = Level=Differential Pool=DoPool Thursday at 20:10
Run = Level=Full Pool=Fr1Pool 1st Friday at 20:10
Run = Level=Full Pool=Fr2Pool 2nd Friday at 20:10
Run = Level=Full Pool=Fr3Pool 3rd Friday at 20:10
Run = Level=Full Pool=Fr4Pool 4th Friday at 20:10
}
# This is the backup of the catalog
FileSet {
Name = "Catalog"
Include {
Options {
signature = MD5
}
File = /var/lib/bacula/bacula.sql
}
}
Client {
Name = backupsrv
Address = 192.168.200.23
FDPort = 9102
Catalog = MyCatalog
Password = "geheim1" # password for FileDaemon
File Retention = 30 days # 30 days
Job Retention = 6 months # six months
AutoPrune = yes # Prune expired Jobs/Files
}
Hier wird hinterlegt wie sich der Storage-Daemon und der Director kommunizieren.
Storage {
Name = File
# Do not use "localhost" here
Address = 192.168.200.23 #die IP-Adresse des Bacula-servers
SDPort = 9103
Password = "geheim1"
Device = FileStorage
Media Type = File
}
wie sich bacula mit der DB verbindet um dort die Katalog-daten zu speichern, sollte alles selbst erklärend sein
# Generic catalog service
Catalog {
Name = MyCatalog
dbname = "bacula"; dbuser = "bacula"; dbpassword = "bacula"
}
hier wird angegeben wann mails wohin geschickt werden sollen.
Messages {
Name = Standard
mailcommand = "/usr/lib/bacula/bsmtp -h 192.168.200.11:25 -f \"\(Bacula\) \<%r\>\" -s \"Bacula: %t %e of %c %l\" %r" #hier wird der mail-server(smtp) angegeben, danach absender und betreff, genaueres siehe Doku
operatorcommand = "/usr/lib/bacula/bsmtp -h localhost -f \"\(Bacula\) \<%r\>\" -s \"Bacula: Intervention needed for %j\" %r"
mail = ICH@meine-email.de = warning, error, fatal, mount, alert, security, notsaved, !terminate !skipped #email-adresse wo es hingehen soll, genauso welche meldungen hingehen sollen und welche nicht, mit ! gekennzeichnet
operator = root@localhost = mount
console = all, !skipped, !saved
append = "/var/lib/bacula/log" = all, !skipped #was alles wo geloggt werden soll
}
# Message delivery for daemon messages (no job).
Messages {
Name = Daemon
mailcommand = "/usr/lib/bacula/bsmtp -h localhost -f \"\(Bacula\) \<%r\>\" -s \"Bacula daemon message\" %r"
# mail = root@localhost = all, !skipped
mail = ICH@meine-email.de = warning, error, fatal, mount, alert, security, notsaved, !terminate !skipped
console = all, !skipped, !saved
append = "/var/lib/bacula/log" = all, !skipped
}
Hier kommen die einzelnen Pools
Pool {
Name = Default
Pool Type = Backup
Recycle = yes # Bacula can automatically recycle Volumes
AutoPrune = yes # Prune expired volumes
Volume Retention = 365 days # one year
}
Pool {
Name = MoPool #name des pools
Pool Type = Backup #welche Art des Pools, momentan gibts nur Backup, mehr Infos siehe Doku
Recycle = yes
AutoPrune = yes
Volume Retention = 6d #wie lange Bacula die Daten in der Datenbank hält, hier 6tage
Maximum Volume Jobs = 0 #wieviel Jobs auf das Laufwerk geschrieben werden 0=unendlich
}
Pool {
Name = DiPool
Pool Type = Backup
Recycle = yes
AutoPrune = yes
Volume Retention = 6d
Maximum Volume Jobs = 0
}
Pool {
Name = MiPool
Pool Type = Backup
Recycle = yes
AutoPrune = yes
Volume Retention = 6d
Maximum Volume Jobs = 0
}
Pool {
Name = DoPool
Pool Type = Backup
Recycle = yes
AutoPrune = yes
Volume Retention = 6d
Maximum Volume Jobs = 0
}
Pool {
Name = Fr1Pool
Pool Type = Backup
Recycle = yes
AutoPrune = yes
Volume Retention = 6d
Maximum Volume Jobs = 0
}
Pool {
Name = Fr2Pool
Pool Type = Backup
Recycle = yes
AutoPrune = yes
Volume Retention = 27d
Maximum Volume Jobs = 0
}
Pool {
Name = Fr3Pool
Pool Type = Backup
Recycle = yes
AutoPrune = yes
Volume Retention = 27d
Maximum Volume Jobs = 0
}
Pool {
Name = Fr4Pool
Pool Type = Backup
Recycle = yes
AutoPrune = yes
Volume Retention = 27d
Maximum Volume Jobs = 0
}
# Scratch pool definition
Pool { #wenn kein Pool gefunden wird für den Einsatz, dann wird in den Scratch-pool geschrieben
Name = Scratch
Pool Type = Backup
}
wird gebraucht damit die konsole oder der tray-monitor sicher verbinden kann.
Console {
Name = backupsrv
Password = "geheim1"
CommandACL = status, .status
}
bacula-sd.conf
Im Storage-Daemon wird eingestellt auf was wie zugegriffen wird. Ob Festplatte, DVD, Tape etc., kann hier angegeben werden.
hier gibts eigentlich nichts neues zu beschreiben:
Storage { # definition of myself
Name = backupsrv-sd
SDPort = 9103 # Director's port
WorkingDirectory = "/var/lib/bacula"
Pid Directory = "/var/run/bacula"
Maximum Concurrent Jobs = 20
SDAddress = 192.168.200.23
}
hier werden die Daten zum Direktor angegeben, damit er sich verbinden kann
Director {
Name = backupsrv
Password = "geheim1"
}
#für den Tray-monitor und Statusabfragen
Director {
Name = backupsrv-mon
Password = "geheim1"
Monitor = yes
}
hier kommen wir zur Device-recource, hier wird angegeben was für ein typ es ist, wo gegebenenfalls was gespeichert werden soll, ob es autoamtisch wechselt, etc..
Device {
Name = FileStorage #frei wählbar, aber muss dann im bacual-dir.conf auch so genannt werden
Media Type = File #auf was/wie bacula speichern sollen(Tape, file, DVD, fifo)
Archive Device = /backup #bei File= muss angegeben werden WO gespeichert werden soll
LabelMedia = yes; #Bacula erstellt automatisch labels für ungelabelte Medien
Random Access = Yes; #yes=dvd, festplatten; no=tapes
AutomaticMount = yes; #ob es autoamtisch mountet
RemovableMedia = yes; #ob es ein wechselmedium ist
AlwaysOpen = no; #ob es immer verfügbar ist
Unmount Command = "/bin/umount %a"; #selbsterklärend
}
es folgen viele beispiele für diverse varianten, hab ich aber ausgeblendet
[...]
hier was alles geloggt werden soll
Messages {
Name = Standard
director = backupsrv-dir = all
}
bacula-fd.conf
Der Client bzw Filedaemon muss auf jeden Rechner installiert werden der gesichert werden soll, ausser man sichert über smb-shares.
erstmal wieder zum verbinden, also nichts neues
Director {
Name = backupsrv
Password = "geheim1"
}
Director {
Name = backupsrv-mon
Password = "geheim1"
Monitor = yes
}
und auch hier nicht wirklich nichts neues
FileDaemon {
Name = backupsrv-fd #der Name des filedaemons
FDport = 9102 # der Port auf den man die Befehle vom Director wartet
WorkingDirectory = /var/lib/bacula
Pid Directory = /var/run/bacula
Maximum Concurrent Jobs = 20 #maximal gleichzeitige Jobs
FDAddress = 192.168.200.23 #IP des Clients
}
# Send all messages except skipped files back to Director
Messages {
Name = Standard
director = backupsrv-dir = all, !skipped, !restored
}