Gérer ses backups avec Borg
Lecture 10 min. âą
Table des matiĂšres
Gérer ses backups

Bonjour Ă toutes et tous đ
Aujourdâhui les bases de lâadmin sys.
Pour ceux qui verront cet article dans un certain temps, un datacenter OVH a brûlé dans la nuit du 10 mars 2021.
Jâai Ă©tĂ© effarĂ© de voir le nombre dâentreprises qui pleuraient sur twitter quâils avaient dĂ©finitivement perdu leur donnĂ©es.
Lorsque jâapprenais les rudiments de lâinformatique, mon mentor mâa posĂ© une simple question qui a hantĂ© mes nuits pendant un certain temps (oui mon sommeil est assez agitĂ© đŁ)
Quâest ce que tu fais si je fous un coup de masse dans le serveur de prod et quâon passe dans 1h Ă Capital sur M6.
(oui câest vieux 2016, peut-ĂȘtre đ)
De cette simple phrase une multitude de choses en est ressorti.
Jâai appris Ă faire du Puppet, puis du Ansible pour remonter nâimporte quel service automatiquement sur une machine neuve.
Mais un service sans données ça sert à rien. Sauf que le coup de masse, il a surement chatouillé les disques durs, et donc les données des services.
Alors que faire ?
La rĂ©ponse est simple et connu depuis lâaube de lâinformatique : faire des backups !!!
Je vous propose de vous montrer ma stratĂ©gie de backups que jâai mis en place au cours des annĂ©es et qui a bien entendu Ă©voluĂ©e au fil du temps.
Et bien allons y đ
Installer Borg
Il existe une quantité de projets permettant de réaliser des backups.
Jâai choisis arbitrairement le projet Borg, jâĂ©tais dans ma pĂ©riode vieux Startrek đ, le projet est gratuit efficace et je nâai jamais eu Ă mâen plaindre.
Si un jour je trouve mieux je referai surement un article dessus.
On vĂ©rifie que câest bien installĂ©
# borg -V
Créer notre premier backup
Il va nous falloir des donnĂ©es, je vous propose ce jeu dâimages.
http://images.cocodataset.org/zips/val2017.zip
Ne vous inquiĂ©tez pas il est pas vĂ©rolĂ©, jâai vĂ©rifiĂ© đ
Avant de pouvoir crĂ©er une backup il nous faut un repository. Son rĂŽle va ĂȘtre dâindexer lâhistorique de backups et leur intĂ©gritĂ© ( checksum ).
Il est possible de crĂ©er un repository Ă distance ou sur un disque externe, mais pour les besoins de simplicitĂ© de lâarticle, je vais crĂ©er mon backup en local.
Cette commande initialise un nouveau repository. Le paramĂštre âencryption=repokey dĂ©fini lâalgorithme utilisĂ© pour chiffrer votre repository.
On dézippe notre archive pour avoir plein de fichiers à backuper :D
Puis on créé notre premier backup
--compression=lz4: algorithme de compression des données/opt/backups: chemin du repository::1: nom du backupval2017: dossier à backuper
On aurait pu mettre plus dâun dossier Ă backuper avec la mĂȘme commande.
Borg va vous redemander le mot de passe que vous avez entrĂ© Ă la crĂ©ation du repository ( jâespĂšre que vous lâavez toujours đ )
Pour visualiser notre backup on peut lancer la commande
# borg list /opt/backups
Enter passphrase for key /opt/backups:
1 Thu, 2021-03-11 20:12:23 [7c19bd1f9bc96c1b3aa8d2d0ef586883d8cf3ae127fb750ea02bde88c747ec59]
Et pour avoir les info dâun backup en particulier
# borg info /opt/backups::1
Enter passphrase for key /opt/backups:
Archive name: 1
Archive fingerprint: 7c19bd1f9bc96c1b3aa8d2d0ef586883d8cf3ae127fb750ea02bde88c747ec59
Comment:
Hostname: backup
Username: root
Time (start): Thu, 2021-03-11 20:12:23
Time (end): Thu, 2021-03-11 20:12:37
Duration: 13.54 seconds
Number of files: 5000
Command line: /usr/bin/borg create --compression=lz4 /opt/backups::1 val2017
Utilization of maximum supported archive size: 0%
------------------------------------------------------------------------------
Original size Compressed size Deduplicated size
This archive: 814.71 MB 813.18 MB 813.57 MB
All archives: 815.68 MB 813.57 MB 813.57 MB
Unique chunks Total chunks
Chunk index: 5011 5011
Grùce à cette commande on peut voir le poids des fichiers présents dans le backup.
On va maintenant rajouter du contenu Ă notre dossier val2017
On créé une nouvelle version de backup
borg create --compression=lz4 /opt/backups::2 val2017
On peut aller voir les fichiers contenu dans les backups.
Regardons notre premier backup et voyons si on peut récupérer le fichier test.
# borg list /opt/backups::1 | grep text
Enter passphrase for key /opt/backups:
Il nây est pas pas et câest bien normal, il nâexistait pas quand on a rĂ©alisĂ© notre premier backup.
Regardons dans la deuxiĂšme version du backup
# borg list /opt/backups::2 | grep text
Enter passphrase for key /opt/backups:
-rw-r--r-- root root 7 Thu, 2021-03-11 21:34:17 val2017/text
Cette fois ci câest bon đ
Essayons dâextraire ce fichier
CrĂ©ons dâabord un dossier de travail et rendons-nous-y.
&&
Puis on extrait notre fichier
borg extract /opt/backups::2 val2017/text
On réalise un diff, pour vérifier la cohérence des données sauvegardées
Aucune diffĂ©rence, cela signifie que le backup câest bien rĂ©alisĂ© et que son extraction aussi. đ
Rajoutons des nouvelles données
# echo "line 2" >> ../val2017/text
# diff val2017/text ../val2017/text
1a2
> line 2
Cette fois ci on a bien une différence
Revenons dans le dossier parent de work
Puis on créé une version de backup
# borg create --stats --compression=lz4 /opt/backups::3 val2017
)
)
En rajoutant le flag --stats on peut voir que la taille des fichiers modifié, ici 801 B. Ce qui explique la rapidité de backup. Seul les données modifiées sont prise en compte.
On va le faire plusieurs fois pour se simuler divers runs de backups
# echo "line 3" >> val2017/text
# borg create --compression=lz4 /opt/backups::4 val2017
# echo "line 4" >> val2017/text
# borg create --compression=lz4 /opt/backups::5 val2017
# echo "line 5" >> val2017/text
# borg create --compression=lz4 /opt/backups::6 val2017
Si on liste les backup présents vous devriez avoir quelque chose qui ressemble à cela.
# borg list /opt/backups
1 Fri, 2021-03-12 09:37:06 [bf2669e900d0f32bd058681a796882d0aef71e48f0f76487f43424400652cf61]
2 Fri, 2021-03-12 09:37:55 [622988ce6989ef681c59ca5a1dd3c446995bf44c1f6838f2a431277c7e411935]
3 Fri, 2021-03-12 09:38:45 [b1039973a9e7501670e4b15a30e0cbf20a3fc63bd34a20e35e723219a8ac3e68]
4 Fri, 2021-03-12 09:47:34 [5b13478ff317eca07e870a282864095e1c476a5459ec98c43fc9bfa1462e6067]
5 Fri, 2021-03-12 09:47:49 [d26a226f8b5374d4f3cbc1925ee2ef970e2ca05d81d7f5a2817bb06ec7f4a1e2]
6 Fri, 2021-03-12 09:48:15 [3762d2eebd9670a01d3f3334d6d9be985735973f52db3104b1e1eb7adb5cfc27]
Bien essayons dâextraire notre backup en revision 3 et 6.
# borg extract --stdout /opt/backups::3 val2017/text > text.3
# borg extract --stdout /opt/backups::6 val2017/text > text.6
Si on fait le diff
# diff text.3 text.6
2a3,5
> line 3
> line 4
> line 5
Et si je supprime le backup de la version 3, il se passe quoi pour la version 6 ?
# borg delete /opt/backups::3
# borg list /opt/backups
1 Fri, 2021-03-12 09:37:06 [bf2669e900d0f32bd058681a796882d0aef71e48f0f76487f43424400652cf61]
2 Fri, 2021-03-12 09:37:55 [622988ce6989ef681c59ca5a1dd3c446995bf44c1f6838f2a431277c7e411935]
4 Fri, 2021-03-12 09:47:34 [5b13478ff317eca07e870a282864095e1c476a5459ec98c43fc9bfa1462e6067]
5 Fri, 2021-03-12 09:47:49 [d26a226f8b5374d4f3cbc1925ee2ef970e2ca05d81d7f5a2817bb06ec7f4a1e2]
6 Fri, 2021-03-12 09:48:15 [3762d2eebd9670a01d3f3334d6d9be985735973f52db3104b1e1eb7adb5cfc27]
Notre version 3 est bien supprimé.
Quand est-il de la version 6. Est-elle corrompu ?
Essayons
# borg extract --stdout /opt/backups::6 val2017/text > text.6.2
Si on fait un diff:
# diff text.6 text.6.2
Aucune diffĂ©rence, ce qui signifie que lâon peut supprimer des vieilles versions de backups sans que cela nâinflue sur les backups prĂ©cĂ©dants.
On va tirer profit de cette particularité pour se débarasser des vieux backup qui polluent le disque.
borg prune --keep-last 3 /opt/backups
Si on liste les backups:
# borg list /opt/backups
4 Fri, 2021-03-12 09:47:34 [5b13478ff317eca07e870a282864095e1c476a5459ec98c43fc9bfa1462e6067]
5 Fri, 2021-03-12 09:47:49 [d26a226f8b5374d4f3cbc1925ee2ef970e2ca05d81d7f5a2817bb06ec7f4a1e2]
6 Fri, 2021-03-12 09:48:15 [3762d2eebd9670a01d3f3334d6d9be985735973f52db3104b1e1eb7adb5cfc27]
On a plus que nos 3 backups ( les plus récents ).
Exporter les backups
Il est possible dâexporter un backup sous la forme dâune archive.
borg export-tar --tar-filter="gzip -9" /opt/backups::6 backup.6.tar.gz
Puis on vĂ©rifie que lâarchive contient bien ce quâil faut
# tar -axf backup.6.tar.gz val2017/text -O
line 1
line 2
line 3
line 4
line 5
Notre archive contient bien ce que lâon veut. :D
Automatisation du process de backup
Borg est sympathique mais est un peu trop manuel Ă mon goĂ»t câest la raison pour laquelle nous allons rajouter une couche dâautomatisation sous la forme dâun projet python appelĂ© borgmatic.
Son rĂŽle est de gĂ©rer la configuration du backup et dâautomatiser les tĂąches dâavant et aprĂšs backup comme le montage de disque ou lâĂ©xĂ©cution de borg prune pour nettoyer les anciens backups ou chaĂźner dâautres opĂ©rations.
En parlant de configuration borgmatic est fourni avec un générateur.
generate-borgmatic-config
Celle ci va créer le fichier /etc/borgmatic/config.yml
Il faut modifier quelques lignes:
location:
source_directories:
- /root/val2017
repositories:
- /opt/backups
storage:
encryption_passphrase: "test"
archive_name_format: '{hostname}-backups-{now:%Y-%m-%dT%H:%M}'
retention:
keep_daily: 7
prefix: '{hostname}-backups-'
consistency:
checks:
- repository
- archives
prefix: '{hostname}-backups-'
Le keep_daily permet de conserver 7 jours de backups sur la machine.
Pour plus dâinformations concernant les diverses options, je vous laisse consulter la documentation de rĂ©fĂ©rence.
Pour exécuter un backup rien de plus simple:
borgmatic
Cette commande va effectuer plusieurs choses.
Dâabord elle effectue un nettoyage des anciens backups
borg prune --keep-daily 7 --prefix {hostname}-backups /opt/backups
Puis effectue le backup à proprement parlé
borg create /opt/backups::{hostname}-backups-{now:%Y-%m-%dT%H:%M} /root/val2017
Avant de vĂ©rifier lâintĂ©gritĂ© du dĂ©pĂŽts dâarchives ainsi que les archives elles mĂȘme.
borg check --prefix {hostname}-backups /opt/backups
Automatisons lâautomatisation
Ok, câest bien beau tout ça mais je vais pas aller dans la console taper
borgmatictous les jours moi !
Effectivement tu ne va pas le faire. On va automatiser tout ça via lâutilisation de systemd, de services et de timers.
Tout dâabord le service borgmatic.service
[Unit]
borgmatic backup
network-online.target
network-online.target
true
[Service]
oneshot
true
no
yes
yes
yes
yes
yes
yes
yes
yes
yes
AF_UNIX AF_INET AF_INET6 AF_NETLINK
yes
yes
yes
native
@system-service
EPERM
full
CAP_DAC_READ_SEARCH CAP_NET_RAW
19
batch
best-effort
7
100
no
0
sleep 1m
systemd-inhibit --who="borgmatic" --why="Prevent interrupting scheduled backup" /root/.local/bin/borgmatic --syslog-verbosity 1
Puis le timer borgmatic.timer
[Unit]
Run borgmatic backup
[Timer]
daily
true
[Install]
timers.target
Et on installe tout ça
Si tous se passe bien vous devriez avoir ceci:
# service borgmatic status
; ; )
)
Maintenant chaque jour la commande borgmatic sera exécutée à votre place :D
Upload du backup
Fantastique et maintenant en quoi rĂ©pond Ă la problĂ©matique de âmon serveur est dĂ©truitâ, les backups sont toujours sur la machine, non ?
Excellente remarque, on va justement dans cette partie adresser ce problĂšme.
Pour cela je vous propose dâutiliser Amazon Glacier qui a pour principale intĂ©rĂȘt dâĂȘtre gratuit en transfert entrant.

