BTRFS: effettuare automaticamente snapshot e backup remoti

BTRFS

Utilizzo con soddisfazione BTRFS (ne ho parlato nel 2014 e, più recentemente, nel blog IT-Notes). Non lo considero ottimale per tutti i tipi di carico, ma risolve molti problemi in moltissime situazioni. Una delle cose che utilizzo con più soddisfazione è la funzione di generazione dinamica di snapshot, che garantisce la possibilità di avere una copia perfetta e immediata di uno specifico volume (o subvolume). Quando è necessario un backup, ad esempio, l'utilizzo delle snapshot è fondamentale e averle a livello di file system è senza dubbio un buon ausilio.

Quando si tratta di volumi BTRFS, però, abbiamo ulteriori opzioni. Ci sono strumenti nativi che sono in grado di inviare e ricevere dati da e verso volumi BTRFS in maniera ottimizzata, sfruttando le caratteristiche intrinseche del file system stesso. Ecco dunque un metodo per fare automaticamente delle snapshot e trasferirle, in maniera ottimale, su un altro volume BTRFS (locale o remoto).

Da un po' di tempo mi avvalgo di due script interessanti. In passato ho utilizzato snapper ma non l'ho trovato ottimale per il mio utilizzo. Ho dunque continuato ad effettuare ricerche e trovato delle valide alternative, ovvero l'accoppiata di btrfs-snp e btrfs-sync

btrfs-snp

btrfs-snp permette di essere lanciato con un path, un prefisso legato alla snapshot effettuata, il numero massimo di snapshot con quel prefisso da tenere e un tempo minimo tra una snapshot e l'altra.

Ad esempio:

root@foobar:~# /usr/local/sbin/btrfs-snp / hourly  10 3600

Effettuerà una snapshot di /, mettendo come prefisso il termine hourly (ma può essere qualsiasi prefisso), ne terrà massimo 10 e non ne effettuerà altri (ovvero il programma uscirà senza fare azioni) a meno di 3600 secondi dal precedente.

Si possono ovviamente combinare in questo modo, per avere più snapshot di tipo diverso:

/usr/local/sbin/btrfs-snp / hourly  10 3600
/usr/local/sbin/btrfs-snp / daily    3 86400
/usr/local/sbin/btrfs-snp / weekly   1 604800

