🐧 Edge Linux Debian · diagnostic & exploitation

Chapitre 08
Sauvegarde & restauration

Objectifs du chapitre

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Ă©gorieExemplesSauvegarder ?
Config & dĂ©finitions/opt/edge/compose.yml, gateway.yml, unitĂ©s systemd, chrony.conf, sshd_config✅ oui — petit, critique, propre Ă  la machine
DonnĂ©es persistantesvolumes Docker (gateway-data, mqtt-data)✅ oui — l'Ă©tat/historique local, irremplaçable
Reconstructibleimages 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).

Edge /opt/edge (config) volumes Docker → tar.gz /var/backups Laptop ~/backups/edge-cell12 rsync ← Stockage rĂ©seau NAS / coffre IT restauration →
Figure 8.1. RĂšgle du 3-2-1 en pratique : l'archive existe sur l'edge, sur le laptop, et sur un stockage rĂ©seau. La restauration (trait rouge) fait le chemin inverse — c'est elle qu'il faut avoir rĂ©pĂ©tĂ©e avant d'en avoir besoin.

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

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.