Le stockage lui est payant mais les sommes sont minimes.

Ce qui est une chose plutÎt intéressante. :D
Il est aussi possible dâutiliser un autre provider comme Scaleway. Ne connaissant pas du tout le produit, je vais me renseigner sur le sujet et on fera peut-ĂȘtre alors un nouvel article dessus :)
Pour utiliser Glacier il vous faut un compte AWS qui peut ĂȘtre créé gratuitement.
CrĂ©ation dâun utilisateur de backup
Une fois cela fais il faut que vous vous connectiez Ă la Console.

Puis taper dans le moteur de recherche IAM (2) et sĂ©lectionnĂ© âUtilisateursâ (3)

Appuyer sur le bouton de crĂ©ation dâun nouvel utilisateur.

Donnez un nom Ă votre utilisateur (1) et un droit API (2) puis Suivant (3)

Afin de permettre les droits en écritures sur le Vault Glacier, vous devez lui attacher la stratégie correspondante (1) , puis cocher le AmazonGlacierFullAccess (2).
Vous pouvez alors faire Suivant (3).

Vous pouvez optionnellement rajouter des labels appelés des balises (1), puis Suivant (2)

Suivant !

Important !
Téléchargez le CSV ou copier avec le mot de passe (1), il ne vous sera plus jamais remontré !!
Maintenant
CrĂ©ation dâun Vault Glacier
Nous allons maintenant créer le Vault à proprement parlé.

