FUNIX

Mettez un manchot dans votre PC


Encourager FUNIX

La consultation du site est totalement libre et gratuite, sans publicités. Les dons sont néanmoins appréciés pour payer l'hébergement et encourager son auteur


Sauvegarde
Présentation   |  btrfs ( Présentation | Maintenance | Sauvegarde par snapshot | L'outil snapper ) | Sauvegarde avec borg ( Installation de borg , utilisation de borg , mise en place d'un script de sauvegarde automatique avec borg ) | Unison ]

Dernière modification 13 septembre 2021

Techniques de sauvegarde

Réseau et système

Présentation

Cette page est issue de mon expérience de la sauvegarde de donnée, et notamment les mauvaises expériences. Le contexte matériel : mes données les plus sensibles sont stockées sur un serveur Dell PowerEdge T310 sur un système RAID5 matériel et sont partagés sur les autres postes du réseau, jusqu'à présent je faisais des sauvegardes manuelles, par la suite j'ai mis en place une sauvegarde régulière incrémentale régulière sur la base d'un script rsync. Il se trouve qu'un disque, puis deux disques du RAID 5 ont lâché (disques de plus de 5ans non prévus pour tourner 24h/24 7j/7) entraînant une corruption des données bas bruit car je n'avais pas programmé de script automatique d'alerte en cas de problème disque. Je m'en suis rendu compte trop tard et de fait la sauvegarde automatique a écrasé la sauvegarde saine avec des données corrompues ! J'ai perdu des données dans l'affaire :-(

Cette mauvaise expérience a conduit à une remise en cause de ma stratégie de sauvegarde, je suis d'abord passé par cette étape toujours basée sur rsync mais cette fois-ci avec des tests d'intégrité du RAID et du disque de sauvegarde. Suite à un journal sur linuxfr présentant cette dernière stratégie de sauvegarde j'ai pris en compte les différents commentaires pour mettre en place la solution de sauvegarde qui est présentée dans cette page.

Cette solution de sauvegarde est basée sur le système de fichier btrfs qui intègre intrinsèquement des fonctionnalités facilitant la sauvegarde, l'outil borg qui permet de mettre en place très facilement des sauvegardes incrémentales et unison un outil graphique qui gère les sauvegardes en mode manuel.

Sur le principe de sauvegarde, j'ai distingué les données chaudes et les données froides. les données froides sont les données qui évoluent peu ou pas du tout, typiquement des photos ou des vidéos le plus souvent, a contrario les données chaudes sont celles qui évoluent plus régulièrement comme les mails par exemple. Les stratégies de sauvegarde seront différentes suivant que les données soient froides ou chaudes. Pour les données froides qui évoluent peu, je choisis des copies manuelles, cela permet de s'assurer de leur intégrité, les données chaudes sont copiées automatiquement, avec toutefois un test d'intégrité au préalable des disques.

Concrètement ci-dessous on retrouve le principe de sauvegarde adapté à ma configuration matérielle

Les données froides présentes sur le RAID5 du serveur sont sauvegardées manuellement avec btrfs avec les snapshots, les snapshots sont copiés ensuite manuellement sur des disques externes (boîtier terramaster). Les données froides sont également dupliquées sur d'autres PC du réseau avec Unison.
Les données chaudes présentes sur le RAID1 et le RAID5 du serveur sont copiés automatiquement sur un disque externe USB branché au serveur avec borg après un test d'intégrité.

Cette page détaille donc la configuration de btrfs, de borg et d'Unison pour mettre en œuvre cette stratégie de sauvegarde. Pour les tests d'intégrité du disque, on pourra consulter cette page.



Présentation btrfs

