Introduction
La planification de capacité des secrets Docker avec des exemples pratiques signifie passer d'un problème observé à un résultat vérifié. Vous devez commencer par identifier la version de Docker installée, la topologie de déploiement (Swarm, Compose ou autonome), le système d'exploitation et le noyau, ainsi que le composant exact que vous inspectez. Ne devinez pas : exécutez d'abord une commande en lecture seule, enregistrez l'état actuel, puis décidez si un changement est justifié.
Cet article s'adresse aux développeurs, consultants DevOps et équipes techniques de startups qui doivent planifier la capacité des secrets avant qu'elle ne devienne un goulot d'étranglement. Il relie la mise à l'échelle, les ressources, les limites et le dimensionnement des secrets Docker à des commandes concrètes, des résultats attendus, des signaux d'échec et des décisions de récupération. L'objectif est la sécurité opérationnelle : observer avant de changer, limiter le rayon d'impact, utiliser des espaces réservés au lieu de secrets réels dans les exemples, vérifier le résultat et documenter comment récupérer si l'état attendu n'est pas atteint.
Les secrets Docker sont une fonctionnalité du mode Docker Swarm et, avec l'élément de niveau supérieur secrets de Compose, ils peuvent être utilisés avec docker compose même sur un nœud unique. Les secrets sont stockés chiffrés dans le journal Raft et mis à disposition des services sous forme de fichiers dans /run/secrets/. La planification de capacité implique de comprendre combien de secrets un service peut monter, quelle taille un secret peut avoir, combien de services peuvent utiliser un secret, comment le chiffrement et la rotation affectent les performances, et comment surveiller la saturation.
Inventaire des versions et de l'environnement
Avant de dimensionner quoi que ce soit, confirmez la version de Docker, le mode d'exécution et le pilote de stockage. C'est essentiel car les limites de taille des secrets et le comportement diffèrent entre les versions de Docker et entre Swarm et Compose. Exécutez les vérifications en lecture seule suivantes :
docker version --format '{{.Server.Version}}'
docker info --format '{{.Swarm.LocalNodeState}} {{.Driver}}'
Le résultat attendu doit montrer la version du serveur (par exemple, 24.0.7) et soit active pour un nœud Swarm actif, soit inactive si vous n'êtes pas en mode Swarm. Si le nœud n'est pas en mode Swarm, les commandes docker secret échoueront avec Error response from daemon: This node is not a swarm manager.
Si vous utilisez Docker Compose, vérifiez la version du plugin Compose :
docker compose version
Sortie typique : Docker Compose version v2.23.0. Compose ne prend en charge les secrets qu'avec la spécification Compose et un runtime compatible ; l'ancien docker-compose (v1) ne prend pas en charge les secrets.
Confirmez où les secrets existants sont stockés et comment ils sont montés. Listez les secrets avec :
docker secret ls
Colonnes de sortie : ID, NAME, CREATED, UPDATED. Par exemple :
ID NAME CREATED UPDATED
vqj0f2a7x4n9k3p1m8t5r6w db_password 2 days ago 2 days ago
Inspectez les métadonnées d'un secret spécifique (pas sa valeur) :
docker secret inspect db_password
Cela renvoie du JSON avec ID, Version, CreatedAt, UpdatedAt et Spec.Name. La valeur réelle du secret n'est jamais affichée.
Pour un projet Compose, listez les secrets définis dans le fichier compose et leurs fichiers :
docker compose config --secrets
Cela révèle combien de secrets sont reliés aux services et si certains ne sont pas utilisés.
Lorsque des données sont impliquées, confirmez où les fichiers sont stockés avant de modifier les conteneurs. Les secrets Docker ne sont pas stockés dans un volume nommé ; ils sont chiffrés dans le journal Raft et montés en tmpfs à /run/secrets/<nom_du_secret> dans le conteneur. Un montage de liaison ou un volume peut être utilisé pour les données applicatives, mais les secrets doivent toujours utiliser le mécanisme des secrets Docker, jamais des variables d'environnement ou des fichiers intégrés à l'image.
Par exemple, un service défini comme suit :
services:
db:
image: postgres:16
secrets:
- db_password
secrets:
db_password:
file: ./secrets/db_password.txt
auras le secret disponible à /run/secrets/db_password dans le conteneur db. Vérifiez avec :
docker compose exec db ls -l /run/secrets/
Sortie attendue :
-r--r--r-- 1 root root 24 Jan 15 10:00 db_password
Le fichier est en lecture seule et appartient à root. Si l'application s'exécute en tant qu'utilisateur non root, vous devrez peut-être ajuster la propriété ou utiliser un groupe avec accès en lecture, comme expliqué plus loin.
Dans le cadre de l'inventaire de l'environnement, effectuez un test de redémarrage : créez un service, ajoutez un secret, arrêtez le conteneur, recréez-le et confirmez que l'application voit toujours le secret. Pour Swarm :
docker service create --name secret-test --secret db_password alpine sleep 3600
docker service ps secret-test
docker service rm secret-test
docker service create --name secret-test --secret db_password alpine sleep 3600
Ensuite, exécutez une commande dans le nouveau conteneur et vérifiez que /run/secrets/db_password existe. Si le secret est manquant, la définition du service ou la référence du secret est incorrecte.
Comprendre les limites et le dimensionnement des secrets Docker
Les secrets Docker ont des limites documentées et non documentées qui affectent directement la planification de capacité. Les deux limites strictes sont :
- Taille maximale d'un secret : 500 Ko par secret. Ceci est appliqué par l'API ; toute tentative de créer un secret plus grand renvoie
Error response from daemon: rpc error: code = InvalidArgument desc = invalid secret: exceeds maximum size of 500KB. - Nombre maximal de secrets par service : aucune limite stricte officielle, mais la limite pratique est déterminée par la taille totale des tmpfs montés et les limites de mémoire du conteneur. Chaque secret monté consomme de la mémoire dans le tmpfs du conteneur. Pour un service avec 10 secrets de 100 Ko chacun, le tmpfs utilise au moins 1 Mo de mémoire, plus les frais généraux.
Swarm stocke les secrets dans le journal Raft, qui est répliqué sur tous les nœuds managers. Un secret de 500 Ko est stocké dans Raft, et chaque manager en conserve une copie. Si vous avez 5 managers et 10 secrets de ce type, cela représente 25 Mo de stockage Raft uniquement pour les secrets. La taille du journal Raft peut affecter les performances s'il devient trop volumineux ; Docker recommande de maintenir le journal Raft en dessous de quelques centaines de mégaoctets.
Pour vérifier la taille actuelle du journal Raft sur un manager :
du -sh /var/lib/docker/swarm/raft/
Si le répertoire dépasse les attentes, inspectez le nombre et la taille des secrets :
docker secret ls -q | xargs -I {} sh -c 'docker secret inspect {} | jq -r ".[0].Spec.Name, .[0].ID"'
Mais les valeurs des secrets ne sont pas stockées en clair sur le disque, donc leurs tailles individuelles ne sont pas directement exposées. Vous pouvez les approximer en lisant les fichiers sources avant de créer le secret. Utilisez des espaces réservés :
head -c 500K /dev/zero | base64 > secret_placeholder.txt
Créez ensuite le secret à partir de cet espace réservé pour tester la limite de l'API.
Pour les services, le montage tmpfs est dimensionné à la taille réelle du secret plus un petit surcoût. Docker ne permet pas de spécifier une taille tmpfs personnalisée pour les secrets. Si un secret fait 400 Ko, la taille du tmpfs est de 400 Ko plus quelques octets. Si un service monte plusieurs secrets, chacun reçoit son propre montage tmpfs, et l'utilisation totale de la mémoire est la somme des tailles des secrets plus le surcoût par montage (généralement 4 Ko par montage).
Exemple concret : un service monte 8 secrets de 200 Ko chacun. Total des données de secrets = 1,6 Mo. Surcoût par montage ~ 4 Ko, donc total ~ 1,632 Mo. Si le conteneur a une limite de mémoire de 64 Mo, cela représente moins de 3 % de la mémoire, négligeable. Mais si vous avez 50 services sur le même nœud montant chacun ces 8 secrets, la mémoire par conteneur reste faible, mais le stockage Raft sur les managers peut croître si les secrets sont volumineux et nombreux.
La surveillance de l'utilisation des secrets nécessite de vérifier le cgroup mémoire du conteneur pour les montages tmpfs. Utilisez docker stats ou docker inspect pour l'utilisation de la mémoire. Il n'y a pas de métrique intégrée spécifique au tmpfs des secrets, mais vous pouvez voir les montages :
docker inspect <container_id> | jq '.[0].Mounts[] | select(.Type=="tmpfs")'
La sortie montre Source, Destination, Type et Options. La Source est vide pour tmpfs ; les Options contiennent size si explicitement défini, mais pour les secrets, Docker le définit automatiquement. Si vous voyez size=524288 pour un secret de 512 Ko, cela confirme la taille du montage.
Chemin de configuration sûr
Lorsque vous modifiez les configurations de secrets, utilisez une approche par étapes : définissez le secret, affectez-le à un service de test, vérifiez, puis déployez en production. Suivez ces étapes :
- Créez un secret à partir d'un fichier ou de l'entrée standard. Utilisez un espace réservé pour les tests :
echo "test_secret_value" | docker secret create test_secret -
Cela évite de stocker la valeur réelle dans l'historique du shell. Pour un vrai secret, utilisez un fichier avec des permissions restreintes.
- Attachez le secret à un service dans un environnement de test :
docker service create --name test-app --secret test_secret alpine cat /run/secrets/test_secret
Résultat attendu : le service démarre et affiche test_secret_value, puis se termine. Vérifiez les journaux du service :
docker service logs test-app
- Vérifiez que le secret est monté et lisible, mais pas inscriptible :
docker exec $(docker ps -q --filter name=test-app) ls -l /run/secrets/test_secret
La sortie doit montrer -r--r--r--. Si l'application a besoin d'un accès en écriture, c'est un problème de conception ; les secrets sont destinés à être en lecture seule.
- Revenez en arrière si nécessaire : si le secret cause des problèmes, retirez le secret du service sans supprimer l'objet secret lui-même :
docker service update --secret-rm test_secret test-app
Puis observez. Pour supprimer entièrement le secret, assurez-vous d'abord qu'aucun service ne l'utilise :
docker secret rm test_secret
Si un service l'utilise encore, vous obtenez Error response from daemon: rpc error: code = InvalidArgument desc = secret 'test_secret' is in use by the following service: test-app.
Pour Compose, les modifications de configuration sont apportées dans le fichier YAML. Utilisez docker compose config pour valider avant d'appliquer :
docker compose config
Cela affiche la configuration résolue et détecte les erreurs de syntaxe ou les fichiers manquants. Ensuite, appliquez :
docker compose up -d
Si le fichier de secret change, vous devez recréer le service pour prendre en compte la nouvelle valeur du secret :
docker compose up -d --force-recreate
Docker ne met pas automatiquement à jour les conteneurs en cours d'exécution lorsqu'un fichier de secret change ; le contenu du secret est copié dans le Raft au moment de la création. Pour Swarm, la rotation d'un secret nécessite de créer un nouveau secret sous un nouveau nom et de mettre à jour le service pour l'utiliser, car les versions de secret sont immuables.
Vérification et diagnostics
La vérification de la livraison des secrets et des performances nécessite de vérifier trois niveaux : la santé du service, le montage du secret et la santé du Raft sur les managers.
Tout d'abord, confirmez que le service est en cours d'exécution et possède les références de secret attendues :
docker service inspect <service_name> --format '{{json .Spec.TaskTemplate.ContainerSpec.Secrets}}' | jq
La sortie est un tableau d'objets avec SecretID, SecretName et File.Name. Par exemple :
[
{
"File": {
"Name": "db_password",
"UID": "0",
"GID": "0",
"Mode": 292
},
"SecretID": "vqj0f2a7x4n9k3p1m8t5r6w",
"SecretName": "db_password"
}
]
Le Mode 292 est l'octal 0444 (lecture seule pour tous). Pour changer l'UID/GID ou le mode, vous pouvez les spécifier dans le fichier compose ou utiliser docker service update avec --secret-add et --secret-rm.
Ensuite, vérifiez que le secret est correctement monté dans le conteneur :
docker exec <container_id> cat /run/secrets/db_password
Cela doit afficher la valeur du secret. Si le fichier est vide ou si le chemin est incorrect, vérifiez la définition du service et la sensibilité à la casse du nom du secret (les noms de secret sont sensibles à la casse).
Pour les diagnostics lorsqu'un service ne démarre pas en raison d'un secret manquant, vérifiez les tâches du service :
docker service ps <service_name> --no-trunc
Recherchez les états Rejected ou Failed. Une erreur courante est secret not found: <name>, ce qui signifie que le secret a été supprimé ou n'a jamais été créé dans le swarm.
Surveillez la santé du Raft avec :
docker info | grep -A5 'Raft'
Recherchez Raft: Snapshot: ... et Nodes: .... Si le journal Raft est trop volumineux (des centaines de Mo), le manager peut devenir lent. Utilisez docker node ls pour vous assurer que tous les managers sont joignables.
Pour tester les limites de taille des secrets sans consommer d'espace, créez un secret d'espace réservé proche de 500 Ko :
head -c 499K /dev/urandom | base64 > /tmp/big_secret.txt
docker secret create big_secret /tmp/big_secret.txt
Si cela réussit, la taille du secret est dans la limite. Si vous essayez 501 Ko, cela échouera avec l'erreur mentionnée précédemment.
Modes de défaillance et récupération
Plusieurs modes de défaillance affectent la capacité et la disponibilité des secrets Docker.
Secret trop volumineux : la création d'un secret de plus de 500 Ko échoue. La tentative de création renvoie une erreur immédiatement, et aucun secret n'est créé. Récupération : réduisez la taille du secret en le divisant en plusieurs secrets ou en compressant les données si possible. N'essayez pas de contourner la limite en montant un fichier depuis un volume ; cela va à l'encontre de l'objectif des secrets.
Secret en cours d'utilisation ne peut pas être supprimé : docker secret rm échoue si un service référence le secret. Récupération : mettez à jour tous les services pour supprimer la référence au secret, puis supprimez le secret. Pour Swarm :
docker service update --secret-rm <nom_du_secret> <nom_du_service>
Pour Compose, supprimez le secret de la liste secrets: du service et exécutez docker compose up -d.
Rupture lors de la rotation des secrets : lorsque vous faites pivoter un secret en en créant un nouveau et en mettant à jour le service, le service peut redémarrer et échouer si l'application attend un nom de fichier spécifique. Récupération : utilisez le paramètre target dans les secrets pour contrôler le nom de fichier monté. Par exemple, dans Compose :
secrets:
db_password_v2:
file: ./new_password.txt
services:
db:
secrets:
- source: db_password_v2
target: db_password
Cela maintient le montage à /run/secrets/db_password même si le nom du secret a changé. Testez cela d'abord dans un environnement hors production.
Perte de secrets due à la perte de quorum des managers : si une majorité de nœuds managers sont perdus, le swarm perd le quorum et ne peut pas traiter de nouvelles créations ou mises à jour de secrets. Récupération : restaurez suffisamment de managers pour retrouver le quorum, ou forcez un nouveau cluster si tous les managers sont perdus, mais les secrets sont stockés dans Raft et peuvent être irrécupérables sans sauvegardes. Sauvegardez toujours le répertoire Raft (/var/lib/docker/swarm/) sur un manager, mais sachez qu'il contient des données de secret chiffrées ; la clé de chiffrement y est également stockée.
Le conteneur ne peut pas lire le secret en raison des permissions : le mode par défaut est 0444 (lecture seule pour tous), mais si vous définissez mode: 0400, seul root peut le lire. Si le conteneur s'exécute en tant que non-root et que vous n'avez pas défini UID/GID, l'application obtient une permission refusée. Récupération : définissez l'UID/GID sur l'utilisateur de l'application dans la définition du secret.
secrets:
app_secret:
file: ./secret.txt
uid: "1000"
gid: "1000"
mode: 0400
Recréez ensuite le service.
Pression mémoire due à de nombreux secrets : si un service monte des dizaines de secrets volumineux, les montages tmpfs consomment de la mémoire. Si le conteneur atteint sa limite de mémoire, il peut être tué par OOM. Récupération : réduisez le nombre de secrets ou leurs tailles, ou augmentez la limite de mémoire du conteneur. Surveillez avec docker stats et définissez des alertes.
Pièges courants et comment les éviter
- Utiliser des variables d'environnement pour les secrets : de nombreuses équipes commencent avec
environment: DB_PASSWORD=...puis essaient de passer aux secrets Docker. Le secret est visible dansdocker inspectet dans les listes de processus. À éviter en utilisant les secrets Docker dès le départ. Pour le développement local, utilisez un fichier.envgitignoré, mais en production, utilisez les secrets.
- Intégrer les secrets dans les images : coder en dur des informations d'identification dans un Dockerfile les copie dans les couches de l'image. Même si vous supprimez la ligne plus tard, le secret reste dans l'historique de l'image. Utilisez des constructions multi-étapes et évitez de copier des fichiers de secret dans l'image finale. Si vous devez utiliser un secret au moment de la construction, utilisez les secrets BuildKit avec
--mount=type=secret.
- Ne pas planifier la rotation : la rotation des secrets n'est pas automatique ; vous devez créer un nouveau secret et mettre à jour le service. Planifiez un calendrier de rotation (par exemple, tous les 90 jours) et automatisez le processus de mise à jour. Utilisez l'option
targetpour garder le nom de fichier stable. Documentez le responsable de la rotation (par exemple, « Priya Shah, responsable ingénierie ») et réexaminez-le mensuellement.
- Ignorer la croissance du stockage Raft : les secrets volumineux remplissent le journal Raft, provoquant un consensus plus lent et d'éventuels problèmes de disponibilité. Surveillez la taille de
/var/lib/docker/swarm/raftchaque semaine. Le responsable des opérations (par exemple, « rotation DevOps ») doit alerter à 200 Mo et agir à 500 Mo.
- Mélanger Compose v1 et v2 : l'ancien
docker-compose(v1) ne prend pas en charge les secrets, ce qui provoque des erreursunsupported Compose file version. Utilisez toujours le plugin Composedocker compose(v2). Exécutezdocker compose versionpour confirmer.
- Créer des secrets à partir de sources non contrôlées : si vous créez un secret à partir d'un fichier contenant un saut de ligne final, la valeur du secret inclut ce saut de ligne, ce qui peut casser les applications. Utilisez
printfau lieu deechopour éviter un saut de ligne supplémentaire, ou supprimez-le du fichier. Testez toujours avec un espace réservé connu.
- Négliger les collisions de noms de secrets : dans un swarm, les noms de secrets sont uniques. La création d'un secret avec un nom existant échoue avec
Error response from daemon: rpc error: code = AlreadyExists. Utilisez le versionnage dans les noms (par exemple,db_password_v1,db_password_v2) pour éviter les conflits lors de la rotation.
Liste de contrôle opérationnelle pour la capacité des secrets
Utilisez cette liste de contrôle avant de déployer ou de mettre à l'échelle les secrets. Chaque élément comprend une commande ou une action concrète, le résultat attendu et le responsable.
| Élément | Action | Résultat attendu | Responsable | Fréquence |
|---|---|---|---|---|
| Vérification de la version de Docker | docker version --format '{{.Server.Version}}' | Version >= 24.0 | Ingénieur de release | Mensuelle |
| Vérification du mode Swarm | docker info --format '{{.Swarm.LocalNodeState}}' | active ou intentionnellement inactif | Responsable DevOps | Hebdomadaire |
| Audit de la liste des secrets | docker secret ls | Aucun secret inutilisé de plus de 90 jours | Agent de sécurité | Trimestrielle |
| Audit de la taille des secrets | Pour chaque secret, vérifiez la taille du fichier source | Tous < 500 Ko, idéalement < 100 Ko | Propriétaire développeur | Mensuelle |
| Montages de secrets de service | docker service inspect <svc> --format '{{json .Spec.TaskTemplate.ContainerSpec.Secrets}}' | Seuls les secrets nécessaires sont montés | Propriétaire du service | Mensuelle |
| Taille du journal Raft | du -sh /var/lib/docker/swarm/raft | < 200 Mo | Propriétaire infrastructure | Hebdomadaire |
| Rotation de secrets / test | Créez un secret de test et attachez-le à un service de staging | Le service démarre et peut lire le secret | Responsable de release | À chaque rotation |
| Exercice de récupération | Simulez un secret manquant et restaurez en staging | Temps de récupération < 15 min | Ingénieur DevOps | Trimestrielle |
Chaque élément doit avoir un seul responsable imputable (pas un groupe), comme indiqué. Réexaminez le tableau mensuellement lors d'une réunion de préparation à la production.
Conclusion
La planification de capacité des secrets Docker n'est pas un calcul ponctuel ; elle nécessite une surveillance continue, une sensibilisation aux versions et une attribution claire des responsabilités. Les limites pratiques — 500 Ko par secret, croissance du stockage Raft, mémoire tmpfs et nombre de montages de service — ne sont utiles que lorsque vous les observez dans votre environnement.
Un flux de travail fiable rend les défaillances visibles : exécutez les commandes en lecture seule, enregistrez l'état actuel, effectuez un changement limité, vérifiez avec un signal concret et définissez la récupération avant qu'un incident ne force la décision. Protégez les valeurs sensibles en utilisant des espaces réservés dans les exemples et des secrets réels uniquement dans des fichiers contrôlés.
Documentez votre inventaire de secrets, votre calendrier de rotation et vos seuils de taille. Attribuez des responsables pour l'audit et la récupération. Testez la livraison des secrets dans un environnement de staging avec un redémarrage. Ces habitudes évitent les surprises et maintiennent votre planification de capacité fondée sur des données réelles plutôt que sur des suppositions.