Chapitre 08
Sauvegarde & restauration
Objectifs du chapitre
- Identifier ce qui doit ĂȘtre sauvegardĂ© sur un edge : config, volumes Docker, compose, unitĂ©s â et ce qui ne sert Ă rien de sauvegarder.
- Fabriquer une sauvegarde cohérente avec
tar, et la tirer sur le laptop avecrsync/scp. - Automatiser avec un timer systemd et une politique de rétention.
- Surtout : tester la restauration â une sauvegarde jamais restaurĂ©e n'est pas une sauvegarde.
1. Quoi sauvegarder ? (et quoi ignorer)
La bonne question n'est pas « comment tout copier » mais « qu'est-ce qui est irremplaçable et propre à cet edge ? ». On distingue trois catégories.
| Catégorie | Exemples | Sauvegarder ? |
|---|---|---|
| Config & dĂ©finitions | /opt/edge/compose.yml, gateway.yml, unitĂ©s systemd, chrony.conf, sshd_config | â oui â petit, critique, propre Ă la machine |
| DonnĂ©es persistantes | volumes Docker (gateway-data, mqtt-data) | â oui â l'Ă©tat/historique local, irremplaçable |
| Reconstructible | images Docker (dans le registry), paquets APT, l'OS | â non â se re-tĂ©lĂ©charge / rĂ©installe |
Le principe directeur : on sauvegarde ce qu'on ne peut pas reconstruire Ă partir d'une source. L'image Docker est dans le registry : inutile de la sauvegarder (mais garde le numĂ©ro de version dĂ©ployĂ©, lui, dans le compose â d'oĂč l'intĂ©rĂȘt de sauvegarder le compose). Les donnĂ©es du volume, elles, n'existent nulle part ailleurs : c'est le cĆur de la sauvegarde.
2. OĂč vivent les volumes ?
Un volume Docker nommé vit sous /var/lib/docker/volumes/<nom>/_data. On peut le
localiser avec inspect :
maint@edge-cell12:~$ docker volume inspect edge_gateway-data --format '{{.Mountpoint}}'
/var/lib/docker/volumes/edge_gateway-data/_data
Copier un volume « à chaud », conteneur en marche, risque de capturer des données
incohérentes (fichier à moitié écrit, base en cours de transaction). Pour une
sauvegarde vraiment fiable, on met le service en pause le temps du snapshot : docker compose
stop gateway â sauvegarde â docker compose start gateway. Sur un edge en production,
cette courte interruption se planifie en fenĂȘtre de maintenance. Si l'arrĂȘt est impossible, privilĂ©gie
un mĂ©canisme de dump applicatif cohĂ©rent (ex. l'app exporte elle-mĂȘme son Ă©tat) plutĂŽt qu'une copie
brute du volume vivant.
3. Fabriquer la sauvegarde avec tar
On rassemble config + volumes dans une archive horodatée. Le nom de fichier inclut la date pour la rétention :
#!/usr/bin/env bash
# /usr/local/sbin/edge-backup.sh â sauvegarde locale de l'edge
set -euo pipefail
STAMP=$(date +%Y%m%d-%H%M)
DEST=/var/backups/edge
mkdir -p "$DEST"
# 1. ArrĂȘt bref pour un snapshot cohĂ©rent des volumes
docker compose -f /opt/edge/compose.yml stop
# 2. Archive : config + volumes Docker, compressée
tar czf "$DEST/edge-$STAMP.tar.gz" \
-C / \
opt/edge \
etc/systemd/system/edge-gateway.service \
etc/chrony/chrony.conf \
var/lib/docker/volumes/edge_gateway-data/_data \
var/lib/docker/volumes/edge_mqtt-data/_data
# 3. Relance immédiate du service
docker compose -f /opt/edge/compose.yml start
# 4. Rétention : ne garder que les 7 derniÚres archives
ls -1t "$DEST"/edge-*.tar.gz | tail -n +8 | xargs -r rm --
echo "Sauvegarde OK : $DEST/edge-$STAMP.tar.gz"
On le rend exécutable et on l'essaie une fois à la main :
maint@edge-cell12:~$ sudo chmod +x /usr/local/sbin/edge-backup.sh
maint@edge-cell12:~$ sudo /usr/local/sbin/edge-backup.sh
Sauvegarde OK : /var/backups/edge/edge-20260704-0930.tar.gz
maint@edge-cell12:~$ ls -lh /var/backups/edge/
-rw-r--r-- 1 root root 214M Jul 4 09:30 edge-20260704-0930.tar.gz
set -euo pipefail en tĂȘte de script est une bonne habitude : -e
arrĂȘte au premier Ă©chec (on ne veut pas « rĂ©ussir » une sauvegarde Ă moitiĂ© faite),
-u refuse les variables non définies, pipefail propage l'échec dans un
pipe. Sans -e, un tar qui échoue (disque plein !) passerait inaperçu et
tu croirais avoir une sauvegarde.
4. Tirer la sauvegarde hors de l'edge
Point capital : une sauvegarde qui reste sur l'edge ne protĂšge de rien. Si le disque meurt ou la machine est volĂ©e, elle part avec. On la copie ailleurs â typiquement, on la tire depuis le laptop (l'edge n'a pas forcĂ©ment le droit d'Ă©crire vers l'IT).
# Depuis le LAPTOP : rapatrier la derniĂšre archive
laptop:~$ rsync -avz --progress \
edge12:/var/backups/edge/edge-20260704-0930.tar.gz \
~/backups/edge-cell12/
edge-20260704-0930.tar.gz 214.00M 100% 28.4MB/s
# Ou tout le dossier de sauvegardes, en miroir incrémental :
laptop:~$ rsync -avz edge12:/var/backups/edge/ ~/backups/edge-cell12/
rsync est préférable à scp pour du récurrent : il ne transfÚre que les
diffĂ©rences (les nouvelles archives), reprend un transfert interrompu, et compresse (-z) â
utile sur une liaison OT lente. Il passe par la config SSH du chapitre 2 (l'alias edge12).
5. Automatiser : un timer systemd
On veut que la sauvegarde tourne seule, chaque nuit. PlutĂŽt que cron, on utilise un timer systemd (chapitre 3) : mĂȘmes logs (journald), mĂȘme outillage. Deux fichiers.
# /etc/systemd/system/edge-backup.service
[Unit]
Description=Sauvegarde de l'edge
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/edge-backup.sh
# /etc/systemd/system/edge-backup.timer
[Unit]
Description=Sauvegarde quotidienne de l'edge
[Timer]
OnCalendar=*-*-* 02:30:00 # tous les jours Ă 02h30
Persistent=true # rattrape si l'edge était éteint à l'heure prévue
[Install]
WantedBy=timers.target
maint@edge-cell12:~$ sudo systemctl daemon-reload
maint@edge-cell12:~$ sudo systemctl enable --now edge-backup.timer
maint@edge-cell12:~$ systemctl list-timers edge-backup.timer
NEXT LEFT UNIT ACTIVATES
Sat 2026-07-05 02:30:00 CEST 16h left edge-backup.timer edge-backup.service
Persistent=true est important sur un edge susceptible d'ĂȘtre Ă©teint : si l'heure
prévue est manquée (machine hors tension à 02h30), la sauvegarde se lance au démarrage suivant, au lieu
d'ĂȘtre simplement sautĂ©e.
On vérifie qu'une sauvegarde automatique a bien tourné exactement comme un service :
systemctl status edge-backup.service (dernier résultat) et journalctl -u
edge-backup.service (le « Sauvegarde OK⊠» du script). Une automatisation qu'on ne
surveille pas est une automatisation qui vous lĂąche en silence le jour oĂč le disque est plein.
6. Restaurer : le seul test qui compte
Une sauvegarde n'a de valeur que si on sait la restaurer. La restauration type, aprĂšs un incident ou sur un edge de remplacement :
# 1. ArrĂȘter la stack (si elle tourne)
maint@edge-cell12:~$ docker compose -f /opt/edge/compose.yml down
# 2. Restaurer config + volumes depuis l'archive (Ă la racine)
maint@edge-cell12:~$ sudo tar xzf edge-20260704-0930.tar.gz -C /
# 3. Recharger les unitĂ©s (au cas oĂč une unitĂ© a Ă©tĂ© restaurĂ©e) et redĂ©marrer
maint@edge-cell12:~$ sudo systemctl daemon-reload
maint@edge-cell12:~$ docker compose -f /opt/edge/compose.yml up -d
# 4. VĂ©rifier que le service repart ET que les donnĂ©es sont lĂ
maint@edge-cell12:~$ docker compose ps
maint@edge-cell12:~$ docker logs --tail 20 edge-gateway
Teste la restauration sur un banc, pas sur l'edge de production. Restaurer une
archive « à la racine » avec tar -C / écrase des fichiers systÚme : sur un
edge en marche, une archive mal fabriquée (chemins absolus inattendus, version incompatible) peut
casser la config vivante. La bonne pratique : monter un edge de test, y dérouler la procédure de
restauration complÚte, chronométrer, noter les piÚges. Le jour d'un vrai sinistre, tu exécutes une
procédure déjà éprouvée, pas une improvisation.
L'erreur classique : sauvegarder pendant des mois⊠sans jamais avoir restauré une seule fois.
On découvre le jour J que l'archive est tronquée (disque plein pendant le tar), qu'un
volume manquait dans la liste, ou que le script stopait le mauvais service. Une sauvegarde
non testée est une hypothÚse, pas une garantie. Planifie un test de restauration
pĂ©riodique (par ex. trimestriel) au mĂȘme titre que la sauvegarde elle-mĂȘme.
Récapitulatif
- Sauvegarder ce qui est irremplaçable et propre à la machine : config
(
/opt/edge, unités,chrony.conf) + volumes Docker. Pas l'OS ni les images (reconstructibles depuis le registry). - Snapshot cohérent :
stopbref des conteneurs avant letar czf, puisstart. - Sortir la sauvegarde de l'edge (
rsynctirĂ© depuis le laptop â NAS) ; rĂšgle 3-2-1. - Automatiser avec un timer systemd (
OnCalendar,Persistent=true) + rĂ©tention ; surveiller viajournalctl -u edge-backup. - Tester la restauration sur un banc â une sauvegarde jamais restaurĂ©e n'en est pas une. Attention : le rollback d'image (chapitre 7) ne restaure pas les donnĂ©es ; seule la sauvegarde du volume le fait.
Exercices
Exercice 1 â Le tri
Sur l'edge, on te propose de sauvegarder : (a) /opt/edge/compose.yml, (b) l'image
registry.local/edge:1.8.2, (c) le volume edge_gateway-data, (d)
/usr/bin. Lesquels, et pourquoi ?
Voir la solution
Oui : (a) et (c). Le compose est la définition propre à cet edge (dont le
numéro de version déployé) ; le volume contient l'état/historique irremplaçable.
Non : (b) l'image est dans le registry, on la re-pull (il suffit de connaĂźtre son
tag, donné par le compose). Non : (d) /usr/bin vient des paquets
Debian, réinstallables. On sauvegarde ce qui ne se reconstruit pas depuis une source.
Exercice 2 â Sauvegarde Ă chaud, donnĂ©es corrompues
Ton script fait tar du volume sans arrĂȘter le conteneur, et Ă la restauration la base du
service est corrompue. Pourquoi, et comment corriger le script ?
Voir la solution
Le tar a copiĂ© le volume pendant que l'application Ă©crivait : fichiers Ă
moitiĂ© Ă©crits, transaction en cours â incohĂ©rence. On encadre l'archive d'un arrĂȘt bref :
docker compose -f /opt/edge/compose.yml stop
tar czf "$DEST/edge-$STAMP.tar.gz" ...
docker compose -f /opt/edge/compose.yml start
Si l'arrĂȘt est inacceptable, on s'appuie sur un export applicatif cohĂ©rent (l'app dumpe elle-mĂȘme sa base) plutĂŽt qu'une copie brute du volume vivant.
Exercice 3 â « On a des sauvegardes »
Un edge meurt. On sort la derniÚre archive⊠et la restauration échoue. Cite deux causes probables que seul un test de restauration préalable aurait révélées.
Voir la solution
Par exemple : (1) l'archive est tronquĂ©e â le disque Ă©tait plein pendant le
tar et, sans set -e, le script a rapportĂ© « OK » quand mĂȘme ;
(2) un volume manquait dans la liste des chemins tar (on sauvegardait
gateway-data mais pas mqtt-data) ; (3) les chemins de
l'archive ne correspondent pas à l'emplacement réel des volumes sur l'edge de remplacement ;
(4) l'archive était restée sur l'edge mort, jamais tirée ailleurs. Chacune se serait
vue lors d'un test de restauration Ă blanc â d'oĂč la rĂšgle : on teste la restauration, pas
seulement la sauvegarde.