Comment partager des données entre des conteneurs Docker sur Ubuntu 22.04

De Get Docs
Aller à :navigation, rechercher

Introduction

Docker est un outil de conteneurisation populaire utilisé pour fournir aux applications logicielles un système de fichiers contenant tout ce dont elles ont besoin pour fonctionner. L'utilisation de conteneurs Docker garantit que le logiciel se comportera de la même manière quel que soit l'endroit où il est déployé, car son environnement d'exécution est cohérent.

En général, les conteneurs Docker sont éphémères et s'exécutent aussi longtemps qu'il faut pour que la commande émise dans le conteneur se termine. Parfois, cependant, les applications doivent partager l'accès aux données ou conserver les données après la suppression d'un conteneur. Les bases de données, le contenu généré par l'utilisateur pour un site Web et les fichiers journaux ne sont que quelques exemples de données peu pratiques ou impossibles à inclure dans une image Docker, mais auxquelles les applications doivent accéder. Un accès permanent aux données est fourni avec Docker Volumes.

Les volumes Docker peuvent être créés et attachés dans la même commande qui crée un conteneur, ou ils peuvent être créés indépendamment de tout conteneur et attachés ultérieurement. Dans cet article, vous allez examiner quatre façons différentes de partager des données entre conteneurs.

Conditions préalables

Pour suivre cet article, vous aurez besoin d'un serveur Ubuntu 22.04 avec les éléments suivants :

Remarque : Même si les prérequis donnent des instructions pour installer Docker sur Ubuntu 22.04, les commandes docker pour les volumes de données Docker dans cet article devraient fonctionner sur d'autres systèmes d'exploitation tant que Docker est installé et que L'utilisateur sudo a été ajouté au groupe docker.


Étape 1 - Création d'un volume indépendant

Introduite dans la version 1.9 de Docker, la commande docker volume create vous permet de créer un volume sans le lier à un conteneur particulier. Vous utiliserez cette commande pour ajouter un volume nommé DataVolume1 :

docker volume create --name DataVolume1

Le nom s'affiche, indiquant que la commande a réussi :

OutputDataVolume1

Pour utiliser le volume, vous allez créer un nouveau conteneur à partir de l'image Ubuntu, en utilisant le drapeau --rm pour le supprimer automatiquement lorsque vous quittez. Vous utiliserez également -v pour monter le nouveau volume. -v nécessite le nom du volume, deux-points, puis le chemin absolu vers l'endroit où le volume doit apparaître à l'intérieur du conteneur. Si les répertoires du chemin n'existent pas dans le cadre de l'image, ils seront créés lors de l'exécution de la commande. S'ils existent, le volume monté masquera le contenu existant :

docker run -ti --rm -v DataVolume1:/datavolume1 ubuntu

Dans le conteneur, écrivez des données sur le volume :

echo "Example1" > /datavolume1/Example1.txt

Parce que vous avez utilisé le drapeau --rm, votre conteneur sera automatiquement supprimé lorsque vous quitterez. Votre volume, cependant, sera toujours accessible.

exit

Vous pouvez vérifier que le volume est présent sur votre système avec docker volume inspect :

docker volume inspect DataVolume1
Output[
    {
        "CreatedAt": "2018-07-11T16:57:54Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/DataVolume1/_data",
        "Name": "DataVolume1",
        "Options": {},
        "Scope": "local"
    }
]

Remarque : Vous pouvez même consulter les données sur l'hôte au chemin indiqué sous la forme Mountpoint. Vous devez toutefois éviter de le modifier, car cela peut entraîner une corruption des données si les applications ou les conteneurs ne sont pas conscients des modifications.


Ensuite, démarrez un nouveau conteneur et attachez DataVolume1 :

docker run --rm -ti -v DataVolume1:/datavolume1 ubuntu

Vérifiez le contenu :

cat /datavolume1/Example1.txt
OutputExample1

Quittez le conteneur :

exit

Dans cet exemple, vous avez créé un volume, l'avez attaché à un conteneur et vérifié sa persistance.

Étape 2 - Création d'un volume qui persiste lorsque le conteneur est supprimé

Dans l'exemple suivant, vous allez créer un volume en même temps que le conteneur, supprimer le conteneur, puis attacher le volume à un nouveau conteneur.

Vous utiliserez la commande docker run pour créer un nouveau conteneur à l'aide de l'image Ubuntu de base. -t nous donnera un terminal, et -i nous permettra d'interagir avec lui. Pour plus de clarté, vous utiliserez --name pour identifier le conteneur.

