Introduction
Les secrets Docker offrent un moyen intégré de gérer les mots de passe, les clés API, les certificats et autres données sensibles sans les intégrer dans les images ni les variables d’environnement. Dans Docker Swarm, les secrets sont chiffrés pendant le transit et au repos, et ne sont montés que dans les conteneurs explicitement autorisés à y accéder. Le stockage est simple. Les problèmes surviennent généralement lorsqu’un service tente d’accéder au montage du secret ou de communiquer avec un autre service qui dépend de ces secrets, et qu’un problème réseau se met en travers.
Ce guide est une présentation pratique pour ces moments-là. Nous aborderons la résolution DNS dans le réseau overlay, la connectivité des ports entre services, le comportement du routage entre nœuds, les règles de pare-feu qui bloquent silencieusement le trafic Swarm, et les commandes de diagnostic sûres à exécuter sans interrompre la production. Vous repartirez avec un processus reproductible : établir une base de référence, inspecter la configuration, tester chaque couche, isoler la panne et récupérer avec un plan de retour en arrière.
Inventaire des versions et de l’environnement
Avant de modifier quoi que ce soit, sachez avec quoi vous travaillez. Les incompatibilités de versions et les mauvaises configurations de nœuds sont des causes profondes fréquentes, et vous voulez les écarter tôt.
Vérifier les versions de Docker et de Swarm
Exécutez ceci sur un nœud manager :
docker version --format '{{.Server.Version}}'
Sortie attendue :
20.10.17
Confirmez maintenant que le nœud est un manager et que le Swarm est sain :
docker info --format '{{.Swarm.LocalNodeState}} {{.Swarm.ControlAvailable}}'
Sortie attendue :
active true
Si l’état local du nœud n’est pas active, ou si le contrôle n’est pas disponible, vous n’êtes pas sur un nœud manager. Toutes les commandes de gestion docker service et docker network doivent s’exécuter sur un manager.
Lister les nœuds et les réseaux
Obtenez une vue d’ensemble du cluster :
docker node ls
Recherchez les nœuds avec le statut Ready et la disponibilité Active. Un nœud à l’état Down ou Drain peut expliquer des réplicas de service manquants ou des conteneurs inaccessibles.
Listez ensuite les réseaux :
docker network ls
Faites attention au driver et à la portée. Les réseaux overlay de Docker Swarm utilisent le driver overlay et ont une portée swarm. Un réseau créé avec le driver bridge est local à un seul nœud et ne routera pas le trafic entre conteneurs sur des hôtes différents.
Prérequis pour le dépannage
- Accès SSH à au moins un nœud manager et à tout nœud worker où le service est planifié.
- Permissions d’exécuter les commandes
docker, généralement viasudoou l’appartenance au groupedocker. - Un modèle mental de base des services Swarm, des tâches et du réseau overlay.
- Un service ou une pile de test qui reproduit le problème sans toucher aux données de production.
Chemin de configuration sûr
Lorsqu’un service ne peut pas atteindre un secret ou un autre service, la tentation est de supprimer et de recréer le réseau, ou de redémarrer toute la pile. Résistez. Des modifications ciblées et réversibles vous permettent d’isoler le problème sans dommages collatéraux.
Inspecter la configuration du service
D’abord, voyez comment le service est défini :
docker service inspect --pretty <nom-du-service>
Recherchez les rattachements réseau et les montages de secrets. Voici un exemple tronqué d’un service réel :
Networks:
frontend-overlay
Secrets:
db_password
Target: /run/secrets/db_password
Le chemin cible du secret est le chemin du fichier à l’intérieur du conteneur. Si l’application attend le secret à un emplacement différent, elle échouera même si le secret existe.
Inspectez maintenant le réseau lui-même :
docker network inspect --verbose <nom-du-réseau>
Cela montre le sous-réseau, la passerelle et les conteneurs attachés à ce réseau. Vérifiez que le conteneur du service est listé. S’il ne l’est pas, le service n’est pas sur ce réseau, quoi que dise la spécification du service.
Ajouter un service de test sur le même réseau
Pour tester le comportement réseau depuis l’intérieur de l’overlay, créez un service temporaire attaché au même réseau :
docker service create --name test-secret-net --network <nom-du-réseau> alpine sleep 3600
Cela crée un seul réplica d’un conteneur Alpine qui dort pendant une heure, vous laissant le temps d’exécuter les diagnostics. Obtenez l’ID du conteneur :
docker ps -q --filter name=test-secret-net
Puis exécutez une commande dedans :
docker exec -it $(docker ps -q --filter name=test-secret-net) sh
Dans le conteneur, testez l’accès au secret si le service testé est censé en avoir un :
cat /run/secrets/my-secret
Si le fichier est absent, le secret n’est pas monté. C’est un problème de configuration, pas nécessairement un problème réseau, mais il apparaît souvent en même temps que les problèmes réseau parce que le service ne peut pas démarrer et ne rejoint donc jamais le réseau correctement.
Isoler les problèmes DNS
Le serveur DNS intégré de Docker tourne à 127.0.0.11 dans chaque conteneur. Il résout les noms de service en adresses IP virtuelles (VIP) sur le réseau overlay. Testez la résolution dans le conteneur de test :
nslookup <nom-du-service>
La sortie attendue inclut la VIP :
Name: <nom-du-service>
Address: 10.0.0.2
Si la résolution échoue, vérifiez que le service est attaché au même réseau que le conteneur de test. La résolution DNS ne fonctionne que pour les services sur le même réseau overlay. Vérifiez aussi que le serveur DNS est accessible :
cat /etc/resolv.conf
Il devrait afficher nameserver 127.0.0.11. S’il affiche un serveur DNS externe, quelque chose ne va pas dans la configuration réseau du conteneur.
Vérification et diagnostics
Travaillez maintenant systématiquement à travers chaque couche : DNS, ports, routage et pare-feu. Chaque test soit innocente une couche, soit pointe vers le coupable.
Tests de résolution DNS
Dans le conteneur de test, utilisez dig ou nslookup pour interroger le nom du service. Pour un service appelé my-web sur le réseau frontend :
dig my-web +short
Résultat attendu :
10.0.0.2
Si le service est attaché à plusieurs réseaux, le serveur DNS renvoie une VIP par réseau. Interrogez avec le nom complet avec la portée du réseau si nécessaire :
dig my-web.frontend +short
Vous pouvez aussi vérifier directement la VIP du service :
docker service inspect my-web --format '{{json .Endpoint.VirtualIPs}}'
Cela montre la VIP par réseau, par exemple :
[{"NetworkID":"abcd1234","Addr":"10.0.0.2/24"}]
Si le DNS échoue, le service peut ne pas avoir de réplicas en cours d’exécution, ou le service n’est pas sur le même réseau.
Connectivité des ports
Une fois que le DNS fonctionne, testez si le port TCP est ouvert. La commande nc (netcat) est disponible dans de nombreuses images, ou vous pouvez l’installer dans le conteneur de test :
apk add --no-cache netcat-openbsd
Testez ensuite la connectivité :
nc -zv my-web 80
Sortie attendue :
my-web (10.0.0.2:80) open
Si le port est fermé, vérifiez si le service publie réellement le port. Pour la communication interne de service à service, le service n’a pas besoin de publier un port avec --publish ; il lui suffit d’écouter sur le port à l’intérieur du conteneur. Inspectez la configuration des ports du service :
docker service inspect my-web --format '{{json .Endpoint.Ports}}'
Si aucun port n’est listé, le service n’expose aucun port vers le monde extérieur, mais il peut toujours écouter en interne. Pour voir ce que fait le processus à l’intérieur du conteneur, exécutez une commande dans l’un des conteneurs du service :
docker exec <id-conteneur> netstat -tulpn
Recherchez le port attendu à l’état LISTEN.
Vérifications du routage
Le routage IP de base peut être testé avec ping. Depuis le conteneur de test :
ping -c 4 my-web
Si vous recevez des réponses, le routage IP fonctionne. Si le ping échoue, ne concluez pas immédiatement à un problème de routage : de nombreuses images de production désactivent l’écho ICMP, ou des règles de pare-feu bloquent le ping. Utilisez traceroute pour voir le chemin :
traceroute my-web
Dans le réseau overlay, vous devriez voir une route directe vers la VIP sans sauts intermédiaires, car la VIP est gérée par le maillage de routage local.
Pour un aperçu plus approfondi de la configuration réseau du conteneur :
ip addr show
ip route
Vérifiez que la passerelle par défaut correspond à la passerelle du réseau overlay. Vous pouvez obtenir la passerelle avec docker network inspect :
docker network inspect frontend-overlay --format '{{json .IPAM.Config}}'
Exemple de sortie :
[{"Subnet":"10.0.0.0/24","Gateway":"10.0.0.1"}]
Si la route par défaut du conteneur pointe ailleurs, le conteneur peut avoir démarré avec une mauvaise configuration réseau.
Vérifications du pare-feu
Les règles de pare-feu sur les hôtes Docker bloquent fréquemment le trafic Swarm. Docker gère ses propres chaînes iptables, mais les règles définies par l’utilisateur dans la chaîne DOCKER-USER peuvent les outrepasser. Sur un hôte Linux, exécutez :
sudo iptables -L DOCKER-USER -n -v
Recherchez les règles REJECT ou DROP qui pourraient affecter les ports :
2377/tcppour la communication de gestion du cluster7946/tcpet7946/udppour la communication entre nœuds4789/udppour le trafic du réseau overlay
Par exemple, une règle comme celle-ci bloque le trafic VXLAN :
Chain DOCKER-USER (1 references)
pkts bytes target prot opt in out source destination
0 0 DROP udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:4789
Si une telle règle existe, supprimez-la ou ajustez-la. Vérifiez aussi que les ports sont ouverts entre les nœuds avec ss ou nc depuis l’hôte :
sudo ss -lntup | grep -E '2377|7946|4789'
Cela montre si le démon Docker écoute sur ces ports.
Diagnostics spécifiques aux secrets
Si un service ne démarre pas à cause d’un secret manquant, inspectez les journaux du service :
docker service logs <nom-du-service>
Un message d’erreur courant :
secret not found: my-secret
Cela signifie que le service a été créé avec une référence à un secret qui n’existe pas. Listez les secrets :
docker secret ls
Si le secret existe mais que le conteneur ne peut pas y accéder, vérifiez la configuration des secrets du service :
docker service inspect <nom-du-service> --format '{{json .Spec.TaskTemplate.ContainerSpec.Secrets}}' | jq .
Exemple de sortie :
[
{
"File": {
"Name": "/run/secrets/my-secret",
"UID": "0",
"GID": "0",
"Mode": 292
},
"SecretID": "somesecretid",
"SecretName": "my-secret"
}
]
Le File.Name est le chemin cible. Le Mode est la permission octale, ici 292 en décimal qui vaut 0444 en octal, c’est-à-dire lisible par tous. Si le mode est 0, le fichier peut être inaccessible. Vérifiez aussi que l’UID et le GID correspondent à l’utilisateur qui exécute le processus dans le conteneur.
Dans le conteneur, vérifiez le fichier :
ls -l /run/secrets/
Si le fichier existe mais est illisible, ajustez les permissions de la cible du secret ou exécutez le conteneur en tant qu’utilisateur avec un accès approprié.
Modes de défaillance et récupération
Reconnaître les schémas de défaillance courants accélère la récupération. Pour chacun, nous décrivons le symptôme, la cause probable et les étapes concrètes de récupération.
Échec de résolution DNS
Symptôme : nslookup ou dig ne renvoie aucune réponse, ou le nom du service ne peut pas être résolu.
Cause : Le service et le conteneur de test ne sont pas sur le même réseau overlay, ou le service n’a aucun réplica en cours d’exécution, ou le DNS intégré est mal configuré.
Récupération :
- Vérifiez les réseaux du service :
docker service inspect my-service --format '{{json .Spec.TaskTemplate.Networks}}'
- Si le réseau est manquant, ajoutez-le :
docker service update --network-add frontend-overlay my-service
- Assurez-vous qu’au moins un réplica est en cours d’exécution :
docker service ps my-service
- Testez à nouveau la résolution depuis le conteneur de test.
Échec de connectivité des ports
Symptôme : nc signale une connexion refusée ou expire lors de la connexion au port du service.
Cause : Le service n’écoute pas sur le port attendu à l’intérieur du conteneur, ou une règle de pare-feu bloque la connexion, ou le service n’a pas de tâches en cours d’exécution.
Récupération :
- Vérifiez que le service est en cours d’exécution :
docker service ps my-service
- Vérifiez le port que le service pense exposer :
docker service inspect my-service --format '{{json .Endpoint.Ports}}'
- Dans un conteneur en cours d’exécution du service, vérifiez les ports en écoute :
docker exec <id-conteneur> netstat -tulpn | grep <port>
- Si aucun processus n’écoute, corrigez la configuration de l’application ou la directive
EXPOSEdu Dockerfile. Si le port est en écoute mais que la connexion échoue, vérifiez les règles de pare-feu comme décrit précédemment.
Échec d’accès au secret
Symptôme : Le conteneur ne peut pas lire le fichier du secret, ou le fichier est manquant.
Cause : Le secret n’est pas monté correctement, le chemin cible est incorrect ou les permissions sont trop restrictives.
Récupération :
- Listez les secrets et confirmez que le secret voulu existe :
docker secret ls
- Recréez le service avec la bonne cible de secret si le chemin est incorrect :
docker service update --secret-rm my-secret --secret-add source=my-secret,target=/run/secrets/db_password my-service
- Vérifiez dans un conteneur :
docker exec <id-conteneur> ls -l /run/secrets/
La sortie devrait montrer le fichier avec des permissions raisonnables, par exemple -r--r--r-- 1 root root.
Dégradation des performances réseau
Symptôme : Latence élevée ou perte de paquets entre services sur le réseau overlay.
Cause : Mauvaise configuration du réseau overlay, problèmes de MTU ou problèmes d’infrastructure sous-jacente.
Récupération :
- Testez la perte de paquets :
ping -c 100 <cible>
- Vérifiez les incompatibilités de MTU. Les réseaux overlay ajoutent la surcharge VXLAN, donc le MTU doit être inférieur à celui du réseau sous-jacent. Inspectez le MTU du réseau :
docker network inspect frontend-overlay --format '{{json .Options}}'
Recherchez com.docker.network.driver.mtu. La valeur par défaut est généralement 1450. Si le réseau sous-jacent a un MTU de 1500 et que l’overlay est réglé sur 1500, une fragmentation peut se produire. Définissez le bon MTU lors de la création du réseau :
docker network create -d overlay --opt com.docker.network.driver.mtu=1400 my-overlay
- Si les problèmes persistent, envisagez de recréer le réseau overlay et de réattacher les services. Cela perturbe le trafic, alors planifiez une fenêtre de maintenance et utilisez le plan de retour en arrière.
Stratégies de retour en arrière
Soyez toujours capable d’annuler les modifications. Pour les services, utilisez :
docker service rollback <nom-du-service>
Cela revient à la spécification de service précédente, y compris les réseaux et les secrets. Notez que seule la spécification immédiatement précédente est stockée.
Pour les changements de réseau, documentez l’état d’origine avant toute modification :
docker network inspect <nom-du-réseau> > network-backup.json
Si nécessaire, supprimez le réseau et recréez-le à partir de la sauvegarde. Cependant, supprimer un réseau overlay déconnecte tous les services attachés et peut causer une brève interruption.
Pièges courants et comment les éviter
Plusieurs erreurs reviennent sur le terrain. Voici les plus fréquentes et comment les prévenir ou s’en remettre.
1. Tester depuis le mauvais réseau
Pourquoi cela arrive : Il est facile de créer un conteneur de test sur le réseau bridge par défaut ou un autre overlay, puis d’essayer d’atteindre un service par son nom. La résolution DNS de Docker est limitée au réseau, donc le nom ne se résoudra pas.
Comment éviter : Spécifiez toujours le même réseau overlay lors de la création du service de test :
docker service create --name test-container --network <réseau-du-service> alpine sleep 3600
Vérifiez avec docker inspect que le conteneur de test est bien attaché au réseau voulu.
2. Ignorer les règles de pare-feu sur les hôtes
Pourquoi cela arrive : Beaucoup d’administrateurs se concentrent sur le réseau des conteneurs et oublient que les pare-feu au niveau de l’hôte peuvent bloquer la communication inter-nœuds de Swarm. Les règles iptables de Docker sont généralement permissives, mais les règles ajoutées par l’utilisateur dans la chaîne DOCKER-USER peuvent les outrepasser.
Comment éviter : Vérifiez toujours iptables -L DOCKER-USER -n -v sur les hôtes source et cible pendant le dépannage. Autorisez explicitement les ports 2377, 7946 et 4789 si vous avez une politique de pare-feu restrictive.
3. Négliger les chemins cibles des secrets
Pourquoi cela arrive : Le nom du secret et le chemin du fichier dans le conteneur sont indépendants. Un développeur peut créer un secret nommé db_password mais configurer le service pour le monter à /run/secrets/password, alors que l’application attend /run/secrets/db_password.
Comment éviter : Définissez une convention de nommage cohérente pour les secrets et leurs cibles. Utilisez docker service inspect --pretty pour confirmer le chemin cible, et testez toujours avec cat /run/secrets/<chemin-attendu> dans un conteneur.
4. Supposer que la VIP est une vraie IP
Pourquoi cela arrive : La VIP du service est une adresse IP virtuelle gérée par le maillage de routage de Docker. Elle n’est liée à aucun conteneur unique. Certains utilisateurs essaient de pinger la VIP ou de s’y connecter depuis l’extérieur de l’overlay et sont déroutés quand cela ne fonctionne que depuis l’intérieur du réseau.
Comment éviter : Comprenez que la VIP n’est routable que depuis les conteneurs sur le même réseau overlay. Pour un accès externe, utilisez un port publié.
5. Ne pas vérifier le statut des réplicas du service
Pourquoi cela arrive : Un service peut être défini mais avoir zéro réplica en cours d’exécution à cause de tâches échouées. Le DNS peut toujours résoudre le nom du service en une VIP, mais aucun conteneur backend n’existe pour gérer le trafic.
Comment éviter : Exécutez toujours docker service ps <nom-du-service> avant et pendant le dépannage. Recherchez les tâches à l’état Running. Si les tâches échouent, inspectez les journaux avec docker service logs <nom-du-service>.
Propriété des décisions et cadence de revue
Dans un contexte d’équipe, plusieurs décisions et contrôles doivent avoir un propriétaire clair et un cycle de revue régulier.
| Décision ou contrôle | Rôle responsable | Fréquence de revue |
|---|---|---|
| Topologie réseau et conception de l’overlay | Responsable d’infrastructure (par ex., Priya Shah, responsable ingénierie) | Trimestrielle ou lors d’un changement majeur d’architecture |
| Création des secrets et politique de rotation | Ingénieur sécurité (par ex., Marcus Chen, ingénieur sécurité) | Tous les 6 mois ou après toute exposition suspectée |
| Rattachements réseau et expositions de ports des services | Propriétaire d’application (par ex., David Kim, responsable backend) | À chaque planification de sprint ou lors d’un changement de spécification du service |
| Règles de pare-feu pour les hôtes Docker | Administrateur systèmes (par ex., Elena Rodriguez, administrateur systèmes) | Mensuelle ou après tout changement d’infrastructure |
| Mise à jour du manuel de dépannage | Ingénieur DevOps (par ex., Tom Okafor, ingénieur DevOps) | Après chaque incident majeur ou trimestrielle |
La fréquence peut être ajustée à la taille de votre équipe et à votre profil de risque, mais avoir une personne nommée évite le problème du « tout le monde pensait que quelqu’un d’autre le faisait ».
Liste de contrôle des opérations
Utilisez cette liste de contrôle face à un problème réseau avec les secrets Docker. Parcourez-la dans l’ordre et documentez ce que vous trouvez à chaque étape.
| Étape | Action | Commande ou détails | Propriétaire |
|---|---|---|---|
| 1 | Vérifier les versions de Docker et de Swarm | docker version, docker info | Ingénieur d’astreinte |
| 2 | Lister les nœuds et les réseaux | docker node ls, docker network ls | Ingénieur d’astreinte |
| 3 | Inspecter la configuration du service | docker service inspect --pretty <service> | Propriétaire d’application |
| 4 | Vérifier les montages de secrets | docker service inspect --format '{{json .Spec.TaskTemplate.ContainerSpec.Secrets}}' <service> | jq . | Ingénieur sécurité |
| 5 | Créer un service de test sur le même réseau | docker service create --name test-<problème> --network <réseau> alpine sleep 3600 | Ingénieur d’astreinte |
| 6 | Tester la résolution DNS | nslookup <service> dans le conteneur de test | Ingénieur d’astreinte |
| 7 | Tester la connectivité des ports | nc -zv <service> <port> dans le conteneur de test | Ingénieur d’astreinte |
| 8 | Vérifier le routage | ping, ip route, traceroute | Ingénieur d’astreinte |
| 9 | Vérifier les règles de pare-feu | sudo iptables -L DOCKER-USER -n -v sur les hôtes concernés | Administrateur systèmes |
| 10 | Examiner les journaux du service | docker service logs <service> | Propriétaire d’application |
| 11 | Tenter la récupération | Appliquer le correctif pertinent de la section Modes de défaillance | Propriétaire d’application ou astreinte |
| 12 | Confirmer le plan de retour en arrière | docker service rollback <service> disponible, sauvegarde réseau enregistrée | Ingénieur d’astreinte |
Après avoir résolu le problème, mettez à jour le manuel avec les nouvelles découvertes, et si un retour en arrière a été utilisé, planifiez un suivi pour mettre en œuvre un correctif permanent.
Conclusion
Le dépannage des problèmes réseau des secrets Docker n’est pas de la magie. C’est un processus méthodique d’élimination des couches. Commencez par une base de référence : confirmez les versions, la santé du Swarm et la topologie réseau. Inspectez ensuite la configuration du service, y compris les montages de secrets et les rattachements réseau. Utilisez un conteneur de test sur le même réseau overlay pour isoler les problèmes de DNS, de ports et de routage. Vérifiez les pare-feu des hôtes, car ils sont souvent négligés. Quand vous trouvez la cause profonde, appliquez un correctif ciblé et ayez toujours un plan de retour en arrière.
N’oubliez pas de garder le service de test isolé de la production. Utilisez la liste de contrôle des opérations comme aide-mémoire et attribuez des propriétaires clairs pour les contrôles récurrents. Avec la pratique, vous diagnostiquerez la plupart des problèmes réseau en minutes plutôt qu’en heures, et garderez vos secrets et vos services fonctionnant sans accroc.
Commencez par un pilote étroit : choisissez un service et un réseau, vérifiez la connectivité locale, puis étendez le test. Cette approche limite les risques et renforce la confiance dans le processus de dépannage.