Puis taper dans le moteur de recherche Glacier (2) et sĂ©lectionnĂ© âCrĂ©er un coffreâ (3).

Donnez un nom Ă votre Vault (1) puis âSuivantâ (2).

Pas de notification nécessaire.

Puis terminé !
FĂ©licitation vous avez créé votre premier Vault ! đ
Identification AWS
Nous allons stocker les identifiants dans un fichier qui se situera dans le home de lâutilsateur qui lancera la procĂ©dure de backup.
Ici /root/.aws/credentials
[default]
foo
bar
Modifiez foo et bar avec les identifiants de lâutilisateur que vous avez créé sur AWS.
On installe boto3, ici directement, mais vous pouvez parfaitement le faire dans un virtualenv.
Pour nous faciliter lâuplolad vers un vault, jâai Ă©cris un script python utilisant boto3.
Jâai nommĂ© ce script upload_to_glacier.py
#!/usr/bin/env python3
=
=
=
=
=
On créé aussi un script qui a pour rĂŽle de crĂ©er une archive du dernier backup connu, de lancer le script python ci-dessus. Et enfin de nettoyer lâarchive qui a Ă©tĂ© correctement uploadĂ©.
On va appellé ce script python au travers de notre bash.
Jâai appelĂ© ce script archive_and_run_glacier_upload.sh
#!/usr/bin/env bash
ARCHIVE=/tmp/-.tar.gz
On créé un dossier de travail
mkdir -p /opt/work
Puis on y déplace nos deux scripts
mv archive_and_run_glacier_upload.sh upload_to_glacier.py /opt/work/.
Puis on donne les droit dâĂ©xĂ©cution Ă ces fichiers
chmod u+x /opt/work/upload_to_glacier.py
chmod u+x /opt/work/archive_and_run_glacier_upload.sh
On va ensuite déclencher un upload vers Glacier toutes les semaines
Tout dâabord le service glacier.service
[Unit]
Upload archive to glacier
network-online.target
borgmatic.target
network-online.target
true
[Service]
oneshot
true
no
yes
yes
yes
yes
yes
yes
yes
yes
yes
AF_UNIX AF_INET AF_INET6 AF_NETLINK
yes
yes
yes
native
@system-service
EPERM
full
CAP_DAC_READ_SEARCH CAP_NET_RAW
19
batch
best-effort
7
100
no
0
sleep 1m
/opt/work/archive_and_run_glacier_upload.sh
Puis le timer glacier.timer qui se déclenche hebdomadairement
[Unit]
Run glacier upload
[Timer]
weekly
true
[Install]
timers.target
On installe tout ça
Si tout se passe bien
# systemctl status glacier
â glacier.service - Upload archive to glacier
Loaded: loaded (/etc/systemd/system/glacier.service; static; vendor preset: enabled)
Active: inactive (dead)
TriggeredBy: â glacier.timer
Vous pouvez mĂȘme visualiser lorsque le prochain run se fera
# systemctl status glacier.timer
â glacier.timer - Run glacier upload
Loaded: loaded (/etc/systemd/system/glacier.timer; enabled; vendor preset: enabled)
Active: active (waiting) since Mon 2021-03-15 19:23:48 UTC; 15min ago
Trigger: Mon 2021-03-22 00:00:00 UTC; 6 days left
Triggers: â glacier.service
Mar 15 19:23:48 backup systemd[1]: Started Run glacier upload.
Et bien on arrive au bout :D
Ne soyez pas surpris de ne rien voir sur lâinterface de la Console AWS de Glacier. Toutes les actions sont asynchrones.
En clair AWS rĂ©alise les opĂ©rations dâupload quand il le dĂ©sire, par exemple jâai Ă©cris ces lignes Ă 14h, mes backups ont Ă©tĂ© visibles Ă 0h44. Ils sâappellent ça faire lâinventaire.
Conclusion
Beaucoup de choses aujourdâhui, ( comme dâhabitudes on va me rĂ©pondre đ ).
On a appris à réaliser des backups efficaces, à les automatiser au travers de systemd et à les exporter sur AWS.
Un sujet que lâon nâa pas abordĂ© et qui pourrait faire lâobjet dâun article Ă lui tout seul est la rĂ©cupĂ©ration des backups de AWS.
Si ça vous intĂ©resse je pourrai lâĂ©crire dans lâavenir. :)
Un autre sujet qui nâa pas Ă©tĂ© couvert câest le test de vos backups, câest trĂšs bien de savoir sauvegarder, mais si les donnĂ©es sont corrompus câest un peu une perte de temps. LĂ aussi un article supplĂ©mentaire pourrait voir le jour tellement le sujet est vaste et intĂ©ressant. :D
Je vous remercie de mâavoir lu et je vous dit Ă la prochaine đ