Le drapeau -v nous permettra de créer un nouveau volume, que vous appellerez DataVolume2. Vous utiliserez deux points pour séparer ce nom du chemin où le volume doit être monté dans le conteneur. Enfin, vous allez spécifier l'image de base Ubuntu et compter sur la commande par défaut dans le fichier Docker de l'image de base Ubuntu, bash, pour nous déposer dans un shell :

docker run -ti --name=Container2 -v DataVolume2:/datavolume2 ubuntu

Remarque : L'indicateur -v est très flexible. Il peut lier ou nommer un volume avec juste un léger ajustement de la syntaxe. Si le premier argument commence par un / ou ~/, vous créez un bindmount. Supprimez cela et vous nommez le volume. Par example:

  • -v /path:/path/in/container monte le répertoire hôte, /path sur le /path/in/container
  • -v path:/path/in/container crée un volume nommé path sans relation avec l'hôte.

Pour plus d'informations sur le montage lié d'un répertoire à partir de l'hôte, consultez Comment partager des données entre un conteneur Docker et l'hôte


Dans le conteneur, vous allez écrire des données sur le volume :

echo "Example2" > /datavolume2/Example2.txt
cat /datavolume2/Example2.txt
OutputExample2

Quittez le conteneur :

exit

Lorsque vous redémarrez le conteneur, le volume se monte automatiquement :

docker start -ai Container2

Vérifiez que le volume est bien monté et que vos données sont toujours en place :

cat /datavolume2/Example2.txt
OutputExample2

Enfin, sortez et nettoyez :

exit

Docker ne nous laissera pas supprimer un volume s'il est référencé par un conteneur. Pour voir ce qui se passe, essayez :

docker volume rm DataVolume2

Le message nous indique que le volume est toujours utilisé et fournit la version longue de l'ID du conteneur :

OutputError response from daemon: unable to remove volume: remove DataVolume2: volume is in use - [d0d2233b668eddad4986313c7a4a1bc0d2edaf0c7e1c02a6a6256de27db17a63]

Vous pouvez utiliser l'ID du message d'erreur ci-dessus pour supprimer le conteneur :

docker rm d0d2233b668eddad4986313c7a4a1bc0d2edaf0c7e1c02a6a6256de27db17a63
Outputd0d2233b668eddad4986313c7a4a1bc0d2edaf0c7e1c02a6a6256de27db17a63

Le retrait du conteneur n'affectera pas le volume. Vous pouvez voir qu'il est toujours présent sur le système en répertoriant les volumes avec docker volume ls :

docker volume ls
OutputDRIVER              VOLUME NAME
local               DataVolume2

Et vous pouvez utiliser docker volume rm pour le supprimer :

docker volume rm DataVolume2

Dans cet exemple, vous avez créé un volume de données vide en même temps que vous avez créé un conteneur. Dans votre prochain exemple, vous explorerez ce qui se passe lorsque vous créez un volume avec un répertoire de conteneur qui contient déjà des données.

Étape 3 - Création d'un volume à partir d'un répertoire existant avec des données

Généralement, créer un volume indépendamment avec docker volume create et en créer un pendant la création d'un conteneur sont équivalents, à une exception près. Si vous créez un volume en même temps que vous créez un conteneur et vous fournissez le chemin d'accès à un répertoire qui contient des données dans l'image de base, ces données seront copiées dans le volume.

Par exemple, vous allez créer un conteneur et ajouter le volume de données à /var, un répertoire qui contient des données dans l'image de base :

docker run -ti --rm -v DataVolume3:/var ubuntu

Tout le contenu du répertoire /var de l'image de base est copié dans le volume, et vous pouvez monter ce volume dans un nouveau conteneur.

Quittez le conteneur actuel :

exit

Cette fois, plutôt que de vous fier à la commande bash par défaut de l'image de base, vous lancerez votre propre commande ls, qui affichera le contenu du volume sans entrer dans le shell :

docker run --rm -v DataVolume3:/datavolume3 ubuntu ls datavolume3

Le répertoire datavolume3 a maintenant une copie du contenu du répertoire /var de l'image de base :

Outputbackups
cache
lib
local
lock
log
mail
opt
run
spool
tmp

Il est peu probable que vous vouliez monter /var/ de cette manière, mais cela peut être utile si vous avez créé votre propre image et souhaitez un moyen simple de conserver les données. Dans votre prochain exemple, vous montrerez comment un volume peut être partagé entre plusieurs conteneurs.