Può essere lanciato da un cron ogni ora (o ogni quarto d'ora, tanto non effettuerà snapshot a meno di 3600 secondi dal precedente).

btrfs-sync

A questo punto, possiamo copiare su altro file system (locale o remoto) tutte le snapshot grazie a btrfs-sync.

Il comando può essere di questo tipo:

root@foobar:~# /usr/local/sbin/btrfs-sync -d -v /.snapshots btrfs@host:/backups/host01/

Ovviamente il file system di destinazione deve essere un volume BTRFS.

Di solito lancio il comando attraverso uno script nel cron.daily, per avere una copia giornaliera delle snapshot fuori.

Questo tipo di setup mi ha già tolto dai guai più volte e sembra essere efficiente.

Docker: come limitare la crescita incontrollata dei log dei container

(English version, Rotating Docker log files available on IT-Notes blog)

Ho già scritto in merito al fatto che io apprezzi Docker come soluzione per il deploy di specifici servizi. Invece che "sporcare" le singole distribuzioni e dover tenere tutto aggiornato alle versioni delle stesse, si può avere un sistema pulito, replicabile, aggiornabile rapidamente.

Uno dei problemi che ho riscontrato è però questo: quando si hanno dei container che non vengono aggiornati spesso (o, meglio, ricreati spesso), il loro output continua ad accumularsi in un file di log legato al container stesso. Alla fine si rischia di trovarsi con un log enorme e nessuna cognizione di come ridurne le dimensioni.

In un caso specifico, ho avuto un riempimento di disco proprio a causa di uno di questi container (gitlab) che, producendo molto output, aveva creato un json di log di svariate decine di giga in pochi mesi. Facendo una breve ricerca ho trovato la soluzione. E' semplice e Docker supporta, tramite parametri di creazione dei singoli container, la gestione dei log.

Basta dunque passare questi parametri:

--log-opt max-size=50m --log-opt max-file=5

Il container, a quel punto, limiterà il log a 50 mega (limite da definirsi in base alle proprie necessità) ed effettuerà una rotazione dei log stessi (nell'esempio, terrà al massimo 5 log).

In questo modo l'occupazione disco sarà sotto controllo. Perché, dunque, non hanno impostato un limite sano di default? Perché si parte dal presupposto che i container siano usa e getta e che, dunque, vengano spesso buttati e ricreati. La cosa ha una sua logica, ma non è certamente adatta a tutti gli innumerevoli utilizzi.

Nuova disavventura con Tiscali

Arrabbiato

Circa dodici anni fa ho avuto una brutta esperienza con Tiscali. Ne ho parlato e la cosa ha avuto addirittura un seguito, tanto da farmi pensare che non avrei più voluto avere nulla a che fare col gestore in oggetto.

Col passare degli anni, però, ho avuto informazioni da alcuni clienti su come le cose fossero cambiate e la loro soddisfazione mi ha spinto, circa un anno fa, a riflettere. Avendo una linea TIM Business da soli 7 Mbit/sec pagata a peso d'oro, la loro offerta non sembrava così male.

Spinto dunque dalla speranza che fossero davvero migliorati, ho chiesto l'attivazione di una loro linea, subentrando a Telecom. Avendo già Eolo come gestore principale, infatti, la linea ADSL sarebbe servita solo come backup o per gli utilizzi (tipo il Voip) che sopportano male le latenze irregolari e imprevedibili di un ponte radio del genere.

Tutta la procedura, effettuata online, procede correttamente. L'indirizzo risulta attivabile e mi confermano che a breve avrei avuto loro notizie.

Dopo pochi giorni, mi contatta un loro operatore che mi chiede conferma dell'indirizzo per la spedizione del router. Tempo due giorni arriva il router.

E qui inizia il bello

Pochi giorni e arriva una telefonata. C'è un problema e la centrale da il KO al subentro. Dicono che, tecnicamente, l'offerta non sembra essere attivabile in quanto la centrale è satura. Ma come fa ad essere satura se si rimpiazza una connessione esistente? . L'operatore concorda e mi rassicura che sono cose che accadono e che, alla fine, si risolvono.

Nessuna fretta, connessione Telecom lenta e costosa ma stabile.

Passa qualche altro giorno e mi avvisano che poiché Tiscali non ha interessi specifici nelle forniture business, avrebbero passato il contratto a Fastweb che, di fatto, è loro partner. O almeno così dicono. Mi mandano uno stralcio di contratto incompleto con già i miei dati inseriti e chiedono una firma.

Con gentilezza faccio notare che non posso firmare qualcosa che non mi è stato neanche inviato integralmente. Concordano e mi mandano il contratto completo.

Pochi giorni e Fastweb mi manda tutti i dati, compresi username e password di connessione, comunicando che sarebbe a breve stato attivato tutto. Passano settimane... nulla.

Telefono per informazioni, mi dicono che la centrale ha dato KO tecnico e che avrebbero riprovato. Dopo circa un mese, mi comunicano che il servizio non è attivabile e si scusano per avermi fatto perdere tempo.

Ok, penso, "resto coi miei problemi nella speranza che la FTTC arrivi presto" (Ed è accaduto, Telecom ha attivato il 31/12/18).

Dopo un paio di mesi, suonano alla porta. "Sono il Corriere, devo ritirare per conto di Tiscali il router". Senza preavviso, senza appuntamento. Memore di ciò che era accaduto anni fa, avevo tenuto il router ancora chiuso, sigillato, imballato e pronto. Consegno dunque il router al corriere, prendo la ricevuta e, penso, tutto a posto.

Povero illuso...

Arriva Giugno dello scorso anno e vedo un prelievo da conto corrente. Un addebito da parte di Tiscali. Nel frattempo arriva anche la fattura: non hai restituito il router, te lo facciamo pagare.

Telefono subito, inviperito, al loro servizio clienti. Non si meravigliano (succede spesso, quando avviene un ko tecnico) e mi spiegano che devo mandare via fax (!!!) o via messaggio Facebook (!!!) copia della fattura, copia della ricevuta del corriere e una richiesta di rimborso. Contrariato, eseguo, pur chiedendomi se al giorno d'oggi sia il fax lo strumento di comunicazione oppure un "messaggio Facebook".

Passa circa un mese, telefono. Non hanno ricevuto nulla e mi suggeriscono di mandare di nuovo tutto. Incredulo (della mia idiozia nel dare di nuovo fiducia a questa Compagnia) mando tutto di nuovo e chiedo conferma. Stavolta hanno ricevuto la documentazione.

Chiedo dunque il tempo di rimborso. La risposta è esilarante: "Più di un anno, forse un anno e mezzo in quanto abbiamo molte pratiche"

Rido. Rido per non piangere. Inutile dire che ad oggi, dopo più di un anno, non è ancora arrivato un singolo euro di rimborso.

Tutto questo mi fa venire in mente un vecchio proverbio arabo:

La prima volta che m’inganni la colpa è tua, ma la seconda volta la colpa è mia.

Alla Ricerca del Backup Perfetto: Borg e Restic

/images/backup.thumbnail.png

Backup: tecniche principali

In passato ho già affrontato l'argomento backup ponendo alcune basi e dando alcune indicazioni sulle principali modalità e sul perché è fondamentale farlo, sul perché il RAID non può essere considerato una forma di backup e su alcuni software da me presi in esame e utilizzati in precedenza. Invito dunque a leggere l'articolo collegato, per una base di partenza. Questa volta, però, daro delle guide su come io realizzo i backup e su come io riesca a garantire un certo grado di sicurezza.

Backup: le basi di partenza

Proporrò l'argomento sotto forma di elenco puntato, onde coprire le principali problematiche da gestire:

  • Sistema Operativo e dati da salvare: ogni sistema operativo è un universo. E' ragionevole pensare che non esista una soluzione universale, anche se molti dei principali software open source sono multi-piattaforma. Il principale divario è tra i sistemi Unix-Like (GNU/Linux, BSD, MacOS, ecc.) e Windows. Lo stesso software, pur essendo disponibile per più piattaforme, potrebbe non essere il migliore per la propria o per le proprie necessità.
  • Tipo di dati da salvare: ogni tipo di backup richiede soluzioni diverse. Ci sono situazioni in cui si ha la necessità di copie pressoché sempre incrementali in quanto i file crescono ma non vengono modificati. In questo caso, un qualunque sistema appunto incrementale (es: Duplicity ) può essere sufficiente. Nel caso, invece, di backup sempre diversi (es: un database che cambia costantemente), un sistema come quello precedente può essere estremamente inefficiente, specialmente nel lungo periodo.
  • Necessità di crittografia o meno: i backup delle mie fatture, ad esempio, potrei anche evitare di crittarli...
  • Rapidità di esecuzione e di recupero: ci sono strumenti che sono estremamente efficienti nell'effettuare l'operazione di copia, ma che rendono estremamente lento il recupero. Una delle (poche) carenze da me riscontrate in BURP Backup, di cui ho parlato nell'articolo precedente e che utilizzo ancora con successo in certe situazioni, è che richiede il restore dei file e non consente, per lo meno direttamente, di navigare nel backup come fosse un file system locale. Stesso discorso vale, ad esempio, per il backup nativo di Proxmox: è comodissimo da impostare, completo e nativo ma il tempo di recupero può essere importante, specialmente se effettuato in postazioni remote e su connessioni lente. Recuperare un file richiederà, molto spesso, il recupero totale della macchina.
  • Snapshot: ultima in lista, ma questione di primaria importanza. Un backup di un file system "live" avrà un momento di inizio e un momento di fine. Nel frattempo, i dati cambieranno all'interno di esso e potrebbe generarsi incoerenza. In passato ho avuto problemi del genere: un database (mysql) di qualche GB è stato rovinato da un cliente e me ne è stato chiesto il recupero. Ho preso, con baldanza, l'ultimo backup e ho ripristinato i vari file (non un dump). Inutile dire che è stato impossibile farlo ripartire: il file molto grande era cambiato troppo tra l'inizio del backup dello stesso e la fine, per cui era incoerente. Per i maliziosi: avevo anche il dump, ovviamente, per cui ho recuperato quello. Ma la questione resta chiara: fare un backup di un file system live è periocoloso, a meno che non si stia copiando la cartella "Documenti" o "Immagini". Un database aperto, come anche semplicemente quello del browser, ha altissime probabilità di corrompersi e rendere inutile la copia di sicurezza fatta. La tecnica è fare uno snapshot dell'intero file system prima di iniziare la copia. Ci sono margini di rischio anche in questo (il backup avrà all'incirca lo stesso stato che avrebbe la macchina se venisse improvvisamente staccata la spina), ma largamente inferiori. Ad oggi, utilizzando snapshot, sono stato in grado di recuperare tutto.

Backup: Snapshot

Effettuare uno snapshot del file system è importante al fine di avere un backup sufficientemente coerente. Nel tempo ho provato varie soluzioni: Windows ha il suo VSS, su Linux ci sono varie opzioni diverse. Ne elencherò le principali:

  • Snapshot nativo del File System (es: BTRFS o ZFS): se il file system supporta nativamente la possibilità di fare uno snapshot, è opportuno sfruttare questo sistema. Sarà senza dubbio il meno dispendioso e il più corretto, a livello formale.
  • LVM snapshot: se si utilizza LVM, si può chiedere uno snapshot del volume logico, montarlo ed effettuare il backup dello stesso. Bisognerà specificare una dimensione massima di variazione (ovvero quanti dati al massimo il sistema può variare nel tempo di esistenza dello snapshot stesso) e questo spazio dovrà essere parte del VG ma non allocato ad alcun LV. Ci sarà dunque dello spazio sprecato e direttamente proporzionale al working set, ovvero ai dati che vengono maneggiati e scritti in uno specifico lasso di tempo. E' una soluzione che utilizzo ancora ma che mi ha causato alcuni problemi. In determinate circostanze, infatti, il file system si inchioda durante la distruzione dello snapshot, richiedendo un riavvio. Cosa poco carina, per fortuna è capitata di rado ma in situazioni diverse, dunque non imputabili a uno specifico disco/controller/hardware.
  • DattoBD: ho seguito lo sviluppo di questo strumento sin dai suoi albori e ho avuto, nelle primissime versioni, dei problemi che però sono spariti release dopo release. Ha repository per le principali distribuzioni e il funzionamento è ora stabile e, per ciò che ho potuto sperimentare fino ad oggi, sicuro. Per effettuare gli snapshot con Datto utilizzo gli script di UrBackup (altro ottimo sistema di backup che ho utilizzato molto ma che sto ormai usando solo per sistemi Windows), comodi e rapidi.

Backup: push o pull?

Una delle diatribe che da sempre divide gli esperti è proprio quella sulla tipologia di gestione e iniziazione del backup: dovrebbe essere il client a collegarsi al server (push), di fatto "iniziando" il backup, oppure il server a connettersi ai client e "chiedere" il backup (pull)?

A mio avviso, dipende. Nel complesso, tendo ad avere dei sistemi di backup centralizzati su server dedicati che, di conseguenza, tengo in massima sicurezza, facendo girare solo i servizi fondamentali. In alcuni casi, utilizzo Docker per inscatolare l'intero sistema di backup ed evitare il più possibile un coinvolgimento di altri servizi. Proprio per questa ragione tendo a preferire l'approccio "pull", in cui è il server che si collega al client e chiede l'operazione, oppure l'approccio misto del già citato BURP, in cui il client si collega al server che, però, decide se è il momento o meno di fare il backup e ne contingenta l'operazione. Il server, in questo caso, non è dunque uno "stupido" storage, ma un vero e proprio software che svolge la sua funzione.

Purtroppo, però, gli attuali sistemi da me preferiti non supportano questo genere di funzionalità. Ragion per cui ho messo in piedi delle soluzioni alternative che possano in qualche maniera ovviare la situazione.

Prenderò ora in esame i due strumenti che utilizzo maggiormente (insieme al già citato BURP), ovvero Borg Backup e Restic.

Borg Backup

Borg Backup è lo strumento che, da più di un anno, garantisce la sicurezza di quasi tutti i miei backup. Le peculiarità solo:

  • Compressione e deduplicazione dei dati all'interno dello stesso repository
  • Possibilità di effettuare il mount dei backup in una directory, permettendone navigazione, consultazione e ripristino in maniera semplice & comoda
  • Rapido nelle operazioni, genera una cache locale per tenere traccia dei file già copiati e la utilizza per i backup successivi

Addio dunque ai sistemi incrementali, ecc. Borg consente di avere tutti backup deduplicati e compressi come se fossero tutti completi, evitando lente ricostruzioni in fase di consultazione o ripristino.

Ho riscontrato alcuni difetti che, a mio avviso, non sono importantissimi ma è opportuno tenerne conto:

  • Il principale: si consiglia di utilizzare un repository per server in quanto l'operazione di backup è bloccante. Questo implica che la deduplicazione verrà effettuata solo tra "generazioni di backup" e dati dello stesso server. Nel mio caso, che ho centinaia di server "simili" (per OS, configurazioni, ecc.) ci sarà una grossa perdita di spazio. Questo può essere considerato sia un difetto che un pregio (la rottura di un repository sarà limitata a quel repository, non a tutti i backup). Dipende dalle situazioni.
  • Essendo in Python (adoro il Python), impiega qualche secondo a caricarsi ed eseguirsi. Niente di estremo, sia chiaro, ed è rapido e snello nel funzionamento, ma in alcuni casi può essere un po' fastidioso
  • Quando viene effettuato il mount di un repository, lui deve creare degli indici interni per mostrare le directory. Quando i backup cominciano a diventare molti e di molti dati, questa operazione può richiedere anche qualche minuto. Nessun problema se non si ha fretta, ma quando si ha il cliente al telefono e chiede disperatamente di rimettere in piedi un sito o recuperare un documento importantissimo e urgente, quei minuti sono preziosi
  • Anche lui è push, per cui è il client che si collega allo storage per piazzarci i dati. Se lo storage, come nel mio caso, è un server provvisto dell'eseguibile di borg, l'operazione sarà più rapida ed efficace pur girando comunque via ssh

Borg è rapido, efficace e la mia esperienza diretta mi suggerisce che sia sicuro. In molte occasioni sono stato in grado di recuperare server interi, oltre che dati sparsi, in brevissimo tempo e in maniera completa.

Restic

Seguo Restic già da un po', ho fatto esperimenti ma fino ad un po' di tempo fa ho continuato a preferire Borg. Sono due software molto diversi (Restic è scritto in Go) eppure molto simili, sia come approccio che come funzionalità.

Ultimamente, però, le cose stanno prendendo una buona piega per Restic: è diventato molto più rapido e lo sviluppo si sta direzionando verso una delle principali carenze di questo software (alla data odierna): la mancanza di compressione dei dati.

Ecco alcuni vantaggi di Restic:

  • Deduplicazione dei dati anche tra server diversi: Restic, a differenza di Borg, suggerisce l'utilizzo di un unico repository di dati per aumentare la possibilità di deduplicazione anche tra macchine diverse. E' un grosso vantaggio in situazioni, come la mia, in cui ci sono moltissimi server molto simili e ne snellisce anche il primo backup
  • Rapido: i miei test spannometrici dicono sia più rapido di borg, forse perché non comprime
  • Possibilità di effettuare il mount dei backup in una directory, permettendone navigazione, consultazione e ripristino in maniera semplice & comoda. La navigazione è rapida e divisa per snapshot, per host, per tag, rendendo molto semplice l'identificazione del backup richiesto. A differenza di Borg, le strutture vengono create man mano che si naviga all'interno delle directory, rallentando (di un pelo) l'accesso alle stesse ma garantendo prestazioni sempre accettabili.
  • Possibilità di separare le operazioni di "forget" e "prune": alla fine del backup, tendo a far dire al client "ok, butta via i backup più vecchi di..." e lui risponde immediatamente. L'operazione vera e propria di cancellazione verrà poi effettuata successivamente, lanciando il comando "prune". Nel mio caso, questo viene fatto dal server e per tutto il repository (garantendo differenti politiche di tenuta dati in base al server e al cliente), riducendo il tempo effettivo di backup allo stretto indispensabile
  • Community estremanente valida: lo sviluppatore principale, Alexander Neumann è estremamente gentile, cortese e disponibile, nel forum ufficiale, ad aiutare e ricevere feedback e proposte da chiunque.

Restic, come qualunque software, non è perfetto. Ecco alcuni lati negativi che ho riscontrato nell'utilizzo:

  • Mancanza di compressione: a oggi un problema, per me, ma lo sviluppatore ci sta lavorando ed è una feature che arriverà sufficientemente presto
  • Anche Restic è una soluzione push
  • Sembra una banalità, ma nell'uso può essere scomodo: quando si effettua il mount del repository (per navigare nei backup), non viene restituito il prompt ma un messaggio che dice di effettuare l'unmount alla fine dell'operazione. Alias c'è necessità di avere una seconda shell disponibile per entrare nel backup stesso. A volte la cosa può essere frustrante, specialmente se si ha un accesso d'emergenza. Quando me ne ricordo, apro un tmux prima del mount e una seconda shell sotto la prima, per non dimenticare di fare l'unmount alla fine

Esempio: Script utilizzato per effettuare il backup del mio portatile usando Borg e Restic

Passiamo ad un esempio pratico: lo script che utilizzo per effettuare il backup dei miei notebook. In primis, controllo che il computer non stia funzionando a batteria e che il server di backup sia presente (non siamo in una rete diversa o non sia giù per manutenzione). A quel punto, metto un lock ed effettuo uno snapshot utilizzando DattoBD, redirezionando tutto l'output su un file nella directory temporanea:

Borg:

#!/bin/bash
PATH="/usr/local/jdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/pkg/bin:/usr/pkg/sbin"
export PATH
server=192.168.2.254
export server
STATE=`upower -i /org/freedesktop/UPower/devices/battery_BAT0|grep state|grep discharging`
export STATE
if [[ $STATE == *'discharging'* ]]; then
       exit
fi
if nc -w 10 -z $server 22 2>/dev/null; then
echo "$server ✓";
else
echo "$server ✗";
       exit;
fi
if mkdir /tmp/backuphappening; then
  echo "Locking succeeded" >&2
else
  echo "Lock failed - exit" >&2
  exit 1
fi
exec > /tmp/borg_backup_log
exec 2>&1
date;
/usr/local/share/urbackup/dattobd_create_filesystem_snapshot 1 /
REPOSITORY=user@$server:repo
TAG=daily
ionice -c3 borg create -v --progress --compression zlib --stats                          \
    $REPOSITORY::$TAG'-{now:%Y-%m-%dT%H:%M:%S}'          \
    /mnt/urbackup_snaps/ /boot /boot/efi                                       \
    --exclude '*.cache*'                  \
    --exclude '*/home/*/.cache*'                  \
    --exclude '*/home/*/Scaricati*'                  \
    --exclude '*.datto*'                  \
    --exclude '*.overlay*'                  \
    --exclude '*.crdownload'                  \
    --exclude '*.rpm'                  \
    --exclude '*.deb'                  \
    --exclude '*swapfile*'                  \
    --exclude '*/home/*/Virtualbox VMs*'          \
    --exclude '*/home/*/VirtualBox VMs*'          \
    --exclude '*/home/*/.vagrant.d*'              \
    --exclude '*/root/.cache*'                    \
    --exclude '*/var/lib/docker*'                    \
    --exclude '*/tmp'
/usr/local/share/urbackup/dattobd_remove_filesystem_snapshot 1 /mnt/urbackup_snaps/1
borg prune -v $REPOSITORY --stats --prefix $TAG'-' \
    --keep-hourly=12 --keep-daily=60 --keep-weekly=12 --keep-monthly=24
rm -Rf /tmp/backuphappening
date;

Restic:

#!/bin/bash
PATH="/usr/local/jdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/pkg/bin:/usr/pkg/sbin"
export PATH
STATE=`upower -i /org/freedesktop/UPower/devices/battery_BAT0|grep state|grep discharging`
export STATE
if [[ $STATE == *'discharging'* ]]; then
       exit
fi
if nc -w 10 -z $server 22 2>/dev/null; then
echo "$server ✓";
else
echo "$server ✗";
exit;
fi
if mkdir /tmp/backuphappening; then
  echo "Locking succeeded" >&2
else
  echo "Lock failed - exit" >&2
  exit 1
fi
exec > /tmp/restic_backup_log
exec 2>&1
date;
/usr/local/share/urbackup/dattobd_create_filesystem_snapshot 1 /
ionice -c3 restic -r myrepo \
    backup                                     \
    --exclude='*/home/*/.cache*'                  \
    --exclude='*.cache*'                  \
    --exclude='*/home/*/Scaricati*'                  \
    --exclude='*.datto*'                  \
    --exclude='*.overlay*'                  \
    --exclude='*.crdownload'                  \
    --exclude='*.rpm'                  \
    --exclude='*.deb'                  \
    --exclude='*swapfile*'                  \
    --exclude='*/home/*/Virtualbox VMs*'          \
    --exclude='*/home/*/VirtualBox VMs*'          \
    --exclude='*/home/*/.vagrant.d*'              \
    --exclude='*/root/.cache*'                    \
    --exclude='*/var/lib/docker*'                    \
    --exclude='/sys'                    \
    --exclude='/proc'                    \
    --exclude='/dev'                    \
    --exclude='*/tmp'                    \
    --exclude='/run'    \
    /mnt/urbackup_snaps/1/
/usr/local/share/urbackup/dattobd_remove_filesystem_snapshot 1 /mnt/urbackup_snaps/1
restic forget -d 30 -w 8 -m 12 -y 1 --host myhost -r myrepo
rm -Rf /tmp/backuphappening
date;

Lo script di Restic è molto più grezzo, è solo un adattamento di quello di Borg per farlo andare e, come già scritto, non effettua il prune effettivo del repository ma marca solo come "da rimuovere" i backup più vecchi. Consiglio una lettura, almeno superficiale, dei manuali dei due strumenti, in modo da non avere i classici problemi da copia & incolla.

Conclusioni

In questo momento sto utilizzando sia Borg che Restic, il primo come sistema principale, il secondo come "emergente", nel senso che lo sto testando nel dettaglio e promette davvero bene. L'arrivo della compressione potrà, probabilmente, colmare il gap e permettermi di sostituire Borg, grazie alla maggiore efficienza di deduplicazione. In entrambi i casi, di notte effettuo un rsync dell'intero repository su uno storage remoto per avere backup replicati in più posti. E un Jenkins che si occupa di collegarsi alle singole macchine, effettuare il backup e avvisarmi in caso di problemi.

Docker e la nuova separazione dei servizi

Se c'è una cosa che mi piace, nell'ambito informatico, è il trovare nuove soluzioni a vecchi problemi. O nuovi problemi a vecchie soluzioni, ma allo scopo di risolvere eventuali punti lasciati in sospeso da tempo, per mancanza di tempo o per mancanza di soluzioni a disposizione.

Una delle questioni più annose, per chi lavora nel settore (ma non solo) è sempre la vecchia scelta operativa: accentrare i servizi su un server o separarli il più possibile?

Alla domanda non esiste una risposta semplice. Dipende dalle risorse a disposizione, da come uno è abituato a gestire e, nel complesso, da quanto tempo si avrà poi per fare la manutenzione del tutto. Più semplice (e più rischioso) fare manutenzione o aggiornamenti ad un singolo server piuttosto che ad uno stuolo di macchine più piccole.

La mia filosofia, per quanto possibile, è sempre stata similare al concetto principale dei sistemi Unix: K.I.S.S. (ovvero Keep It Simple and Stupid), separazione massima per ottimizzare la resa e frammentare eventuali criticità future. Già nei primi anni 2000 utilizzavo OpenVZ e, successivamente, lxc anche su piccoli server Atom domestici per tenere tutto separato. Un container come file server, un altro come mail server, un altro come media server, un altro come backup server, ecc. Il vantaggio è sempre stato quello di separare il più possibile i servizi e ridurre le possibilità di guai in caso di aggiornamenti fasulli o, peggio, compromissione di una delle macchine.

Ho per questo osservato con interesse (e ne ho già scritto in passato) l'avvento di Docker, anche se inizialmente non ho avuto un grosso impatto emotivo. Non mi piaceva o, per lo meno, lo reputavo estremamente immaturo. Tutto è corso e il risultato è che oggi, finalmente, riesco ad avere la separazione che ho tanto sognato. Non più una macchina virtuale per servizio, ma un contenitore per servizio, con tutte le sue dipendenze all'interno. Un overhead inferiore, un risultato equivalente.

Questo approccio, apparentemente complesso, rende in realtà semplicissima la gestione successiva delle risorse. Non dovendomi preoccupare di non incrociare dipendenze, librerie, distribuzioni, servizi, ecc., sarà semplicemente necessario sapere quali sono le richieste di un contenitore ed, eventualmente, collegarlo ad un altro. Stop, il risultato è presto detto: servizio attivo, isolato, aggiornabile, sicuro. E, non da sottovalutare, migrabile da un server all'altro senza particolari problemi.

Mi è recentemente capitato di dover installare un sito che necessitasse di mysql 5.7 su un server con mysql 5.5. Aggiornare il secondo non l'ho neanche preso in considerazione (preferisco restare fedele ai repository ufficiali della distribuzione), far andare il primo su una versione più vecchia sarebbe stato un hack sporco e inaffidabile. Risultato: ho tirato su un bel container con mysql 5.7 e fatto puntare ad esso il CMS. Ho inoltre potuto installare un bel PhpMyAdmin solo per esso e il tutto è stabile e aggiornabile.

Uno dei vantaggi, inoltre, del setup docker-style è quello di non dover perdere più troppo tempo con la macchina da installare. Il sistema operativo del server che farà girare Docker, infatti, servirà ad interfacciarsi con l'hardware (fisico o virtuale) e a gestire gli eventuali backup. Il risultato è presto detto: semplicità di gestione in quanto il centro del tutto non è più il server, fisico o virtuale, ma il singolo servizio.