btrfs ou B-tree File System (qu'on prononce souvent ButterFS !) est un système de fichiers développé par Oracle, plutôt que paraphraser ce qu'on peut trouver sur le net, je vous renvoie vers ces pages pour plus de détail, en français:

en anglais:

Il faudra d'abord créer un système de fichier btrfs sur votre espace disque, dans mon exemple il est monté sous /data sur mon serveur mana et physiquement il est constitué de 4 disques montés en RAID5 hard.

La commande suivante donne des informations détaillées sur le système de fichier

btrfs filesystem usage /data

Voilà le résultat

Overall:
    Device size:                   6.00TiB
    Device allocated:              2.04TiB
    Device unallocated:            3.95TiB
    Device missing:                  0.00B
    Used:                          2.04TiB
    Free (estimated):              3.95TiB      (min: 1.98TiB)
    Data ratio:                       1.00
    Metadata ratio:                   2.00
    Global reserve:              512.00MiB      (used: 0.00B)
    Multiple profiles:                  no

Data,single: Size:2.04TiB, Used:2.04TiB (99.98%)
   /dev/sdb1       2.04TiB

Metadata,DUP: Size:3.00GiB, Used:2.27GiB (75.65%)
   /dev/sdb1       6.00GiB

System,DUP: Size:8.00MiB, Used:240.00KiB (2.93%)
   /dev/sdb1      16.00MiB

Unallocated:
   /dev/sdb1       3.95TiB

Donc un espace total de 6To avec 2To utilisé. Pour avoir des informations sur l'état de l'espace, on tapera la commande

btrfs device stats /data

voilà le résultat

[/dev/sdb1].write_io_errs    0
[/dev/sdb1].read_io_errs     0
[/dev/sdb1].flush_io_errs    0
[/dev/sdb1].corruption_errs  0
[/dev/sdb1].generation_errs  0

[Retour haut de la page ]

Maintenance de btrfs

btrfs permet certaines opérations de maintenance :

  • Tout d'abord la balance, ça n'a essentiellement d'intérêt que si votre espace disque est constitué de plusieurs disques montés en raid logiciel (et non hard), cela permet entre autres de répartir les données quand on rajoute un nouveau disque, et a contrario de reconstruire les copies sur les disques restants quand on enlève un disque ou un disque est endommagé. Si votre espace n'est constitué que d'un seul disque, ça permet quand même de diminuer l'espace alloué.
  • Autre opération de maintenance le scrub, cela consiste à lire les blocs de données et les métadonnées qui vont avec (nom, taille du fichier, emplacement, etc.) et à vérifier leurs sommes de contrôle. Si une erreur est détectée, Une réparation automatique des blocs de données corrompus est lancée si une copie valide est disponible.
  • Pour terminer le trim, qui consiste à libérer les blocs inutilisés d'un disque SSD supportant la commande

Sur cette page on trouvera davantage d'informations sur l'ensemble de ces opérations.

On peut automatiser toutes ces opérations, l'ensemble des scripts fournis par btrfsmaintenance fait ça très bien. C'est une sorte de boîte à outils pour maintenir un système de fichiers btrfs. Le site officiel est https://github.com/kdave/btrfsmaintenance on récupère l'archive qu'on décompresse en tapant

unzip btrfsmaintenance-master.zip

cela donne le répertoire btrfsmaintenance-master dans lequel on tape en tant que root

./dist-install.sh

cela donne

Installation path: /etc/sysconfig
For cron-based setups:
- edit cron periods and mount points in /etc/sysconfig/btrfsmaintenance
- run ./btrfsmaintenance-refresh-cron.sh to update cron symlinks

For systemd.timer-based setups:
- copy *.timer files to the systemd.unit path (eg. /usr/lib/systemd/system/ or /etc/systemd/system)
- copy *.service files to the systemd.unit path (eg. /usr/lib/systemd/system/ or /etc/systemd/system)
- edit cron periods and mount points in /etc/sysconfig/btrfsmaintenance
- run './btrfsmaintenance-refresh-cron.sh timer' to enable and schedule the timers

sur ma Mageia, j'ai tapé également

cp *.timer /usr/lib/systemd/system
cp *.service /usr/lib/systemd/system


voilà le contenu du fichier de configuration /etc/sysconfig/btrfsmaintenance

## Path:        System/File systems/btrfs
## Type:        string(none,stdout,journal,syslog)
## Default:     "stdout"
#
# Output target for messages. Journal and syslog messages are tagged by the task name like
# 'btrfs-scrub' etc.
BTRFS_LOG_OUTPUT="journal"

## Path:        System/File systems/btrfs
## Type:        string
## Default:     ""
#
# Run periodic defrag on selected paths. The files from a given path do not
# cross mount points or other subvolumes/snapshots. If you want to defragment
# nested subvolumes, all have to be listed in this variable.
# (Colon separated paths)
BTRFS_DEFRAG_PATHS=""

## Path:           System/File systems/btrfs
## Type:           string(none,daily,weekly,monthly)
## Default:        "none"
## ServiceRestart: btrfsmaintenance-refresh
#
# Frequency of defrag.
BTRFS_DEFRAG_PERIOD="none"

## Path:        System/File systems/btrfs
## Type:        string
## Default:     "+1M"
#
# Minimal file size to consider for defragmentation
BTRFS_DEFRAG_MIN_SIZE="+1M"

## Path:        System/File systems/btrfs
## Type:        string
## Default:     "/"
#
# Which mountpoints/filesystems to balance periodically. This may reclaim unused
# portions of the filesystem and make the rest more compact.
# (Colon separated paths)
# The special word/mountpoint "auto" will evaluate all mounted btrfs
# filesystems
BTRFS_BALANCE_MOUNTPOINTS="auto"

## Path:           System/File systems/btrfs
## Type:           string(none,daily,weekly,monthly)
## Default:        "weekly"
## ServiceRestart: btrfsmaintenance-refresh
#
# Frequency of periodic balance.
#
# The frequency may be specified using one of the listed values or
# in the format documented in the "Calendar Events" section of systemd.time(7),
# if available.
BTRFS_BALANCE_PERIOD="none"

## Path:        System/File systems/btrfs
## Type:        string
## Default:     "5 10"
#
# The usage percent for balancing data block groups.
#
# Note: default values should not disturb normal work but may not reclaim
# enough block groups. If you observe that, add higher values but beware that
# this will increase IO load on the system.
BTRFS_BALANCE_DUSAGE="5 10"

## Path:        System/File systems/btrfs
## Type:        string
## Default:     "5"
#
# The usage percent for balancing metadata block groups. The values are also
# used in case the filesystem has mixed blockgroups.
#
# Note: default values should not disturb normal work but may not reclaim
# enough block groups. If you observe that, add higher values but beware that
# this will increase IO load on the system.
BTRFS_BALANCE_MUSAGE="5"

## Path:        System/File systems/btrfs
## Type:        string
## Default:     "/"
#
# Which mountpoints/filesystems to scrub periodically.
# (Colon separated paths)
# The special word/mountpoint "auto" will evaluate all mounted btrfs
# filesystems
BTRFS_SCRUB_MOUNTPOINTS="auto"

## Path:        System/File systems/btrfs
## Type:        string(none,weekly,monthly)
## Default:     "monthly"
## ServiceRestart: btrfsmaintenance-refresh
#
# Frequency of periodic scrub.
#
# The frequency may be specified using one of the listed values or
# in the format documented in the "Calendar Events" section of systemd.time(7),
# if available.
BTRFS_SCRUB_PERIOD="monthly"

## Path:        System/File systems/btrfs
## Type:        string(idle,normal)
## Default:     "idle"
#
# Priority of IO at which the scrub process will run. Idle should not degrade
# performance but may take longer to finish.
BTRFS_SCRUB_PRIORITY="idle"

## Path:        System/File systems/btrfs
## Type:        boolean
## Default:     "false"
#
# Do read-only scrub and don't try to repair anything.
BTRFS_SCRUB_READ_ONLY="false"

## Path:           System/File systems/btrfs
## Description:    Configuration for periodic fstrim
## Type:           string(none,daily,weekly,monthly)
## Default:        "none"
## ServiceRestart: btrfsmaintenance-refresh
#
# Frequency of periodic trim. Off by default so it does not collide with
# fstrim.timer . If you do not use the timer, turn it on here. The recommended
# period is 'weekly'.
#
# The frequency may be specified using one of the listed values or
# in the format documented in the "Calendar Events" section of systemd.time(7),
# if available.
BTRFS_TRIM_PERIOD="none"

## Path:        System/File systems/btrfs
## Description: Configuration for periodic fstrim - mountpoints
## Type:        string
## Default:     "/"
#
# Which mountpoints/filesystems to trim periodically.
# (Colon separated paths)
# The special word/mountpoint "auto" will evaluate all mounted btrfs
# filesystems
BTRFS_TRIM_MOUNTPOINTS="auto"

## Path:    System/File systems/btrfs
## Description:    Configuration to allow concurrent jobs
## Type:     boolean
## Default:    "false"
#
# These maintenance tasks may compete for resources with each other, blocking
# out other tasks from using the file systems.  This option will force
# these jobs to run in FIFO order when scheduled at overlapping times.  This
# may include tasks scheduled to run when a system resumes or boots when
# the timer for these tasks(s) elapsed while the system was suspended
# or powered off.
BTRFS_ALLOW_CONCURRENCY="false"

Dans la pratique seul le scrub est activé tous les mois. Maintenant pour configurer le lancement automatique des scripts via systemd on tapera

./btrfsmaintenance-refresh-cron.sh timer

voilà le résultat

Refresh script btrfs-scrub.sh for uninstall
Refresh script btrfs-defrag.sh for uninstall
Refresh script btrfs-balance.sh for uninstall
Refresh script btrfs-trim.sh for uninstall
Refresh timer btrfs-scrub for monthly
Refresh timer btrfs-defrag for none
Refresh timer btrfs-balance for weekly
Refresh timer btrfs-trim for none


Accessoirement j'ai tapé la commande suivante

cp btrfsmaintenance-refresh-cron.sh /usr/share/btrfsmaintenance

Maintenant pour voir que tout est bien lancé on tapera

 systemctl status btrfs-scrub.timer

voilà le résultat

● btrfs-scrub.timer - Scrub btrfs filesystem, verify block checksums
   Loaded: loaded (/usr/lib/systemd/system/btrfs-scrub.timer; enabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/btrfs-scrub.timer.d
           └─schedule.conf
   Active: active (waiting) since Sun 2021-01-10 10:59:11 CET; 5min ago
  Trigger: Mon 2021-02-01 00:00:00 CET; 3 weeks 0 days left
     Docs: man:btrfs-scrub

janv. 10 10:59:11 mana.kervao.fr systemd[1]: Started Scrub btrfs filesystem, verify block checksums.

et

systemctl status btrfs-balance.timer

voilà le résultat

● btrfs-balance.timer - Balance block groups on a btrfs filesystem
   Loaded: loaded (/usr/lib/systemd/system/btrfs-balance.timer; enabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/btrfs-balance.timer.d
           └─schedule.conf
   Active: active (waiting) since Sun 2021-01-10 10:59:11 CET; 5min ago
  Trigger: Mon 2021-01-11 00:00:00 CET; 12h left
     Docs: man:btrfs-balance

janv. 10 10:59:11 mana.kervao.fr systemd[1]: Started Balance block groups on a btrfs filesystem.

à chaque modification de /etc/sysconfig/btrfsmaintenance il faudra penser à taper

systemctl restart btrfsmaintenance-refresh


Sous mon répertoire /data, j'avais initialement les répertoires bureautique, musiques, photos et videos, on va faire en sorte de créer des sous volumes pour chacun de ces répertoires qui seront vus comme des systèmes de fichier indépendant. Pour le répertoire bureautique qui contenait déjà des données et qui se trouvait dans le volume btrfs /data, j'ai tapé les commandes suivantes :

mv bureautique/ bureautique.old

création du sous volume bureautique

btrfs subvolume create bureautique
Create subvolume './bureautique'

Je replace les droits qui vont bien de mon sous volume

chown olivier:hoarau bureautique

et je remets en place les données du répertoire bureautique d'origine que je supprime ensuite

cd bureautique.old
mv * ../bureautique
cd ..
rmdir bureautique.old

J'ai fait de même pour les autres répertoires de données. Bien sûr si vous partez d'un système de fichiers vierge, vous pouvez créer tout de suite vos sous volumes sans passer par ces étapes. Pour lister mes sous volumes je tape

btrfs subvolume list /data

voilà le résultat

ID 2358 gen 6055 top level 5 path bureautique
ID 2359 gen 6058 top level 5 path homepage
ID 2360 gen 6063 top level 5 path musiques
ID 2361 gen 6065 top level 5 path photos
ID 2362 gen 6067 top level 5 path videos

Maintenant je crée une image (snapshot) de mon sous volume dans le répertoire /data/.snapshots précédemment créé avec la commande

btrfs subvolume snapshot -r /data/bureautique /data/.snapshots/2021-01-10-snapshot-bureautique

cela donne

Create a snapshot of '/data/bureautique' in '/data/.snapshots/2021-01-10-snapshot-bureautique'

L'option -r

Idem pour mes autres sous volumes

btrfs subvolume snapshot -r /data/homepage /data/.snapshots/2021-01-10-snapshot-homepage
Create a readonly snapshot of '/data/homepage' in '/data/.snapshots/2021-01-10-snapshot-homepage'

btrfs subvolume snapshot -r /data/musiques /data/.snapshots/2021-01-10-snapshot-musiques
Create a readonly snapshot of '/data/musiques' in '/data/.snapshots/2021-01-10-snapshot-musiques'

btrfs subvolume snapshot -r  /data/photos /data/.snapshots/2021-01-10-snapshot-photos
Create a readonly snapshot of '/data/photos' in '/data/.snapshots/2021-01-10-snapshot-photos'

btrfs subvolume snapshot -r /data/videos /data/.snapshots/2021-01-10-snapshot-videos
Create a readonly snapshot of '/data/videos' in '/data/.snapshots/2021-01-10-snapshot-videos'

maintenant quand je liste mes sous volumes avec la commande

btrfs subvolume list /data

cela me donne

ID 2358 gen 6142 top level 5 path bureautique
ID 2359 gen 6144 top level 5 path homepage
ID 2360 gen 6145 top level 5 path musiques
ID 2361 gen 6146 top level 5 path photos
ID 2362 gen 6147 top level 5 path videos
ID 2363 gen 6142 top level 5 path .snapshots/2021-01-10-snapshot-bureautique
ID 2364 gen 6144 top level 5 path .snapshots/2021-01-10-snapshot-homepage
ID 2365 gen 6145 top level 5 path .snapshots/2021-01-10-snapshot-musiques
ID 2366 gen 6146 top level 5 path .snapshots/2021-01-10-snapshot-photos
ID 2367 gen 6147 top level 5 path .snapshots/2021-01-10-snapshot-videos

Il me semble qu'on ne peut pas créer le snapshot dans un autre volume, pour le déplacer ailleurs dans le répertoire /run/mount2/backup par exemple il faudra taper

btrfs send /data/.snapshots/2021-01-10-snapshot-bureautique/ | btrfs receive /run/mount2/backup/

et voilà le résultat

At subvol /data/.snapshots/2021-01-10-snapshot-bureautique/
At subvol 2021-01-10-snapshot-bureautique

on fera de même pour les autres snapshots. Attention le système de fichiers d'accueil, ici en l’occurrence /run/mount2/ doit être également formaté en btrfs. Pour liste ce que contient ce système de fichier d'accueil on tapera :

btrfs subvolume list /run/mount2

voilà le résultat

ID 257 gen 2883 top level 5 path backup
ID 886 gen 690 top level 257 path backup/2021-01-10-snapshot-bureautique
ID 890 gen 703 top level 257 path backup/2021-01-10-snapshot-homepage
ID 898 gen 731 top level 257 path backup/2021-01-10-snapshot-musiques
ID 921 gen 1575 top level 257 path backup/2021-01-10-snapshot-photos

Pour supprimer un snapshot ou d'une manière générale un sous volume, il ne faut pas passer par un rm classique, il faudra taper

btrfs subvolume delete /data/.snapshots/2021-01-10-snapshot-bureautique

Voilà le résultat

Delete subvolume (no-commit): '/data/.snapshots/2021-01-10-snapshot-bureautique'

Pour restaurer un fichier, il n'y a pas plus simple on se déplace dans un snapshot comme on se déplace dans n'importe quel répertoire et avec mv ou cp en ligne de commande ou avec n'importe quel explorateur de fichiers vous restaurer le(s) fichier(s) qui vous intéresse(nt).

Pour vérifier l'intégrité d'un disque btrfs (il ne doit pas être monté) dont le fichier spécial est /dev/sdg1 on tapera

btrfs check /dev/sdg1

voilà le résultat

Opening filesystem to check...
Checking filesystem on /dev/sdg1
UUID: 4ea323b2-0b81-4690-9a49-7aff4a80a1e4
[1/7] checking root items
[2/7] checking extents
[3/7] checking free space cache
[4/7] checking fs roots
[5/7] checking only csums items (without verifying data)
[6/7] checking root refs
[7/7] checking quota groups skipped (not enabled on this FS)
found 904351330304 bytes used, no error found
total csum bytes: 881925404
total tree bytes: 1037942784
total fs tree bytes: 85213184
total extent tree bytes: 17055744
btree space waste bytes: 58383667
file data blocks allocated: 903313387520
 referenced 903313387520

L'outil snapper

Snapper est un outil qui va vous aider à gérer les snapshots même si ça reste un outil en ligne de commande. Je l'ai installé sur ma Mageia simplement avec la commande urpmi mais à toutes fins utiles le site officiel est http://snapper.io/.

Pour illustrer son fonctionnement j'en reviens à mon répertoire /data et on crée une configuration avec la commande

snapper -c data create-config /data

ça me renvoie

Échec de la création de la configuration (creating btrfs subvolume .snapshots failed since it already exists).

forcément j'avais déjà créé préalablement un sous volume .snapshots qu'on voit bien quand je tape

btrfs subvolume list /data

ID 2358 gen 9137 top level 5 path bureautique
ID 2359 gen 9143 top level 5 path homepage
ID 2360 gen 6631 top level 5 path musiques
ID 2361 gen 9140 top level 5 path photos
ID 2362 gen 9135 top level 5 path videos
ID 2368 gen 6151 top level 5 path .snapshots/2021-01-10-snapshot-bureautique
ID 2369 gen 6152 top level 5 path .snapshots/2021-01-10-snapshot-homepage
ID 2370 gen 6153 top level 5 path .snapshots/2021-01-10-snapshot-musiques
ID 2371 gen 6154 top level 5 path .snapshots/2021-01-10-snapshot-photos
ID 2372 gen 6155 top level 5 path .snapshots/2021-01-10-snapshot-videos

Pas grave, on va renommer mon sous volume /data/.snapshots qui va être recréé par snapper

cd /data
mv .snapshots/ .instantanes

quand je liste à nouveau mon volume /data

btrfs subvolume list /data

j'obtiens

ID 2358 gen 9137 top level 5 path bureautique
ID 2359 gen 9143 top level 5 path homepage
ID 2360 gen 6631 top level 5 path musiques
ID 2361 gen 9140 top level 5 path photos
ID 2362 gen 9135 top level 5 path videos
ID 2368 gen 6151 top level 5 path .instantanes/2021-01-10-snapshot-bureautique
ID 2369 gen 6152 top level 5 path .instantanes/2021-01-10-snapshot-homepage
ID 2370 gen 6153 top level 5 path .instantanes/2021-01-10-snapshot-musiques
ID 2371 gen 6154 top level 5 path .instantanes/2021-01-10-snapshot-photos
ID 2372 gen 6155 top level 5 path .instantanes/2021-01-10-snapshot-videos

c'est tout bon on peut à nouveau retaper

snapper -c data create-config /data

tant qu'à faire je crée également pour l'exercice une configuration pour le sous volume videos

snapper -c video create-config /data/videos

maintenant en tapant

snapper list-configs

j'obtiens la liste des configurations

Configuration | Sous-volume
--------------+------------
data          | /data 
video         | /data/video

et en tapant

snapper -c data list

j'obtiens la liste des snapshots pour la configuration data,

Type   | # | Pre # | Date | Utilisateur | Nettoyer | Description | Données utilisateur
-------+---+-------+------+-------------+----------+-------------+--------------------
single | 0 |       |      | root        |          | current     |  

dans le cas présent il n'y en a pas, il y a juste le répertoire de référence. Maintenant on peut utiliser snapper de différente manière:
  • sauvegarde manuelle, on crée manuellement des snapshots
  • sauvegarde automatique, les snapshots sont créées et nettoyés automatiquement
Dans le cas de la configuration automatique, tout se passe dans le fichier /etc/snapper/configs/data dont voici le contenu

# subvolume to snapshot
SUBVOLUME="/data"

# filesystem type
FSTYPE="btrfs"

# btrfs qgroup for space aware cleanup algorithms
QGROUP=""

# fraction of the filesystems space the snapshots may use
SPACE_LIMIT="0.5"

# users and groups allowed to work with config
ALLOW_USERS=""
ALLOW_GROUPS=""

# sync users and groups from ALLOW_USERS and ALLOW_GROUPS to .snapshots
# directory
SYNC_ACL="no"

# start comparing pre- and post-snapshot in background after creating
# post-snapshot
BACKGROUND_COMPARISON="yes"

# run daily number cleanup
NUMBER_CLEANUP="yes"

# limit for number cleanup
NUMBER_MIN_AGE="1800"
NUMBER_LIMIT="50"
NUMBER_LIMIT_IMPORTANT="10"

# create hourly snapshots
TIMELINE_CREATE="yes"

# cleanup hourly snapshots after some time
TIMELINE_CLEANUP="yes"

# limits for timeline cleanup
TIMELINE_MIN_AGE="1800"
TIMELINE_LIMIT_HOURLY="10"
TIMELINE_LIMIT_DAILY="10"
TIMELINE_LIMIT_WEEKLY="10"
TIMELINE_LIMIT_MONTHLY="10"
TIMELINE_LIMIT_YEARLY="10"

# cleanup empty pre-post-pairs
EMPTY_PRE_POST_CLEANUP="yes"

# limits for empty pre-post-pair cleanup
EMPTY_PRE_POST_MIN_AGE="1800"

Par défaut il va créer  :
  • 10 snapshots par heure, et il conservera le dernier snapshot comme le snapshot du jour (daily snapshot)
  • 10 snapshots par jour, et il conservera le denier snapshot du jour comme le snapshot du mois (monthly snapshot)
  • 10 snapshots par mois, et il conservera le dernier snapshot du mois comme le snapshot de l'année (yearly snapshot)
  • 10 snapshots par année.
Par défaut les snapshots sont automatiquement nettoyés, snapper va conserver que 50 snapshots au total (NUMBER_LIMIT). Maintenant pour que ça se fasse automatiquement il faudra activer les lancer les services suivants :

systemctl enable snapper-timeline.timer
systemctl start snapper-timeline.timer
systemctl enable snapper-cleanup.timer
systemctl status snapper-cleanup.timer

En revanche si on ne souhaite pas mettre en place des sauvegardes automatiques on pourra créer manuellement un snapshot en tapant

snapper -c data create --description "21-01-22"

en tapant

snapper -c data list

on retrouve alors la liste des snapshots

Type   | # | Pre # | Date                            | Utilisateur | Nettoyer | Description | Données utilisateur
-------+---+-------+---------------------------------+-------------+----------+-------------+--------------------
single | 0 |       |                                 | root        |          | current     |                   
single | 1 |       | ven. 22 janv. 2021 18:30:16 CET | root        |          | 21-01-22    |                   
single | 2 |       | ven. 23 janv. 2021 18:58:36 CET | root        |          | 21-01-23   | 

C'est là que ça devient intéressant

snapper -c data status 1..2

va donner les fichiers qui ont évolué entre le snapshots 1 et 2. La commande ci-dessous est plus précise

snapper -c data diff 1..2

pour annuler une modification on tapera

snapper -c data undochange 1..2

et pour supprimer un snapshot

snapper -c data delete 2

Sauvegarde avec Borg

Installation de Borg

Borg est un outil de sauvegarde particulièrement puissant et simple à mettre en oeuvre, le site officiel est https://borgbackup.readthedocs.io/en/stable/ et on trouvera plus d'informations par ici ou . Sur ma Mageia, une fois n'est pas coutume, je me suis contenté d'installer le package fourni par la distribution en tapant

urpmi borgbackup

malheureusement il a disparu de la Mageia 8, il existe certes des packages par ici https://github.com/borgbackup/borg/releases mais ils ne sont pas complets pour permettre une compilation. Aussi il faudra récupérer la dernière version de développement via git en tapant

git clone https://github.com/borgbackup/borg.git

cela donne le répertoire borg, en se plaçant dans le répertoire où on a tapé la commande git on tapera

virtualenv --python=python3 borg-env
source borg-env/bin/activate

avant d'aller plus loin il faudra sans doute installer le package lib64python3-devel

on entre dans le répertoire borg dans lequel on tape

pip install -r requirements.d/development.txt

pip install -e .

voilà le résultat

Obtaining file:///usr/local/compil/borg
Requirement already satisfied: msgpack!=1.0.1,<=1.0.2,>=0.5.6 in /usr/local/lib64/python3.8/site-packages (from borgbackup==1.2.0b4.dev75+g64e694b6) (1.0.2)
Requirement already satisfied: packaging in /usr/lib/python3.8/site-packages (from borgbackup==1.2.0b4.dev75+g64e694b6) (20.4)
Requirement already satisfied: pyparsing>=2.0.2 in /usr/lib/python3.8/site-packages (from packaging->borgbackup==1.2.0b4.dev75+g64e694b6) (2.4.7)
Requirement already satisfied: six in /usr/lib/python3.8/site-packages (from packaging->borgbackup==1.2.0b4.dev75+g64e694b6) (1.15.0)
Installing collected packages: borgbackup
  Running setup.py develop for borgbackup
Successfully installed borgbackup

c'est tout bon !

La première chose à faire est créer un dépôt de sauvegarde

borg init --encryption=authenticated /media/sauvegardes/

voilà le résultat

Enter new passphrase:
Enter same passphrase again:
Do you want your passphrase to be displayed for verification? [yN]: y
Your passphrase (between double-quotes): "XXXX"
Make sure the passphrase displayed above is exactly what you wanted.

By default repositories initialized with this version will produce security
errors if written to with an older version (up to and including Borg 1.0.8).

If you want to use these older versions, you can disable the check by running:
borg upgrade --disable-tam /media/sauvegardes

See https://borgbackup.readthedocs.io/en/stable/changes.html#pre-1-0-9-manifest-spoofing-vulnerability for details about the security implications.

IMPORTANT: you will need both KEY AND PASSPHRASE to access this repo!
Use "borg key export" to export the key, optionally in printable format.
Write down the passphrase. Store both at safe place(s).

Il sera nécessaire de choisir une méthode de chiffrement, le mode authenticated n'utilise pas de clé de chiffrement, mais une méthode d'authentification avec un hash HMAC-SHA256 pour être précis.

Utilisation de Borg

Pour créer une archive contenant le répertoire /data on tapera

borg create /media/sauvegaders::2021-01-12 /data

pour lister les sauvegardes dans le dépôt, on tapera

borg list /media/sauvegardes

Il faudra saisir le mot de passe

Enter passphrase for key /media/sauvegardes:

et voilà ce que ça peut donner

2021-01-09                           Sat, 2021-01-09 04:02:03 [d6c5f9daadf14c9ef852f139443412fdc38ff5a445a2068f2647c38104f4314b]
2021-01-10                           Sun, 2021-01-10 04:36:39 [d9c06e57f60a99ee3c4993384cbef8ab6e287bbd244a82604a49d5edb341458e]
2021-01-11                           Mon, 2021-01-11 04:24:18 [2b396401bb2b5fd33794aa4192a8ba1f03ca610a436a8374649d0bcd30671936]
2021-01-12                           Tue, 2021-01-12 04:26:21 [dd8ac71b5cf3c91d3fc929b5bf1b27fc8ecbe33ef7d2dc3d77d65e65e6dd8a1b]
2021-01-20                           Wed, 2021-01-20 08:20:37 [aaa19828d8103e2387948ba359e74670337147d4898cf1c439a819dbfb18a30d]
2021-01-21                           Thu, 2021-01-21 04:50:00 [19b08f46b3618b3382563ce1eeca510364cb1d762d8dd66a9932ae08e9d8a727]
2021-01-22                           Fri, 2021-01-22 04:44:15 [adc633478cbff0602555a687ebcb404296d26313eccc01b82b5cc987cc615586]

Pour visualiser le contenu de l'archvie

borg list /media/sauvegardes::2021-01-09

Enter passphrase for key /media/sauvegardes:

et le contenu s'affiche

drwxr-xr-x root   root          0 Wed, 2021-01-06 17:16:14 etc
drwxr-xr-x root   root          0 Sun, 2020-11-22 11:24:56 etc/profile.d
-rw-r--r-- root   root        143 Fri, 2019-11-01 10:28:30 etc/profile.d/30python2.csh
-rwxr-xr-x root   root       1552 Wed, 2018-09-26 04:45:42 etc/profile.d/40configure_keyboard.sh
-rwxr-xr-x root   root        243 Mon, 2020-08-24 18:06:27 etc/profile.d/60qt5.csh
-rwxr-xr-x root   root        444 Mon, 2020-08-24 18:06:27 etc/profile.d/60qt5.sh
-rw-r--r-- root   root       1144 Sat, 2020-06-06 08:01:08 etc/profile.d/01msec.csh
-rw-r--r-- root   root        561 Sat, 2020-06-06 08:01:08 etc/profile.d/01msec.sh
(...)

Pour une restauration dans le répertoire courant, on tapera

borg extract /media/sauvegardes::2021-01-09

Pour une restauration dans le répertoire /data/temp

borg extract /media/sauvegardes::2021-01-09 /data/temp

ou autre solution, on monte l'archive dans un répertoire temporaire

borg mount /media/sauvegardes::2021-01-09 /media/borg

on récupère ce qu'on veut puis on démonte l'archive

borg umount /media/borg

Pour supprimer une archive

borg delete /media/sauvegardes::2021-01-09


[Retour haut de la page ]

Mise en place d'un script de sauvegarde avec borg

On commencera à saisir le mot de passe d'authentification du dépôt borg dans un fichier passphare sous le répertoire /root/.borg

mkdir /root/.borg
/root/.borg/passphrase

on donneral les droits d'écriture seul à root à ce fichier

chmod 400 /root/.borg/passphrase

maintenant j'ai créé un fichier /etc/cron.daily/sauvegarde pour qu'il soit lancé quotidiennement à 4h du mat sur ma Mageia. Il contient tout d'abord une batterie de test d'intégrité du disque et ne lance le script /usr/sbin/borg-sauve que si les tests sont passés avec succès.

#!/bin/bash

#lancement d'une commande de test d'intégrité du raid hard
/usr/local/linux/systeme/hwraid-master/wrapper-scripts/megaclisas-status > /tmp/megastatus 2>&1

# chemin du dépôt de sauvegarde qui est sur un disque externe
distant1="/media/sauvegardes"

# test de vérification de la présence du disque de sauvegarde
if [ ! -e "$distant1" ]
then
    #le disque n'est pas monté, j'envoie juste le mail d'état du raid et je stoppe le script
    cat /tmp/megastatus | mail -s "Etat raid" olivier
    exit
fi

#test de l'état de santé du disque dur externe
/usr/sbin/smartctl -a /dev/sdc >> /tmp/megastatus 2>&1

#envoi du mail de l'état des disques de mana
cat /tmp/megastatus | mail -s "Etat disk mana" olivier

# test de l'état du raid, en mode Degraded je stoppe tout
raid=$(MegaCli64 -LDInfo -L1 -a0 | grep State)
if echo $raid | grep Degraded >/dev/null 2>&1
then
    exit
fi

#test de l'état du disque dur externe
ddur=$(/usr/sbin/smartctl -A /dev/sdc)
if echo $ddur | grep FAILING_NOW >/dev/null 2>&1
then
    exit
fi

/usr/sbin/borg-sauve

On en vient au script /usr/sbin/borg-sauve les références qui m'ont aidé à le rédiger sont :

https://code.crapouillou.net/snippets/1
https://www.geek-directeur-technique.com/2017/07/17/utilisation-de-mysqldump
https://borgbackup.readthedocs.io/en/stable/quickstart.html#automating-backups

En plus de faire des sauvegardes régulières dans le dépôt de répertoires particuliers, le script sauvegarde également des bases MySQL et LDAP et envoie des mails pour rendre compte de la sauvegarde. Voilà le contenu du script

#!/bin/bash

# Script de sauvegarde basé sur borg
# Les sauvegardes sont chiffrées

set -e

#fonction de datation
ts_log() {
    echo `date '+%Y-%m-%d %H:%m:%S'` $1 >> ${LOG_PATH_TMP}
}

#définition de chemins de binaires
BORG=/usr/bin/borg
MYSQLDUMP=/usr/local/mysql/bin/mysqldump
MYSQL=/usr/local/mysql/bin/mysql
SLAPCAT=/usr/local/sbin/slapcat

#définition de variables
BACKUP_DATE=`date +%Y-%m-%d`
LOG_PATH_TMP=/var/log/sauvegarde/borg-backup-tmp.log
LOG_PATH=/var/log/sauvegarde/borg-backup.log
export BORG_PASSPHRASE="`cat /root/.borg/passphrase`"
BORG_REPOSITORY=/media/sauvegardes
BORG_ARCHIVE=${BORG_REPOSITORY}::${BACKUP_DATE}

#définition de variables pour les bases MySQL et LDAP
# on définira le mot de passe MySQL dans ce fichier
MYSQL_ROOT_PASS=`cat /root/.mysql/passphrase`
DATABASES=`MYSQL_PWD=$MYSQL_ROOT_PASS $MYSQL -u root -e "SHOW DATABASES;" | tr -d "| " | grep -v -e Database -e _schema -e mysqli -e sys`
LDAP_TMP_DUMP_FILE=/var/log/sauvegarde/ldap/ldab-db.ldif

# c'est parti, on commence à dater la sauvegarde
rm -f $LOG_PATH_TMP
ts_log "Starting new backup ${BACKUP_DATE}..."

# on copie les bases MySQL
ts_log 'Copie des bases MySQL...'
for DB_NAME in $DATABASES; do
  MYSQL_PWD=$MYSQL_ROOT_PASS $MYSQLDUMP -u root --single-transaction --skip-lock-tables $DB_NAME > /var/log/sauvegarde/mysql/$DB_NAME.sql
done

# on copie la base LDAP
ts_log 'Copie de la base LDAP...'
$SLAPCAT -l $LDAP_TMP_DUMP_FILE

# on crée les archives borg
# en mentionnant les répertoires à copier
ts_log "Création de l'archive ${BORG_ARCHIVE}"
$BORG create \
  -v --stats --compression lzma,9 \
  $BORG_ARCHIVE \
  /etc /usr/local/apache2 /usr/local/etc /data /home /var/mysql \
  $LDAP_TMP_DUMP_FILE \
  >> ${LOG_PATH_TMP} 2>&1

# Nettoyage des anciens backups
# On conserve
# - une archive par jour les 7 derniers jours,
# - une archive par semaine pour les 4 dernières semaines,
# - une archive par mois pour les 6 derniers mois.

ts_log "On fait tourner les anciennes sauvegardes"

$BORG prune -v $BORG_REPOSITORY \
  --keep-daily=7 \
  --keep-weekly=4 \
  --keep-monthly=6 \
  >> ${LOG_PATH_TMP} 2>&1

cat $LOG_PATH_TMP | mail -s "Sauvegarde" olivier
cat $LOG_PATH_TMP >> ${LOG_PATH}

Unison

Unison est un logiciel de synchronisation bidirectionnelle, c'est à dire que c'est à vous d'estimer quel est l'instance d'un fichier qui est la bonne entre les deux instances, il vous permet d'avoir la maîtrise totale de la copie et ça permet d'éviter bien des désagréments. Revers de la médaille, ce n'est pas automatique, il est manuel et ça peut prendre du temps, mais il peut être couplé à des solutions automatiques.

Unison se trouve sur n'importe quelle distribution moderne. A la création d'un profil de synchronisation, il faudra choisir son type de connexion, pour ma part ça reste du montage local.


On choisit ensuite les répertoires à synchroniser, si l'un des répertoires est vide, il va faire une copie.


Une fois que les profils de synchronisation ont été créés, il n'y aura plus que régulièrement faire des synchronisations manuelles.


 
[Retour page d'accueil FUNIX] [Retour haut de la page ]