Étape 4 - Partage de données entre plusieurs conteneurs Docker

Jusqu'à présent, vous avez attaché un volume à un conteneur à la fois. Souvent, vous souhaiterez que plusieurs conteneurs soient attachés au même volume de données. C'est relativement simple à réaliser, mais il y a une mise en garde critique : pour le moment, Docker ne gère pas le verrouillage des fichiers. Si vous avez besoin de plusieurs conteneurs écrivant sur le volume, les applications s'exécutant dans ces conteneurs doivent être conçues pour écrire dans des magasins de données partagés afin d'empêcher la corruption des données.

Créer Container4 et DataVolume4

Utilisez docker run pour créer un nouveau conteneur nommé Container4 avec un volume de données attaché :

docker run -ti --name=Container4 -v DataVolume4:/datavolume4 ubuntu

Ensuite, vous allez créer un fichier et ajouter du texte :

echo "This file is shared between containers" > /datavolume4/Example4.txt

Ensuite, vous quitterez le conteneur :

exit

Cela nous ramène à l'invite de commande de l'hôte, où vous allez créer un nouveau conteneur qui monte le volume de données à partir de Container4.

Créer Container5 et monter des volumes à partir de Container4

Vous allez créer Container5 et monter les volumes à partir de Container4 :

docker run -ti --name=Container5 --volumes-from Container4 ubuntu

Vérifiez la persistance des données :

cat /datavolume4/Example4.txt
OutputThis file is shared between containers

Maintenant, ajoutez du texte de Container5 :

echo "Both containers can write to DataVolume4" >> /datavolume4/Example4.txt

Enfin, vous quitterez le conteneur :

exit

Ensuite, vous vérifierez que vos données sont toujours présentes sur Container4.

Afficher les modifications apportées au conteneur5

Maintenant, vérifiez les modifications qui ont été écrites sur le volume de données par Container5 en redémarrant Container4 :

docker start -ai Container4

Vérifiez les modifications :

cat /datavolume4/Example4.txt
OutputThis file is shared between containers
Both containers can write to DataVolume4

Maintenant que vous avez vérifié que les deux conteneurs pouvaient lire et écrire à partir du volume de données, vous allez quitter le conteneur :

exit

Encore une fois, Docker ne gère aucun verrouillage de fichier, donc les applications doivent prendre en compte le verrouillage de fichier elles-mêmes. Il est possible de monter un volume Docker en lecture seule pour s'assurer que la corruption des données ne se produira pas par accident lorsqu'un conteneur nécessite un accès en lecture seule en ajoutant :ro. Vous allez maintenant voir comment cela fonctionne.

Démarrer le conteneur 6 et monter le volume en lecture seule

Une fois qu'un volume a été monté dans un conteneur, plutôt que de le démonter comme vous le feriez avec un système de fichiers Linux typique, vous pouvez à la place créer un nouveau conteneur monté comme vous le souhaitez et, si nécessaire, supprimer le conteneur précédent. Pour rendre le volume en lecture seule, vous ajoutez :ro à la fin du nom du conteneur :

docker run -ti --name=Container6 --volumes-from Container4:ro ubuntu

Vous vérifierez l'état en lecture seule en essayant de supprimer votre fichier d'exemple :

rm /datavolume4/Example4.txt
Outputrm: cannot remove '/datavolume4/Example4.txt': Read-only file system

Enfin, vous allez quitter le conteneur et nettoyer vos conteneurs et volumes de test :

exit

Maintenant que vous avez terminé, nettoyez vos conteneurs et votre volume :

docker rm Container4 Container5 Container6
docker volume rm DataVolume4

Dans cet exemple, vous avez montré comment partager des données entre deux conteneurs à l'aide d'un volume de données et comment monter un volume de données en lecture seule.

Conclusion

Dans ce didacticiel, vous avez créé un volume de données qui permettait aux données de persister grâce à la suppression d'un conteneur. Vous avez partagé des volumes de données entre conteneurs, avec la mise en garde que les applications devront être conçues pour gérer le verrouillage des fichiers afin d'éviter la corruption des données. Enfin, vous avez montré comment monter un volume partagé en mode lecture seule. Si vous souhaitez en savoir plus sur le partage de données entre les conteneurs et le système hôte, consultez Comment partager des données entre le conteneur Docker et l'hôte.