Introduction
Docker BuildKit est le moteur de build moderne de Docker, offrant des builds plus rapides, une meilleure mise en cache et des fonctionnalités avancées comme l'exécution parallèle et la gestion des secrets. Cependant, le cache de build et l'état que BuildKit maintient peuvent devenir un atout critique dans votre flux de développement. Les perdre peut entraîner des builds plus lents, une utilisation accrue du réseau et une perte de reproductibilité. Ce guide fournit une approche pratique pour sauvegarder et restaurer l'état de Docker BuildKit, y compris le cache de build et la configuration, afin de garantir que votre environnement de build puisse être récupéré rapidement et en toute sécurité. Nous couvrons l'inventaire, la configuration sûre, la vérification, les modes de défaillance et une liste de contrôle pour les opérations continues.
Inventaire des versions et de l'environnement
Avant de mettre en œuvre toute stratégie de sauvegarde, il est essentiel de comprendre la version exacte et la configuration de Docker et de BuildKit dans votre environnement. Cet inventaire vous aide à localiser les fichiers pertinents et à déterminer la méthode de sauvegarde appropriée.
Tout d'abord, vérifiez la version de Docker et confirmez que BuildKit est activé :
docker version
Exemple de sortie :
Client: Docker Engine - Community
Version: 24.0.5
API version: 1.43
Go version: go1.20.6
...
Server: Docker Engine - Community
Engine:
Version: 24.0.5
API version: 1.43 (minimum version 1.12)
Go version: go1.20.6
...
Pour vérifier que BuildKit est actif, vérifiez les informations du builder :
docker buildx version
Exemple de sortie :
github.com/docker/buildx v0.11.2 docker/docker-ce-desktop: latest
Si vous utilisez le builder par défaut avec BuildKit, vous pouvez l'inspecter :
docker buildx inspect
La sortie affiche le nom du builder, le pilote et les plateformes des nœuds. Par exemple :
Name: default
Driver: docker
Nodes:
Name: default
Endpoint: docker-desktop
Status: running
Platforms: linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
BuildKit stocke son état à plusieurs emplacements selon le pilote et le système d'exploitation. Pour le pilote Docker (celui par défaut), le cache de build et les métadonnées sont stockés dans le répertoire de données du démon Docker. Sur Linux, il s'agit généralement de /var/lib/docker. Sur macOS et Windows, c'est dans la machine virtuelle Docker Desktop ou le disque Hyper-V, ce qui est moins directement accessible depuis l'hôte.
Pour une sauvegarde plus contrôlable, envisagez d'utiliser le pilote docker-container, qui exécute BuildKit dans un conteneur dédié. Ce pilote stocke son état dans un volume Docker que vous pouvez facilement sauvegarder. Pour créer un builder avec le pilote docker-container :
docker buildx create --name mybuilder --driver docker-container --use
Ensuite, vous pouvez inspecter son volume :
docker volume ls | grep mybuilder
Vous verrez un volume comme mybuilder0_buildkit_state. Ce volume contient le cache et les métadonnées de BuildKit. Sauvegarder ce volume est une méthode fiable.
De plus, notez le fichier de configuration Docker, généralement /etc/docker/daemon.json sur Linux, qui peut contenir des paramètres spécifiques à BuildKit comme "features": {"buildkit": true}. Ce fichier doit également faire partie de votre sauvegarde.
Le tableau 1 résume les emplacements courants à inventorier :
| Composant | Emplacement (Linux) | Méthode de sauvegarde |
|---|---|---|
| Données du démon Docker (inclut le cache BuildKit) | /var/lib/docker | Arrêter Docker, copier le répertoire |
| Volume d'état BuildKit (pilote docker-container) | Volume Docker mybuilder0_buildkit_state | docker run --rm -v mybuilder0_buildkit_state:/data -v /backup:/backup alpine tar czf /backup/buildkit-state.tar.gz -C /data . |
| Configuration du démon Docker | /etc/docker/daemon.json | Copier le fichier |
| Configuration BuildKit (si personnalisée) | /etc/buildkit/buildkitd.toml | Copier le fichier |
Chemin de configuration sûr
Après l'inventaire, configurez les sauvegardes de manière à minimiser les risques et à éviter de perturber les builds en cours. L'approche la plus sûre consiste à utiliser un script de sauvegarde dédié qui gèle ou capture un instantané de l'état sans arrêter le service BuildKit si possible, ou qui planifie une interruption si nécessaire.
Pour le répertoire de données du démon Docker, la méthode recommandée est d'arrêter le démon Docker avant de copier le répertoire pour garantir la cohérence. Cependant, si vous ne pouvez pas vous permettre une interruption, vous pouvez utiliser des instantanés de système de fichiers si votre stockage les prend en charge (par exemple, LVM, ZFS, Btrfs). Alternativement, utilisez tar avec des drapeaux appropriés pour copier pendant que le démon est en cours d'exécution, mais sachez que cela peut entraîner une sauvegarde incohérente si un build est en cours d'écriture. Le risque est faible pour les données de cache uniquement, mais il est plus sûr de suspendre les builds pendant la fenêtre de sauvegarde.
Pour le pilote docker-container, vous pouvez sauvegarder le volume d'état sans arrêter le builder en utilisant un conteneur temporaire pour compresser le contenu du volume. Cependant, pour garantir un instantané cohérent, il est préférable d'arrêter d'abord le conteneur du builder :
docker buildx stop mybuilder
Ensuite, exécutez la sauvegarde :
docker run --rm \
-v mybuilder0_buildkit_state:/data \
-v /backup:/backup \
alpine tar czf /backup/buildkit-state-$(date +%Y%m%d).tar.gz -C /data .
Après la sauvegarde, redémarrez le builder :
docker buildx start mybuilder
Pour éviter les étapes manuelles, créez un script de sauvegarde et planifiez-le avec cron. Par exemple, un script /usr/local/bin/backup-buildkit.sh :
#!/bin/bash
# Sauvegarde l'état BuildKit pour mybuilder
set -e
BACKUP_DIR="/backup/buildkit"
VOLUME="mybuilder0_buildkit_state"
TIMESTAMP=$(date +%Y%m%d%H%M%S)
mkdir -p "$BACKUP_DIR"
echo "Arrêt du builder..."
docker buildx stop mybuilder
echo "Sauvegarde du volume..."
docker run --rm -v "$VOLUME:/data" -v "$BACKUP_DIR:/backup" alpine tar czf "/backup/buildkit-state-$TIMESTAMP.tar.gz" -C /data .
echo "Démarrage du builder..."
docker buildx start mybuilder
echo "Sauvegarde terminée : $BACKUP_DIR/buildkit-state-$TIMESTAMP.tar.gz"
Rendez-le exécutable et ajoutez-le à cron (par exemple, tous les jours à 2 heures du matin) :
chmod +x /usr/local/bin/backup-buildkit.sh
echo "0 2 * * * /usr/local/bin/backup-buildkit.sh >> /var/log/buildkit-backup.log 2>&1" | crontab -
Pour le fichier de configuration du démon Docker, copiez-le simplement dans le répertoire de sauvegarde :
cp /etc/docker/daemon.json /backup/daemon.json
Assurez-vous que votre répertoire de sauvegarde dispose de suffisamment d'espace et qu'il est lui-même sauvegardé vers un stockage hors site ou distant selon votre plan de reprise après sinistre.
Vérification et diagnostics
Après avoir configuré les sauvegardes, vous devez vérifier que la sauvegarde est complète et restaurable. Ne supposez pas que la sauvegarde fonctionne ; testez-la régulièrement.
Tout d'abord, vérifiez l'existence et la taille du fichier de sauvegarde :
ls -lh /backup/buildkit-state-*.tar.gz
Exemple de sortie :
-rw-r--r-- 1 root root 245M Jul 26 02:00 /backup/buildkit-state-20240726020000.tar.gz
Vérifiez l'intégrité de l'archive tar :
tar tzf /backup/buildkit-state-20240726020000.tar.gz | head
Vous devriez voir le contenu de l'état BuildKit, comme des répertoires tels que runc-native, containerd, tmp, etc. Par exemple :
./
./runc-native/
./runc-native/metadata.db
./containerd/
./containerd/daemon/
...
Pour tester la restauration sans affecter l'environnement actuel, créez un builder temporaire avec un nouveau volume et restaurez la sauvegarde dedans :
# Créer un builder temporaire
docker buildx create --name restoretest --driver docker-container
# L'arrêter et restaurer la sauvegarde dans son volume
VOLUME_NAME=$(docker volume ls --format '{{.Name}}' | grep restoretest)
docker buildx stop restoretest
docker run --rm -v "$VOLUME_NAME:/data" -v /backup:/backup alpine sh -c "cd /data && tar xzf /backup/buildkit-state-20240726020000.tar.gz"
docker buildx start restoretest
# Utiliser le builder restauré pour voir si le cache est présent
docker buildx use restoretest
docker buildx du
La commande docker buildx du affiche l'utilisation du disque du cache. Si le cache a été restauré, vous devriez voir des entrées de cache avec des tailles. Par exemple :
ID RECLAIMABLE SIZE LAST ACCESSED
8f2e1c3d4b5a67890abcdef1234567890 true 123MB 2 days ago
...
Si les entrées de cache apparaissent, la restauration est réussie. Vous pouvez également exécuter un exemple de build qui devrait toucher le cache et observer des temps de build plus rapides.
De plus, vérifiez la restauration de la configuration du démon Docker en recopiant le fichier daemon.json et en redémarrant Docker :
sudo systemctl restart docker
sudo docker info | grep -A2 'BuildKit'
La sortie attendue inclut BuildKit: true ou similaire.
Après la vérification, supprimez le builder temporaire :
docker buildx rm restoretest
Modes de défaillance et récupération
Les sauvegardes peuvent échouer, les restaurations peuvent ne pas fonctionner comme prévu et BuildKit lui-même peut rencontrer des problèmes. Comprendre les modes de défaillance courants vous aide à récupérer rapidement.
Échec de sauvegarde dû à un espace disque insuffisant
Si le répertoire de sauvegarde manque d'espace, la commande tar échouera avec une erreur comme No space left on device. Surveillez l'utilisation du disque et configurez des alertes, par exemple en utilisant df -h /backup et en configurant un système de surveillance pour alerter lorsque l'utilisation dépasse 80 %. Récupération : libérez de l'espace et relancez la sauvegarde.
Sauvegarde incohérente due à des builds en cours
Si vous sauvegardez un volume actif sans arrêter le builder, le tar peut capturer un état en cours d'écriture, entraînant un cache corrompu lors de la restauration. Pour minimiser cela, arrêtez toujours le builder avant la sauvegarde. Si vous ne pouvez pas l'arrêter, utilisez des instantanés de système de fichiers. Récupération : si une restauration échoue en raison d'une corruption, vous devrez peut-être repartir avec un état BuildKit vierge et reconstruire les caches.
Restauration vers une version différente
Le format d'état de BuildKit peut changer entre les versions. Restaurer une sauvegarde d'une version beaucoup plus ancienne vers une version plus récente peut ne pas fonctionner. Testez toujours la restauration dans un environnement de préproduction. Récupération : si incompatible, vous devrez peut-être conserver la même version ou reconstruire le cache.
Inadéquation du nom de volume
Si vous restaurez vers un builder avec un nom de volume différent, vous devez vous assurer que le volume cible est vide et monté correctement. Par exemple, si la sauvegarde provient du volume mybuilder0_buildkit_state et que vous restaurez vers un nouveau builder newbuilder, le nom du volume sera newbuilder0_buildkit_state. Utilisez le bon nom de volume dans la commande de restauration.
Archive tar corrompue
Vérifiez toujours l'archive avec tar tzf avant de vous y fier. Conservez plusieurs générations de sauvegardes pour augmenter les chances d'avoir une bonne copie. Par exemple, conservez des sauvegardes quotidiennes pendant 7 jours, hebdomadaires pendant 4 semaines et mensuelles pendant 3 mois.
Le builder ne démarre pas après la restauration
Si le builder restauré ne démarre pas, vérifiez les journaux de BuildKit :
docker logs buildx_buildkit_mybuilder0
Recherchez des erreurs comme une corruption de base de données. Si le cache est corrompu, vous pouvez supprimer le volume et repartir de zéro, puis reconstruire les caches :
docker buildx rm mybuilder
# Recréer à partir de la sauvegarde si nécessaire
Planification du retour en arrière
Ayez toujours un plan de retour en arrière au cas où une restauration introduirait des problèmes. Conservez la version de sauvegarde précédente. Si une restauration échoue, vous pouvez recréer le builder à partir de la sauvegarde précédente connue comme bonne. Documentez les commandes exactes et testez-les.
Le tableau 2 résume les modes de défaillance courants et les actions de récupération :
| Mode de défaillance | Symptôme | Action de récupération |
|---|---|---|
| Disque de sauvegarde plein | Erreur tar : No space left on device | Libérer de l'espace, relancer la sauvegarde |
| Sauvegarde incohérente | La restauration échoue avec des fichiers inattendus | Restaurer à partir d'une sauvegarde antérieure |
| Inadéquation de version | Le builder ne démarre pas après la restauration | Utiliser la même version de BuildKit ou reconstruire le cache |
| Archive corrompue | tar tzf signale des erreurs | Restaurer à partir d'une autre génération de sauvegarde |
| Restauration vers le mauvais volume | Les données ne sont pas visibles dans le builder | Assurer le bon nom de volume et une cible vide |
Pièges courants et comment les éviter
Au-delà des défaillances explicites, il existe plusieurs erreurs courantes qui peuvent compromettre votre stratégie de sauvegarde BuildKit.
Piège 1 : Ne pas tester régulièrement les restaurations
De nombreuses équipes configurent des sauvegardes mais ne testent jamais la restauration. Une sauvegarde ne vaut que par sa capacité à restaurer. Sans test, vous pourriez découvrir au pire moment que vos sauvegardes sont inutilisables.
Évitement : Planifiez un test de restauration trimestriel dans le cadre de votre liste de contrôle opérationnelle. Utilisez la méthode du builder temporaire décrite précédemment pour valider la sauvegarde sans affecter la production.
Piège 2 : Sauvegarder le mauvais volume ou répertoire
Si vous utilisez le pilote docker-container, l'état BuildKit est dans un volume Docker, pas directement dans le système de fichiers hôte. Sauvegarder /var/lib/docker/volumes sans comprendre la disposition des volumes peut capturer des données incomplètes.
Évitement : Utilisez docker volume ls pour identifier le nom exact du volume et sauvegardez-le en utilisant la méthode tar décrite. Validez le contenu de l'archive pour vous assurer qu'il correspond aux fichiers BuildKit attendus.
Piège 3 : Ne pas arrêter le builder pendant la sauvegarde
Sauvegarder un builder en cours d'exécution peut conduire à un état incohérent, surtout si un build est en cours. Bien que cela puisse fonctionner pour les données de cache uniquement, c'est risqué.
Évitement : Arrêtez toujours le builder avec docker buildx stop avant la sauvegarde, ou utilisez des instantanés de système de fichiers si l'indisponibilité n'est pas acceptable.
Piège 4 : Ignorer les fichiers de configuration BuildKit
La configuration du builder comprend plus que les données de cache. Si vous avez des configurations BuildKit personnalisées (par exemple, buildkitd.toml) ou des paramètres du démon Docker, les perdre peut casser votre environnement de build même si le cache est restauré.
Évitement : Incluez les fichiers de configuration dans votre script de sauvegarde et stockez-les dans un système de contrôle de version pour une récupération facile.
Piège 5 : Ne pas conserver plusieurs générations de sauvegardes
Une seule sauvegarde peut être corrompue ou incomplète. Compter sur une seule sauvegarde augmente le risque.
Évitement : Mettez en œuvre une politique de rétention : conservez 7 sauvegardes quotidiennes, 4 hebdomadaires et 3 mensuelles. Automatisez la rotation à l'aide d'un outil comme logrotate ou d'un script personnalisé.
Piège 6 : Oublier les spécificités de Docker Desktop
Sur macOS et Windows, le démon Docker s'exécute dans une VM, et l'état BuildKit est dans l'image disque de la VM. Sauvegarder les répertoires hôtes peut ne pas capturer efficacement l'état BuildKit.
Évitement : Utilisez le pilote docker-container même sur Docker Desktop pour avoir un volume dédié qui peut être sauvegardé de manière cohérente. Alternativement, utilisez les fonctionnalités de sauvegarde intégrées de Docker Desktop ou exportez la VM.
Liste de contrôle opérationnelle
Pour garantir une fiabilité continue, intégrez les vérifications et procédures suivantes dans vos opérations régulières. Attribuez un responsable unique pour chaque élément et définissez une fréquence de révision.
| Élément de la liste de contrôle | Responsable | Fréquence |
|---|---|---|
| Inventorier les versions Docker et BuildKit ; mettre à jour la documentation | Ingénieur DevOps (ex. : Priya Shah) | Mensuelle |
| Confirmer que le script de sauvegarde s'exécute avec succès ; examiner les journaux pour détecter les erreurs | Administrateur système (ex. : Mark Chen) | Quotidienne |
| Tester une restauration vers un builder non productif et vérifier la présence du cache | Responsable QA (ex. : Laura Rodriguez) | Trimestrielle |
| Faire tourner les sauvegardes : conserver 7 quotidiennes, 4 hebdomadaires, 3 mensuelles | Opérateur de sauvegarde (ex. : Sam Patel) | Automatisée, vérifier hebdomadairement |
| Surveiller la capacité de stockage des sauvegardes et alerter si l'utilisation dépasse 80 % | Équipe de surveillance (ex. : Ingénieur DevOps) | Continue, réviser mensuellement |
| Documenter les commandes spécifiques à l'environnement dans le runbook | Rédacteur technique (ex. : Emily Nguyen) | Sur changement, réviser trimestriellement |
| Effectuer un exercice de reprise après sinistre | Responsable informatique (ex. : David Kim) | Deux fois par an |
| Examiner les configurations du builder et ajuster les paramètres de mise en cache | Ingénieur de build (ex. : Alex Johnson) | Mensuelle |
Chaque responsable doit documenter le résultat de ses vérifications et mises à jour dans un journal partagé. Par exemple, l'inventaire mensuel des versions doit enregistrer les versions de Docker et de BuildKit et tout changement dans la procédure de sauvegarde.
Conclusion
Sauvegarder et restaurer l'état de Docker BuildKit est une pratique simple mais essentielle pour maintenir l'efficacité du développement. En suivant les étapes de ce guide, vous pouvez protéger votre cache de build, réduire les temps de reconstruction et récupérer rapidement après des défaillances. Commencez par une simple sauvegarde du volume BuildKit en utilisant le pilote docker-container, vérifiez la restauration dans un environnement de test, puis intégrez le processus à vos opérations régulières avec des scripts planifiés et une surveillance. Des tests et une documentation réguliers garantiront que vos sauvegardes sont toujours prêtes quand vous en avez besoin.
Pour en savoir plus, consultez la documentation officielle de Docker Buildx et le dépôt BuildKit pour les dernières bonnes pratiques et les détails spécifiques aux versions.