Gérer ses backups avec Borg
Lecture 10 min. âą
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
borgmatic
tous 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
-online.target
network-online.target
networktrue
[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
-effort
best7
100
no
0
1m
sleep -inhibit --who="borgmatic" --why="Prevent interrupting scheduled backup" /root/.local/bin/borgmatic --syslog-verbosity 1
systemd
Puis le timer borgmatic.timer
[Unit]
Run borgmatic backup
[Timer]
daily
true
[Install]
.target
timers
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
-online.target
network.target
borgmatic-online.target
networktrue
[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
-effort
best7
100
no
0
1m
sleep /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]
.target
timers
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 đ