## Introduction L'étiquetage des images Docker ne se résume pas à apposer un nom sur une image. C'est un élément critique de votre pipeline de livraison, qui influence la manière dont vous déployez, revenez en arrière et déboguez vos applications. Pourtant, de nombreuses équipes traitent les étiquettes comme une réflexion après coup, ce qui conduit à des environnements de production cassés et à des comportements de conteneurs mystérieux. Cet article va au-delà des bases pour explorer des concepts d'étiquetage avancés qui vous aideront à gérer les images de manière sûre et efficace. Nous verrons comment inspecter votre environnement, concevoir une stratégie d'étiquetage qui passe à l'échelle, vérifier vos images et récupérer des défaillances courantes. En chemin, vous trouverez des commandes pratiques, des exemples concrets et des listes de contrôle que vous pourrez adapter à vos propres flux de travail. Que vous soyez développeur, ingénieur DevOps ou responsable technique, ce guide vous aidera à transformer l'étiquetage des images d'une source de confusion en un outil opérationnel fiable. ## Inventaire des versions et de l'environnement Avant de modifier une étiquette, vous devez savoir exactement ce que vous avez. Commencez par recueillir des informations en lecture seule sur votre environnement Docker et les images en jeu. Cela évite les erreurs et vous donne une base de référence pour comparer plus tard. ### Vérifiez votre configuration Docker Tout d'abord, confirmez que Docker est en cours d'exécution et notez sa version. Les différentes versions prennent en charge des fonctionnalités d'étiquetage différentes. Par exemple, les images multi-architectures et BuildKit se comportent différemment selon les versions. ```bash docker version --format '{{.Server.Version}}' ``` La sortie attendue ressemble à `24.0.5`. Si vous obtenez une erreur comme `Cannot connect to the Docker daemon`, assurez-vous que le démon est en cours d'exécution et que votre utilisateur a les permissions nécessaires. Si vous utilisez Docker Compose, vérifiez également sa version : ```bash docker compose version ``` ### Lister les images et étiquettes actuelles Pour voir toutes les images locales et leurs étiquettes, exécutez : ```bash docker images --format 'table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.Size}}' ``` Un exemple de sortie : ``` REPOSITORY TAG IMAGE ID SIZE myapp latest abc123def456 350MB myapp v1.2.3 abc123def456 350MB myapp v1.2.4 789ghi012jkl 355MB ``` Notez que `latest` et `v1.2.3` pointent vers le même ID d'image. C'est courant mais souvent trompeur, comme nous le verrons plus tard. ### Inspecter une image spécifique Pour approfondir une image, utilisez `docker inspect`. Cela montre les variables d'environnement, le point d'entrée, l'architecture et plus encore. ```bash docker inspect myapp:v1.2.4 --format '{{json .Config.Env}}' ``` La sortie pourrait être : ```json ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","NODE_VERSION=18.17.0","APP_HOME=/app"] ``` Cela vous aide à vérifier que l'étiquette pointe bien vers l'image attendue. ### Inventorier les conteneurs en cours d'exécution et leurs images Vos conteneurs déployés sont les plus importants. Vérifiez quelle image chaque conteneur exécute : ```bash docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}' ``` Exemple : ``` NAMES IMAGE STATUS web-1 myapp:v1.2.4 Up 2 hours worker-1 myapp:v1.2.3 Up 2 hours ``` Ici, vous avez une divergence de version : un conteneur est sur v1.2.4, un autre sur v1.2.3. Sans cet inventaire, vous pourriez la manquer. ### Vérifier l'historique et la provenance de l'image Savoir comment une image a été construite aide à valider une étiquette. Utilisez `docker history` : ```bash docker history myapp:v1.2.4 --no-trunc --format 'table {{.CreatedBy}}\t{{.Size}}' ``` Recherchez des couches inattendues, comme une installation de paquet qui n'était pas dans votre Dockerfile. Cela pourrait indiquer un changement malveillant ou accidentel. ### Données et volumes : où vit l'état ? Avant de réétiqueter ou de remplacer une image, comprenez où les données sont stockées. Utilisez `docker inspect` sur un conteneur pour voir les montages. ```bash docker inspect web-1 --format '{{json .Mounts}}' ``` Exemple de sortie : ```json [{"Type":"volume","Name":"app_data","Source":"/var/lib/docker/volumes/app_data/_data","Destination":"/var/lib/app","RW":true}] ``` Un volume nommé comme `app_data` persiste à travers la recréation du conteneur. Un montage bind comme `./data:/var/lib/app` nécessite le même répertoire hôte sur chaque machine, ce qui peut causer des problèmes de portabilité. Confirmez que votre stratégie de volumes s'aligne avec votre plan d'étiquetage et de déploiement. ### Test de redémarrage pour la persistance des données Un moyen rapide de vérifier que les données sont en sécurité est de recréer un conteneur et de vérifier si les fichiers persistent. ```bash # Arrêter et supprimer le conteneur docker stop web-1 && docker rm web-1 # Recréer à partir de la même image docker run -d --name web-1 -v app_data:/var/lib/app myapp:v1.2.4 # Vérifier si les fichiers clés existent docker exec web-1 ls /var/lib/app ``` Si les fichiers sont manquants, les données ont probablement été écrites dans la couche du conteneur plutôt que dans le volume. C'est une constatation critique avant tout changement d'étiquette. ## Chemin de configuration sûr Avec un inventaire précis, vous pouvez concevoir une configuration d'étiquetage sûre, cohérente et réversible. L'objectif est d'éviter l'ambiguïté et de permettre des retours en arrière rapides. ### Définir un schéma d'étiquetage adapté à votre flux de travail Il existe plusieurs stratégies d'étiquetage courantes. Chacune a ses compromis. **Étiquettes de version sémantique** : `myapp:1.4.0`, `myapp:1.4.1`. Claires et triables, mais vous devez appliquer les incréments de version. **Étiquettes de hachage de commit Git** : `myapp:9fceb02`. Uniques et traçables au code, mais pas conviviales pour les comparaisons de versions. **Étiquettes de métadonnées de build** : `myapp:1.4.0-b456-20240315`. Ajoute l'ID de build et la date, utile pour les audits. **Étiquettes d'environnement** : `myapp:staging`, `myapp:production`. Faciles à comprendre mais mutables ; elles ne capturent pas les informations de version. Une approche robuste combine plusieurs. Par exemple, étiquetez chaque build avec à la fois une version sémantique et un hachage de commit : ```bash docker tag myapp:latest myapp:1.4.0 docker tag myapp:latest myapp:9fceb02 ``` Poussez les deux vers votre registre pour la traçabilité. ### Éviter le piège de `latest` `latest` est l'étiquette par défaut lorsqu'aucune n'est spécifiée. Elle ne signifie pas la plus récente ; elle étiquette simplement l'image qui a été construite ou poussée en dernier sans étiquette explicite. Cela conduit à des déploiements imprévisibles. Considérez ce scénario : ```bash # Construire l'image A docker build -t myapp:latest . docker push myapp:latest # Plus tard, construire l'image B sur une autre machine docker build -t myapp:latest . docker push myapp:latest ``` Maintenant, `myapp:latest` fait référence à l'image B, et tout système qui tire `latest` obtiendra B, même si A était prévue. Pour éviter cela, utilisez toujours des étiquettes explicites et immuables pour la production. ### Épingler les étiquettes dans les manifestes de déploiement Lors du déploiement avec Docker Compose, Kubernetes ou d'autres outils, n'utilisez jamais `latest` pour la production. Épinglez l'étiquette exacte. Dans un fichier Compose : ```yaml services: web: image: myapp:1.4.0 ``` Dans un déploiement Kubernetes : ```yaml spec: containers: - name: web image: myapp:1.4.0 ``` Cela garantit que chaque réplique exécute le même code. Lorsque vous voulez mettre à jour, changez l'étiquette à un seul endroit et déployez délibérément. ### Utiliser des politiques de mutabilité des étiquettes dans votre registre La plupart des registres vous permettent de rendre les étiquettes immuables. Par exemple, dans Docker Hub ou AWS ECR, vous pouvez configurer un dépôt pour rejeter l'écrasement d'une étiquette existante. Cela empêche les poussées accidentelles qui changent ce à quoi une étiquette pointe. Avec des étiquettes immuables, si vous essayez de pousser `myapp:1.4.0` deux fois, la deuxième poussée échoue : ``` error parsing HTTP 409 response body: invalid character 'p' after top-level value: "{\"errors\":[{\"code\":\"TAG_IMMUTABLE\",\"message\":\"tag 1.4.0 is immutable\"}]}" ``` C'est un filet de sécurité pour votre processus de publication. ### Gérer le cycle de vie des étiquettes et le nettoyage Les étiquettes inutilisées s'accumulent et gonflent les registres. La plupart des registres offrent des politiques de cycle de vie. Par exemple, dans AWS ECR, vous pouvez définir une règle pour supprimer les images qui ne sont référencées par aucune étiquette ou qui correspondent à un motif plus ancien que 30 jours. Un exemple de politique : ```json { "rules": [ { "rulePriority": 1, "description": "Expire untagged images older than 14 days", "selection": { "tagStatus": "untagged", "countType": "sinceImagePushed", "countUnit": "days", "countNumber": 14 }, "action": { "type": "expire" } } ] } ``` Faites attention à ne pas supprimer des étiquettes encore utilisées. Auditez avec `docker pull` avant le nettoyage. ## Vérification et diagnostics Après avoir configuré les étiquettes, vous devez vérifier que tout fonctionne comme prévu. Cette section fournit des vérifications concrètes. ### Vérifier la correspondance étiquette-image Utilisez `docker inspect` pour confirmer qu'une étiquette pointe vers l'ID d'image attendu. ```bash docker inspect myapp:1.4.0 --format '{{.Id}}' ``` Comparez avec l'ID d'image de votre système de build. Ils doivent correspondre exactement. ### Exécuter un conteneur à partir de l'image étiquetée et tester Lancez un conteneur et exécutez une vérification de santé. Pour une application web : ```bash docker run -d --name test-web -p 8080:80 myapp:1.4.0 curl -f http://localhost:8080/health ``` Sortie attendue : HTTP 200 ou un payload JSON comme `{"status":"ok"}`. Si curl échoue, inspectez les journaux : ```bash docker logs test-web --tail 50 ``` ### Vérifier les variables d'environnement et le point d'entrée Une étiquette ne garantit pas que le contenu de l'image est correct. Vérifiez les variables d'environnement qui affectent le comportement. ```bash docker inspect test-web --format '{{json .Config.Env}}' ``` Si vous attendiez `DB_HOST=prod-db` mais voyez `DB_HOST=localhost`, vous avez un problème d'étiquetage ou de build. ### Automatiser la vérification dans CI/CD Ajoutez une étape de vérification à votre pipeline après avoir poussé une étiquette. Par exemple, dans GitHub Actions : ```yaml - name: Verify image run: | docker pull myapp:1.4.0 docker run --rm myapp:1.4.0 ./run-tests.sh ``` Cela détecte les problèmes avant que l'étiquette n'atteigne la production. ## Modes de défaillance et récupération Même avec une planification minutieuse, les choses tournent mal. Voici les modes de défaillance courants autour de l'étiquetage des images et comment récupérer. ### Étiquette écrasée accidentellement **Problème** : Un développeur pousse une nouvelle image vers une étiquette existante, ce qui fait qu'un déploiement utilise le mauvais code. **Pourquoi cela arrive** : La mutabilité des étiquettes n'est pas appliquée, ou le système CI réutilise une étiquette statique. **Récupération** : Si votre registre le permet, récupérez l'ancienne image par son empreinte (digest). L'empreinte est immuable. ```bash # Trouver l'empreinte de l'image souhaitée docker manifest inspect myapp:1.4.0 | grep digest # Tirer par empreinte docker pull myapp@sha256:1234567890abcdef... # Réétiqueter correctement docker tag myapp@sha256:1234567890abcdef... myapp:1.4.0-fixed ``` **Prévention** : Activez l'immutabilité des étiquettes dans votre registre. Utilisez des étiquettes uniques par build. ### Le déploiement de `latest` a causé des versions incohérentes **Problème** : Différents conteneurs exécutent un code différent parce qu'ils ont tiré `latest` à des moments différents. **Pourquoi cela arrive** : `latest` est mutable et non déterministe. **Récupération** : Identifiez la version correcte à partir des journaux ou des tags Git, puis épinglez le manifeste de déploiement à cette étiquette exacte. ```bash # Vérifier les ID d'image kubectl get pods -o jsonpath='{range .items[*]}{.spec.containers[*].image}{"\n"}{end}' ``` Ensuite, mettez à jour le manifeste pour utiliser la version exacte et déployez. **Prévention** : N'utilisez jamais `latest` en production. Utilisez des étiquettes immuables. ### Mauvaise étiquette appliquée en raison d'une erreur humaine **Problème** : Une version a été étiquetée `v1.5.0` mais contient en réalité le code `v1.4.9`. **Pourquoi cela arrive** : Étiquetage manuel sans vérification. **Récupération** : Réétiquetez immédiatement l'image correcte. Si la mauvaise étiquette a été poussée, supprimez-la (si possible) et poussez une étiquette corrigée. Alertez l'équipe pour éviter d'utiliser la mauvaise étiquette. **Prévention** : Automatisez l'étiquetage dans CI en utilisant les métadonnées Git. Par exemple, dérivez l'étiquette du SHA de commit ou d'un fichier de version. ### Panne du registre empêchant le tirage des images étiquetées **Problème** : Les déploiements échouent car le registre est indisponible. **Pourquoi cela arrive** : Problèmes réseau, temps d'arrêt du registre ou échecs d'authentification. **Récupération** : Si vous avez des copies locales des images, vous pouvez exécuter des conteneurs à partir de celles-ci. Vérifiez avec `docker images`. ```bash docker images myapp --format '{{.Tag}} {{.ID}}' ``` Si l'image existe localement, Docker l'utilisera même si le registre est en panne, tant qu'aucun tirage n'est forcé. **Prévention** : Maintenez un registre miroir ou mettez en cache les images dans votre infrastructure. ## Pièges courants et comment les éviter ### Piège 1 : Utiliser des étiquettes pour la promotion d'environnement **Problème** : Promouvoir `myapp:staging` en production en le réétiquetant comme `myapp:production`. Cela perd l'historique des versions et rend le retour en arrière difficile. **Pourquoi cela arrive** : Les étiquettes sont considérées comme des environnements plutôt que des versions. **Comment éviter** : Gardez les étiquettes basées sur la version (par exemple, `1.4.0`). Déployez la même étiquette dans différents environnements et utilisez les configurations de déploiement pour différencier les environnements. ### Piège 2 : Prolifération des étiquettes sans nettoyage **Problème** : Des centaines d'étiquettes inutilisées s'accumulent, causant de la confusion et des coûts de stockage. **Pourquoi cela arrive** : Aucune politique de cycle de vie. **Comment éviter** : Mettez en place un nettoyage automatisé. Par exemple, dans Docker Hub, utilisez l'interface web ou l'API pour supprimer les étiquettes plus anciennes qu'une certaine date. Planifiez une revue mensuelle. ### Piège 3 : Étiquetage incohérent entre les équipes **Problème** : Différentes équipes utilisent des conventions de nommage différentes, rendant difficile la recherche d'images. **Pourquoi cela arrive** : Absence de norme partagée. **Comment éviter** : Documentez une convention. Exemple : `-:-`. Appliquez-la via des scripts CI qui rejettent les étiquettes non conformes. ### Piège 4 : Ignorer la provenance de l'image **Problème** : Vous ne pouvez pas tracer quel commit ou build a produit une image. **Pourquoi cela arrive** : Métadonnées insuffisantes dans les étiquettes ou les labels. **Comment éviter** : Ajoutez des labels OCI à votre Dockerfile : ```dockerfile LABEL org.opencontainers.image.source="https://github.com/yourorg/myapp" \ org.opencontainers.image.revision="9fceb02" \ org.opencontainers.image.version="1.4.0" ``` Ensuite, vérifiez avec `docker inspect`. ## Liste de contrôle des opérations Utilisez cette liste de contrôle avant et après toute opération d'étiquetage d'image. Chaque élément inclut un propriétaire et une fréquence de revue. | Vérification | Commande / Action | Résultat attendu | Propriétaire | Fréquence de revue | |--------------|-------------------|------------------|--------------|-------------------| | Version Docker | `docker version --format '{{.Server.Version}}'` | Version >= 20.10 | Responsable DevOps | Trimestrielle | | Images actuelles | `docker images --format 'table {{.Repository}}\t{{.Tag}}\t{{.ID}}'` | Aucune étiquette inattendue | Équipe | Hebdomadaire | | Conteneurs en cours | `docker ps --format 'table {{.Names}}\t{{.Image}}'` | Tous épinglés à des étiquettes explicites | Ingénieur Ops | À chaque déploiement | | Immutabilité des étiquettes activée | Vérification des paramètres du registre | Étiquettes immuables activées | Responsable DevOps | Mensuelle | | Politique de cycle de vie active | Règles de cycle de vie du registre | Anciennes étiquettes nettoyées automatiquement | Responsable DevOps | Mensuelle | | Étape de vérification dans CI | Journal du pipeline | Tests `docker run` réussis | Mainteneur CI | Sur changement | | Plan de retour en arrière documenté | Runbook écrit | Étapes claires pour revenir en arrière | Responsable technique | Trimestrielle | Pour chaque élément, le propriétaire est responsable de l'exécution et du rapport. Les fréquences de revue peuvent changer en fonction de la vélocité de l'équipe. ## Conclusion L'étiquetage des images Docker est une pratique fondamentale qui, bien faite, rend vos déploiements prévisibles et récupérables. En commençant par un inventaire approfondi de l'environnement, en concevant une configuration sûre, en vérifiant chaque changement d'étiquette et en vous préparant aux défaillances, vous transformez l'étiquetage en un avantage stratégique. Maintenant, faites un petit pas : auditez vos étiquettes actuelles en utilisant les commandes de cet article. Identifiez toute utilisation de `latest` en production, activez l'immutabilité des étiquettes et documentez votre convention d'étiquetage. Ces actions réduiront les risques et augmenteront la confiance dans votre pipeline de livraison. Rappelez-vous, l'objectif est la sécurité opérationnelle : observer avant de changer, limiter le rayon d'impact, vérifier les résultats et toujours avoir un chemin de récupération. Avec les concepts avancés et les exemples pratiques présentés ici, vous êtes équipé pour gérer les étiquettes des images Docker comme un professionnel.