I noen år nå har jeg kjørt duplicity backup både på servesystemer og klienter. Dette har virket bra, men har det samme problemet som all annen inkrementell filbackup: Før eller siden må du ta ny full backup for at det ikke skal bli for tungt å kjøre restore. Med mye data trenger du da relativt mye lagringsplass, og en del av skyleverandørene operer med «retention time», dvs. at du må betale for brukt diskplass i et minimum antall dager.
Med overgang til ny server som nevnt i forrige blogg-innlegg, begynte jeg å se på nye backupsystemer også – spesielt siden zfs har mye innebygget snacks som snapshots, zfs send etc, og kan sende inkrementell backup av volumene f.eks. til https://rsync.net/. Dette var fristende – men jeg ville ha en backupløsning som virket både på klienter og servere, og ikke var helt avhengig av zfs.
Her forleden dag fant jeg Borg backup.
Jeg ble litt frelst, bl.a fordi:
- Enhver backup er likeverdig, alle backuper er fulle backuper.
- Deduplisering med checksummer på klientsiden gjør at diskforbruk og båndbreddebehov etter den første backupen blir minimalt.
- Klienter fantes til mine relevante klientplattformer, som alle er unix-baserte. Windows er litt mer komplisert, men det er ikke en aktuell problemstilling for meg.
På min Mac var saken grei: En backup av data-disken var alt som holdt. En av Borg sine kule features: At du kan montere backupen som et remote filsystem, var litt mer komplisert fordi det krever en custom kjernemodul for FUSE. Sikkerhetsinnstillingene på iallefall nyere MacOS gjør at du ikke uten videre kan installere slikt selv som root, og du må boote i sikker modus for å tillate kjernemodulene. Det kan høres skummelt ut, men det gikk ganske greit.
Jeg valgte å bruke borgmatic som rammeverk rundt borg, fordi det forenkler en del operasjoner. Det finnes også en GUI-klient som heter Vorta – men den har jeg ikke prøvd, da jeg er mer kommandolinjemenneske enn gui-menneske.
En av ulempene med Borg er dog at du må bruke ssh for kommunikasjonen, og det begrenser antall leverandører. Du kan bruke rsync.net, men med mitt plassbehov (mer enn 1 TB og økende), ble det ganske kostbart.
En annen leverandør jeg fant heter https://www.borgbase.com/ -her har jeg valgt en plan som gir meg 1TB for $80 i året, og $0.007 per GB per måned for overskytende data. Neste plan er 2TB til $150 i året, og $0.005 per overskytende GB per måned. Det er fremdeles litt data igjen før denne vil lønne seg for meg, og man kan oppgradere når som helst.
Jeg har valgt å lage et repository for hver klientmaskin. Borgbase har en utmerket guide for å lage/sette opp repositories, og gir deg tilogme en borgmatic-template for hvert repository slik at du har et utmerket startpunkt å bygge videre på.
For Macen ser borgmatic-config slik ut (hemmelige data skjult). Som alle andre løsninger sliter man litt med at hemmeligheter må hardkodes et eller annet sted, men på min personlige Mac valgte jeg å se vekk fra dette:
location: source_directories: - /System/Volumes/Data repositories: - *******@********.repo.borgbase.com:repo exclude_patterns: - /System/Volumes/Data/Volumes/ - /System/Volumes/Data/private exclude_if_present: .nobackup storage: compression: auto,lz4 encryption_passphrase: ******* ssh_command: ssh -i /path/to/ssh-key archive_name_format: 'Mac-{now:%Y-%m-%d-%H%M%S}' retention: keep_daily: 3 keep_weekly: 4 keep_monthly: 12 keep_yearly: 2 prefix: 'Mac-' consistency: checks: # Uncomment to always do integrity checks. # (takes long time for larger repos) #- repository - disabled check_last: 3 prefix: 'Mac-' hooks: # Shell commands to execute before or after a backup before_backup: - echo "`date` - Starting backup" after_backup: - echo "`date` - Finished backup"
Med dette oppsettet (etter at repoer er laget), blir en backup kun en enkel kommando, borgmatic, som kan kjøres i cron. Andre operasjoner gjøres med enkle kommandor som f.eks. borgmatic list, borgmatic prune, etc.
En borgmatic info på Macen gir meg i skrivende stund:
------------------------------------------------------------------------------ Original size Compressed size Deduplicated size All archives: 1.28 TB 907.06 GB 254.45 GB Unique chunks Total chunks Chunk index: 945385 4257703
Dette er fordelt på 3 backup-runs, så jeg har ca 400 GB med data å ta backup av – som vist over utgjør det per nå 254 GB lagringsplass hos leverandøren. Den første backupen tok ca. 8 timer – de neste er unnagjort på ikke fryktelig mange minuttene, men selvsagt mye lenger tid hvis det er mye endringer.
På serveren i skyen har jeg et tilsvarende ukomplisert oppsett. Det var på NAS/server-boksen at det ble moro.
I et tidligere innlegg har jeg skrevet om hvordan boksen ble til, og at jeg har valgt ZFS som filsystem. Dette gjør at det etterhvert blir noen logiske volumer, fordi de er dynamiske og lever sammen i samme pool, og er utrolig enkle å håndtere.
En av tingene zfs gjør bra er f.eks. snapshots. Det å opprette, lage, montere og slette snapshots er noe du knapt tenker over, det er lurt å gjøre det til en ryggmargsrefleks å lage et snapshot før du skal gjøre noe seriøst. Et snapshot har også den fordelen at det er atomisk, og det er en seriøs fordel når man skal ta backup. Mye filer hører jo egentlig logisk sammen, og at de er tatt backup av på forskjellig tidspunkt kan være svært uheldig. Dette unngår du hvis du tar backup fra et snapshot.
Jeg har også et rot-volum som ikke er ZFS men LVM, og LVM har også snapshots – så jeg gjør det samme med rotfilsystemet.
location: source_directories: - /backup/*/ - /backup_lvm/*/ - /boot/ repositories: - ******@******.repo.borgbase.com:repo exclude_patterns: - /proc/ - /sys/ - /tmp/ - /var/tmp/ - /run/ - /backup_lvm/*/tmp/ - /backup_lvm/*/var/tmp/ - /backup_lvm/*/run/ - /backup_lvm/*/root/.cache/ - /backup_lvm/*/var/lib/docker/overlay2/ exclude_if_present: .nobackup storage: compression: auto,lz4 encryption_passphrase: ******* ssh_command: ssh -t -i /path/to/ssh-key archive_name_format: 'hassio-{now:%Y-%m-%d-%H%M%S}' retention: keep_daily: 7 keep_weekly: 4 keep_monthly: 12 keep_yearly: 2 prefix: 'hassio-' consistency: checks: # Uncomment to always do integrity checks. # (takes long time for larger repos) # - repository - disabled # check_last: 3 prefix: 'hassio-' hooks: # Shell commands to execute before or after a backup before_backup: - echo "`date` - Starting backup" ;snapname='backup'-`date +%Y-%-m-%d-%H%M`;zfs snapshot -r nasdisk@$snapname;zfs snapshot -r znvm@$snapname;for i in `zfs list -t snapshot|grep $snapname|awk '{print $1}'`;do backup=`zfs get -H borg:backup $i|awk '{print $3}'`; if [ "$backup" = "yes" ]; then fs=`echo $i|sed -e "s/\@$snapname//"`;mp=`zfs get -H mountpoint $fs|awk '{print $3}'`;linkname=`echo $fs|sed -e "s/\//_/g"`;mkdir /backup/$linkname;mount -t zfs $i /backup/$linkname;else zfs destroy $i;fi;done - lvs --noheadings --select 'lv_tags=backup'| while read -r lv vg rest; do which lvcreate;echo lvcreate -L1G --snapshot -n ${lv}_snap /dev/$vg/$lv;lvcreate -L10G --snapshot -n ${lv}_snap /dev/$vg/$lv;mkdir -p /backup_lvm/${lv}_snap;mount /dev/$vg/${lv}_snap /backup_lvm/${lv}_snap/;mount | grep backup_lvm;done after_backup: - for i in /backup/*;do umount $i;rmdir $i;done - echo $snapname - for i in `zfs list -t snapshot|grep @backup-20|awk '{print $1}'`; do zfs destroy $i;done - for i in /backup_lvm/*; do umount $i;rmdir $i;done - lvs --noheadings --select 'lv_tags=backup'| while read -r lv vg rest; do lvremove -f /dev/$vg/${lv}_snap;done - echo "`date` - Finished backup"
Den virkelige moroa ligger i before_backup og after_backup.
Jeg har to zpools, nasdisk og znvm. nasdisk er redundant, znvm er ikke, det er den interne SSDen. Jeg bruker det for data som skal aksesseres hyppig, og hvor hastighet spiller stor rolle. Men manglende redundans er jo litt nedtur. Nå er ikke serveren min så kritisk, men likevel er jeg paranoid. Derfor satte jeg opp en jobb med sanoid som syncer dem hver time til et tilsvarende volum på nasdisken som har redundans. Det er likevel unødvendig å ta backup av begge – selv om dedupliseringen . I tillegg har jeg noen andre volumer som kanskje ikke er interessant å ta backup av – selv om dedupliseringen gjør at det ikke er kritisk, tids- eller plassmesig.
Jeg har valgt å lage en property, borg:backup=yes, på zfs-filsystemene det skal taes backup av. Denne har jeg lagt på zpoolen slik at nye filsystemer automatisk vil taes backup av, og så overstyrer jeg det med borg:backup=no på de filsystemene jeg ikke vil ta backup av. En zfs -r snapshot nasdisk@<navn> lager et snapshot med samme navn på alle volumene i poolen, og så løper jeg igjennom filsystemene i en loop og monterer de jeg vil ta backup av under /backup/ – og sletter de andre snapshotene.
For LVM blir det tilsvarende, jeg setter en tag backup og tar snapshot og monterer alle volumer med denne tagen under /backup_lvm/.
Selve backupen tar jeg av filsystemene /backup, /backup_lvm og /boot. Da får jeg automatisk bort en del irrelevante ting som /proc og /sys, og andre ting man ikke ønsker å ta backup av.
Etter endt backup avmonterer jeg og sletter alle snapshoter.
NAS-boksens initielle backup, med litt over 1 TB data, tok 12 timer. Nattens backup? 4 minutter og 7 sekunder!
For ordens skyld – her er informasjonen fra NAS-boksen sitt repo:
------------------------------------------------------------------------------ Original size Compressed size Deduplicated size All archives: 3.37 TB 3.20 TB 1.04 TB Unique chunks Total chunks Chunk index: 1008300 3913748
Nå har jeg snakket om backup. Et gammelt ordtak sier at backup er lett, det er restore som er vanskelig. Borg-backuper kan monteres, så kan jeg se på innholdet som jeg vil, og kopiere ut det jeg trenger. Du kan også restore med en borgmatic extract.
root@hassio:~# borgmatic mount --mount-point=/mnt
root@hassio:~# cd /mnt
root@hassio:/mnt# ls
hassio-2021-11-23-225804 hassio-2021-11-24-221404 hassio-2021-11-25-010037
root@hassio:/mnt# ls hassio-2021-11-25-010037
backup backup_lvm boot
root@hassio:/mnt# ls hassio-2021-11-25-010037/*
hassio-2021-11-25-010037/backup:
nasdisk nasdisk_docker_volumes_nextcloud_nextcloud nasdisk_home znvm_nextcloud_db
nasdisk_anita nasdisk_docker_volumes_wordpress_database nasdisk_photos znvm_plex_database
nasdisk_cecilie nasdisk_docker_volumes_wordpress_database_vegard nasdisk_storage
nasdisk_docker_volumes nasdisk_docker_volumes_wordpress_html nasdisk_vegard
nasdisk_docker_volumes_calibreweb_config nasdisk_docker_volumes_wordpress_html_vegard znvm
hassio-2021-11-25-010037/backup_lvm:
ubuntu-lv_snap
hassio-2021-11-25-010037/boot:
System.map-5.4.0-88-generic config-5.4.0-89-generic initrd.img initrd.img.old vmlinuz-5.4.0-89-generic
System.map-5.4.0-89-generic config-5.4.0-90-generic initrd.img-5.4.0-88-generic lost+found vmlinuz-5.4.0-90-generic
System.map-5.4.0-90-generic efi initrd.img-5.4.0-89-generic vmlinuz vmlinuz.old
config-5.4.0-88-generic grub initrd.img-5.4.0-90-generic vmlinuz-5.4.0-88-generic
Det er lett å bli glad i Borg. Det finnes et ganske likt system, som heter restic. Dette har fordelen at det kan kjøre mot flere typer backends. Jeg har ikke sett på og sammenlignet dette.
Så, hva har jeg oppnådd med alt dette?
- Fulle backuper gir lettere restores.