Les conteneurs Docker sont des environnements intentionnellement isolés. Chaque conteneur a son propre système de fichiers auquel les autres conteneurs ou votre hôte ne peuvent pas accéder directement.
Parfois, les conteneurs peuvent avoir besoin de partager des données. Bien que vous deviez viser l’autosuffisance des conteneurs, il existe des scénarios où le partage de données est inévitable. Cela peut être pour qu’un deuxième conteneur puisse accéder à un cache combiné, utiliser une base de données basée sur des fichiers, créer une sauvegarde ou effectuer des opérations sur des données générées par l’utilisateur, comme un conteneur d’optimiseur d’image qui traite les photos de profil téléchargées via un conteneur de serveur Web distinct. .
Dans ce guide, nous examinerons quelques méthodes pour transmettre des données entre vos conteneurs Docker. Nous supposerons que vous avez déjà configuré Docker et que vous êtes familiarisé avec les concepts fondamentaux tels que les conteneurs, les images, les volumes et les réseaux.
Utiliser des volumes pour partager un répertoire
Les volumes sont le moyen de facto de configurer le partage de données. Ce sont des systèmes de fichiers indépendants qui stockent leurs données en dehors de tout conteneur individuel. Le montage d’un volume sur un chemin de système de fichiers dans un conteneur fournit un accès en lecture-écriture aux données du volume.
Les volumes peuvent être attachés à plusieurs conteneurs simultanément. Cela facilite le partage et la persistance transparents des données gérées par Docker.
Créez un volume pour commencer :
docker volume create --name shared-data
Créez ensuite vos conteneurs, en montant le volume sur le chemin du système de fichiers attendu par chaque image :
docker run -d -v shared-data:/data --name example example-image:latest docker run -d -v shared-data:/backup-source --name backup backup-image:latest
Dans cet exemple, le backup
conteneur aura un accès effectif au example
le conteneur /data
annuaire. Il sera monté comme /backup-source
; les modifications apportées par l’un des conteneurs seront répercutées dans l’autre.
Démarrer rapidement des conteneurs avec des volumes correspondants
L’exemple ci-dessus pourrait être simplifié en utilisant le docker run
commande --volumes-from
drapeau. Cela fournit un mécanisme pour monter automatiquement les volumes qui sont déjà utilisés par un conteneur existant :
docker run -d --volumes-from example --name backup backup-image:latest
Cette fois le backup
conteneur recevra le shared-data
volume monté dans son /data
annuaire. le --volumes-from
flag extrait toutes les définitions de volume attachées au example
récipient. Il est particulièrement idéal pour les tâches de sauvegarde et autres conteneurs de courte durée qui servent de composants auxiliaires à votre service principal.
Améliorer la sécurité avec les supports en lecture seule
Les volumes sont toujours montés en mode lecture-écriture par défaut. Tous vos conteneurs ayant accès à un volume sont autorisés à modifier son contenu, ce qui peut entraîner une perte de données involontaire.
Il est recommandé de monter des volumes partagés en mode lecture seule lorsqu’un conteneur n’est pas censé apporter de modifications. Dans l’exemple ci-dessus, le backup
le conteneur n’a besoin que de lire le contenu du shared-data
le volume. Définir le montage en mode lecture seule renforce cette attente, empêchant les bogues ou les binaires malveillants dans l’image de supprimer les données utilisées par le example
récipient.
docker run -d -v shared-data:/backup-source:ro --name backup backup-image:latest
Ajouter ro
comme troisième paramètre séparé par des deux-points au -v
flag indique que le volume doit être monté en mode lecture seule. Vous pouvez également écrire readonly
à la place de ro
comme alternative plus explicite.
Partage de données sur un réseau
Vous pouvez utiliser les échanges réseau comme approche alternative au partage de données via des volumes de système de fichiers. L’association de deux conteneurs au même réseau Docker leur permet de communiquer de manière transparente à l’aide de noms d’hôte attribués automatiquement :
docker network create demo-network docker run -d --net demo-network --name first example-image:latest docker run -d --net demo-network --name second another-image:latest
Ici first
pourra envoyer un ping second
et vice versa. Vos conteneurs pourraient exécuter un service d’API HTTP leur permettant d’interagir avec les données des autres.
Poursuivant l’exemple de sauvegarde, maintenant votre backup
conteneur pourrait faire une demande de réseau à http://example:8080/backup-data
pour acquérir les données à sauvegarder. le example
conteneur doit répondre avec une archive contenant toutes les données qui doivent être stockées. Le conteneur de sauvegarde est alors responsable de la persistance de l’archive dans un emplacement de stockage approprié.
L’application du partage des données sur un réseau facilite souvent les efforts de découplage. Vous vous retrouvez avec des interfaces clairement définies qui ne créent pas de dépendances dures entre les services. L’accès aux données peut être contrôlé plus précisément en exposant des API pour chaque type de données, au lieu de donner à chaque conteneur un accès total à un volume.
Il est important de considérer la sécurité si vous utilisez cette approche. Assurez-vous que les API HTTP conçues pour l’accès interne par vos autres conteneurs Docker n’ont pas de ports exposés sur le réseau de pont de votre hôte Docker. Il s’agit du comportement par défaut lors de l’utilisation des options réseau indiquées ci-dessus ; lier un port avec -p 8080:8080
permettrait l’accès à l’API de sauvegarde via les interfaces réseau de votre hôte. Ce serait un problème de sécurité.
Résumé
Les conteneurs Docker sont des environnements isolés qui ne peuvent pas accéder aux systèmes de fichiers des autres. Néanmoins, vous pouvez partager des données en créant un volume qui est monté dans tous les conteneurs participants. L’utilisation d’un réseau Docker partagé est une option alternative qui offre une séparation plus forte dans les scénarios où les interactions directes avec le système de fichiers ne sont pas nécessaires.
Il est recommandé de limiter autant que possible les interactions entre les conteneurs. Les cas où vous avez besoin de partager des données doivent être clairement définis pour éviter de coupler étroitement vos services entre eux. Les conteneurs qui ont une dépendance rigide sur les données de une autre conteneur peut être plus difficile à déployer et à maintenir au fil du temps, érodant les avantages plus larges de la conteneurisation et de l’isolement.