Docker Volumes et Binds

Quel que soit le type de montage que vous choisissez d’utiliser, les données ont la même apparence depuis le conteneur. Il est exposé sous forme de répertoire ou de fichier individuel dans le système de fichiers du conteneur.

Un moyen simple de visualiser la différence entre les volumes, les montages de liaison (binds) et les montages tmpfs consiste à déterminer l’emplacement des données sur l’hôte Docker.

Les volumes sont stockés dans une partie du système de fichiers hôte géré par Docker (/var/lib/docker/volumes/ sous Linux). Les processus autres que Docker ne doivent pas modifier cette partie du système de fichiers. Les volumes constituent le meilleur moyen de conserver des données dans Docker.

Les montages liés (binds) peuvent être stockés n’importe où sur le système hôte. Il peut même s’agir de fichiers système ou de répertoires importants. Les processus non-Docker sur l’hôte Docker ou un conteneur Docker peuvent les modifier à tout moment.

In a nutshell

De façon générale

  • On utilise un bind quand il y a de l’existant sur la machine locale qui doit être traité par un container
    • site web, vidéo, photo, images, …
    • @todo La commande est ....
  • On utilise un volume quand c’est le container qui va générer des données (qui doivent être conservées)
    • logs, statistiques, databases …
    • @todo La commande est ....

Il est important de souligner que les volumes sont gérés intégralement par Docker et que les autres process sur le système ne peuvent altérer les fichiers. Le bind de son côté est altérable.

Même si avec un volume local on peut aller fouiller dans les dossiers de Docker, deviner le hash qui correspond aux volumes et modifier les fichiers dedans reste néanmoins possible.

Exemple

Que choisir, volumes ou les binds dans le cadre d’un site web par exemple ?
Avec un site qui sera hébergé sur l’hôte dans /home/john/lesite.com/www et un container Nginx.

  • Pour cet exemple ça serait un bind, vu qu’on veut qu’un dossier précis soit disponible dans le conteneur.
    Un bind c’est “je veux que ce dossier/fichier local arrive là dans mon conteneur”.
  • Un volume c’est comme un bind, sauf qu’ont ne sait pas où c’est sauvegardé sur la machine.
    Un volume c’est “je veux que ce dossier dans le conteneur survive quand je tue le conteneur, mais je m’en fous d’où c’est stocké”
    Un volume ne copie pas de données depuis l’hôte.

Volume de données

L’idée est de stocker les données dans un répertoire spécifique du serveur hôte Docker plutôt que dans le système de fichiers par défaut du conteneur. Ce stockage externe, appelé volume de données, permet de rendre les données indépendantes de la vie du conteneur. Le volume permet également de partager ces données entre plusieurs conteneurs.

Le volume de données dans Docker propose ces fonctionnalités :

  • Le volume est initialisé à la création du conteneur. Si l’image de base contient déjà des données à l’initialisation du volume, alors elles seront copiées dans le volume.
  • Un volume de données peut être partagé ou réutilisé par plusieurs conteneurs.
  • Les changements dans le volume de données sont appliqués immédiatement.
  • Le volume de données est persistant même si le conteneur lui-même est supprimé.

Ajout manuel

L’option -v permet de rajouter des volumes :

1
2
3
# docker run -d -v /var/log debian:stable /bin/sleep volumedocker1 // je pige pas à quoi sert le dernier param
# docker run -d -v /var/log -v /home debian.cosmetic.nginx /bin/sleep volumedocker2
# docker run -it -v /var/log/nginx -v /home --name container.03.nginx debian.cosmetic.nginx // marche tres biens ans

Ajout dans le dockerfile

L’option à ajouter est VOLUME :

1
VOLUME /var/log

Où se trouvent les données

La commande inspect nous fournira l’emplacement, dans la catégories “volumes”.

1
# docker inspect <ID or NAME container>

Résultats :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
"Mounts": [
{
"Type": "volume",
"Name": "13a30c61866afbb027b88b8f46f51617636abcc221ffbbdba480dffdf5634c86",
"Source": "/var/lib/docker/volumes/13a30c61866a...6f51617636abcc221ffbbdba480dffdf5634c86/_data",
"Destination": "/var/log",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "4e774765ddb90de5943073b4dff11c77220ae63d14658669687b89d59029813b",
"Source": "/var/lib/docker/volumes/4e774765ddb0...43073b4dff11c77214658669687b89d59029813b/_data",
"Destination": "/home",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],

Maintenant la modification des dossier /var/log et /home peut se faire dans le container et sur la machine hôte.

Lier un répertoire choisi

Lancer un container et lier un volume. La machine hôte et le container partageront le même dossier tools. Sur l’hôte il se situe dans /root/tools, dans le container il se situe dans /home/tools

1
2
# docker run -v /chemin/hôte:/chemin/container -it --name <NomNouveauContainer> <NomImage>
# docker run -v /root/tools:/home/tools -it --name testBind debian

Les Binds

Les montages liés (binds) ont des fonctionnalités limitées par rapport aux volumes. Lorsque vous utilisez un montage de liaison, un fichier ou un répertoire sur la machine hôte est monté dans un conteneur. Le fichier ou le répertoire est référencé par son chemin complet sur la machine hôte. Le fichier ou le répertoire n’a pas besoin d’exister déjà sur l’hôte Docker. Il est créé à la demande s’il n’existe pas encore.
Les montages de liaison sont très performants, mais ils reposent sur le système de fichiers de la machine hôte disposant d’une structure de répertoires spécifique. Si vous développez de nouvelles applications Docker, envisagez plutôt d’utiliser des volumes nommés. Vous ne pouvez pas utiliser les commandes CLI de Docker pour gérer directement les montages de liaisons.

Les montages liés permettent l’accès aux fichiers sensibles

L’utilisation des montages liés, pour le meilleur ou pour le pire, a notamment pour effet secondaire de modifier le système de fichiers hôte via des processus exécutés dans un conteneur, notamment la création, la modification ou la suppression de fichiers système ou de répertoires importants. Il s’agit d’une capacité puissante qui peut avoir des conséquences sur la sécurité, notamment sur les processus autres que Docker sur le système hôte.

Faire un script qui permette de copier entre container

Because copying between containers is not supported ! (message d’erreur après un test en 2 containers).

1
2
3
4
5
6
7
8
9
10
cpContainer <container1>:<path1> <container2>:<path>

Creer un dossier temp
se connecter au container 1
accède au path1
copie le contenu
colle le contenu dans le dosser temp
utilise docker cp pour copier le contenu de temp vers <container2>:<path>
supprime le dossier temp et son contenu
fin

Documentation

https://docs.docker.com/storage/volumes/
https://www.nginx.com/blog/deploying-nginx-nginx-plus-docker/
https://stackoverflow.com/questions/44290211/docker-compose-v3-the-difference-between-volume-type-mount-and-bind

Partager