J'ai réussi à partager des dossiers entre un conteneur Docker avec des volumes en utilisant
docker run -v /host/path:/container/path ...
Mais ma question est de savoir quelle est la différence entre cela et l'utilisation de la VOLUMEcommande dans le Dockerfile
VOLUME /path
J'utilise une image avec une VOLUMEcommande et j'aimerais savoir comment la partager avec mon hôte. Je l'ai fait en utilisant la -vcommande ci-dessus, mais je ne savais pas si j'avais besoin à la fois de -vet VOLUME.
La VOLUMEcommande montera un répertoire à l'intérieur de votre conteneur et stockera tous les fichiers créés ou modifiés dans ce répertoire sur votre disque hôte en dehors de la structure de fichiers du conteneur , en contournant le système de fichiers union.
L'idée est que vos volumes peuvent être partagés entre vos conteneurs docker et qu'ils resteront en place tant qu'il y aura un conteneur (en cours d'exécution ou arrêté) qui les référencera.
Vous pouvez demander à d'autres conteneurs de monter des volumes existants (en les partageant efficacement entre conteneurs) à l'aide de la --volumes-fromcommande lorsque vous exécutez un conteneur.
La différence fondamentale entre VOLUMEet -vest la suivante: -vva monter des fichiers existants de votre système d'exploitation à l' intérieur de votre conteneur docker et VOLUMEva créer un nouveau, le volume vide sur votre hôte et le monter à l' intérieur de votre récipient.
Exemple:
Vous avez un Dockerfile qui définit un fichier VOLUME /var/lib/mysql.
Vous créez l'image du docker et vous la marquez some-volume
Vous exécutez le conteneur
Puis,
Vous avez une autre image de menu fixe que vous souhaitez utiliser ce volume
Vous exécutez le conteneur Docker avec les éléments suivants:
docker run --volumes-from some-volume docker-image-name:tag
Maintenant, vous avez un conteneur docker en cours d'exécution qui aura le volume de some-volumemonté dans/var/lib/mysql
Remarque: Utiliser --volumes-frommontera le volume sur tout ce qui existe à l'emplacement du volume. Par exemple, si vous aviez /var/lib/mysqldu contenu, il sera remplacé par le contenu du volume.
Que se passe-t-il si j'utilise -v sur un répertoire déjà spécifié dans VOLUME?
Jeff Storey
6
--volumes-frommontera votre VOLUMEpar-dessus tout ce que vous spécifiez avec -v. Fait intéressant, il semble que l' exécution du conteneur en mode privilégié ( docker run --privileged) et umounting /var/lib/mysqlva juste laisser un répertoire vide de sorte que votre -vmonture est complètement ignoré quand il est en conflit avec VOLUME.
Chris McKinnel
2
Vous dites que les volumes sont conservés tant qu'un conteneur y fait référence, et j'ai vu cela ailleurs. docs.docker.com/userguide/dockervolumes dit: "Les volumes de données sont conçus pour conserver les données, indépendamment du cycle de vie du conteneur. Docker ne supprime donc jamais automatiquement les volumes lorsque vous supprimez un conteneur, et il ne" récupère pas "les volumes qui ne sont plus référencé par un conteneur. " L'une de ces déclarations doit être erronée.
mc0e
1
Les fichiers qui se trouvent dans le volume sont conservés sur le disque lorsqu'un conteneur ne le référence plus, mais le volume lui-même n'est plus utilisable (à moins que vous ne sachiez exactement comment connecter manuellement un volume à un conteneur, mais même dans ce cas, je ne le fais pas) t savoir si cela est possible). Quand je dis plus utilisable, je veux dire que vous ne pouvez pas utiliser --volumes-from pour l'utiliser. Lorsqu'ils disent «ramassage des ordures» ci-dessus, ils signifient supprimer les fichiers de votre disque qui se trouvaient dans le volume.
Chris McKinnel
1
Ils sont utilisables avec -v, mais pas avec --volumes-from. Volumes-from prend un nom de conteneur pour récupérer les données de volume (je crois que cela prend TOUS les points de volume). Pour -v lui-même, cependant, le manuel mentionne que vous pouvez fournir un volume nommé à -v sous la forme de named-volume:/path/in/container. Les volumes sans nom reçoivent des hachages pour les noms et ces hachages peuvent être fournis à la place d'un chemin d'hôte pour accéder aux volumes orphelins. :) Soyez conscient que volume lspeut ne pas les montrer tous - essayez docker volume ls -f dangling=trueaussi.
Jasmine Hegman
44
Permettez-moi d'ajouter ma propre réponse, car je pense que les autres manquent le point de Docker.
L'utilisation VOLUMEdans Dockerfile est la bonne façon ™, car vous faites savoir à Docker qu'un certain répertoire contient des données permanentes. Docker créera un volume pour ces données et ne le supprimera jamais, même si vous supprimez tous les conteneurs qui l'utilisent.
Il contourne également le système de fichiers union, de sorte que le volume est en fait un répertoire réel qui est monté (en lecture-écriture ou en lecture seule) au bon endroit dans tous les conteneurs qui le partagent.
Désormais, pour accéder à ces données depuis l'hôte, il vous suffit d'inspecter votre conteneur:
Ce que je fais habituellement, c'est créer des liens symboliques dans un endroit standard tel que / srv , afin que je puisse facilement accéder aux volumes et gérer les données qu'ils contiennent (uniquement pour les volumes qui vous intéressent):
Que faire si l'hôte docker s'exécute dans une machine virtuelle? Par exemple, boot2docker sur mac. Ensuite, ces volumes ne sont disponibles qu'à distance. De plus, lorsque vous utilisez des volumes dans le Dockerfile comme vous l'avez décrit, le contenu de l'image sera copié sur le volume. Cependant, lors du montage dans un répertoire local, cette copie n'a pas lieu. Savez-vous pourquoi c'est le cas? Existe-t-il un moyen d'avoir un volume monté localement tout en «repartant à zéro» avec les fichiers de l'image?
VOLUME est utilisé Dockerfilepour exposer le volume à utiliser par d'autres conteneurs. Exemple, créez Dockerfilecomme:
DEPUIS ubuntu: 14.04
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol
construire l'image:
$ docker build -t testing_volume .
Exécutez le conteneur, dites container1:
$ docker run -it <image-id of above image> bash
Maintenant, exécutez un autre conteneur avec l'option volumes-from comme (say-container2)
$ docker run -it --volumes-from <id-of-above-container> ubuntu:14.04 bash
Vous obtiendrez toutes les données du /myvolrépertoire container1 dans container2 au même emplacement.
-vL'option est donnée au moment de l'exécution du conteneur qui est utilisé pour monter le répertoire du conteneur sur l'hôte. Il est simple à utiliser, il suffit de fournir une -voption avec un argument comme <host-path>:<container-path>. La commande entière peut être comme$ docker run -v <host-path>:<container-path> <image-id>
Fondamentalement VOLUME, les -voptions sont presque égales. Cela signifie «monter un répertoire spécifique sur votre conteneur». Par exemple, VOLUME /dataet a -v /dataexactement la même signification. Si vous exécutez l'image VOLUME /dataavec ou avec -v /dataoption, le /datarépertoire est monté sur votre conteneur. Ce répertoire n'appartient pas à votre conteneur.
Imaginez que vous ajoutez des fichiers /datasur le conteneur, puis que vous confiez le conteneur dans une nouvelle image. Il n'y a aucun fichier dans le répertoire de données car le /datarépertoire monté appartient au conteneur d'origine.
$ docker run -it -v /data --name volume ubuntu:14.04 bash
root@2b5e0f2d37cd:/# cd /data
root@2b5e0f2d37cd:/data# touch 1 2 3 4 5 6 7 8 9
root@2b5e0f2d37cd:/data# cd /tmp
root@2b5e0f2d37cd:/tmp# touch 1 2 3 4 5 6 7 8 9
root@2b5e0f2d37cd:/tmp# exit
exit
$ docker commit volume nacyot/volume
835cfe3d8d159622507ba3256bb1c0b0d6e7c1419ae32751ad0f925c40378945
nacyot $ docker run -it nacyot/volume
root@dbe335c7e64d:/# cd /data
root@dbe335c7e64d:/data# ls
root@dbe335c7e64d:/data# cd /tmp
root@dbe335c7e64d:/tmp# ls
1 2 3 4 5 6 7 8 9
root@dbe335c7e64d:/tmp#
root@dbe335c7e64d:/tmp#
Ce répertoire monté comme /dataest utilisé pour stocker des données qui n'appartiennent pas à votre application. Et vous pouvez prédéfinir le répertoire de données qui n'appartient pas au conteneur à l'aide de VOLUME.
Une différence entre Volumeet -voption est que vous pouvez utiliser l' -voption dynamiquement au démarrage du conteneur. Cela signifie que vous pouvez monter un répertoire dynamiquement. Et une autre différence est que vous pouvez monter votre répertoire hôte sur votre conteneur en utilisant-v
Cela provient de la documentation Docker elle-même, peut être utile, simple et claire:
"Le répertoire hôte est, de par sa nature, dépendant de l'hôte. Pour cette raison, vous ne pouvez pas monter un répertoire hôte à partir de Dockerfile, l'instruction VOLUME ne prend pas en charge le passage d'un répertoire hôte, car les images construites doivent être portables. Un hôte l'annuaire ne serait pas disponible sur tous les hôtes potentiels. ".
--volumes-from
montera votreVOLUME
par-dessus tout ce que vous spécifiez avec-v
. Fait intéressant, il semble que l' exécution du conteneur en mode privilégié (docker run --privileged
) etumount
ing/var/lib/mysql
va juste laisser un répertoire vide de sorte que votre-v
monture est complètement ignoré quand il est en conflit avecVOLUME
.named-volume:/path/in/container
. Les volumes sans nom reçoivent des hachages pour les noms et ces hachages peuvent être fournis à la place d'un chemin d'hôte pour accéder aux volumes orphelins. :) Soyez conscient quevolume ls
peut ne pas les montrer tous - essayezdocker volume ls -f dangling=true
aussi.Permettez-moi d'ajouter ma propre réponse, car je pense que les autres manquent le point de Docker.
L'utilisation
VOLUME
dans Dockerfile est la bonne façon ™, car vous faites savoir à Docker qu'un certain répertoire contient des données permanentes. Docker créera un volume pour ces données et ne le supprimera jamais, même si vous supprimez tous les conteneurs qui l'utilisent.Il contourne également le système de fichiers union, de sorte que le volume est en fait un répertoire réel qui est monté (en lecture-écriture ou en lecture seule) au bon endroit dans tous les conteneurs qui le partagent.
Désormais, pour accéder à ces données depuis l'hôte, il vous suffit d'inspecter votre conteneur:
Ce que je fais habituellement, c'est créer des liens symboliques dans un endroit standard tel que / srv , afin que je puisse facilement accéder aux volumes et gérer les données qu'ils contiennent (uniquement pour les volumes qui vous intéressent):
la source
VOLUME est utilisé
Dockerfile
pour exposer le volume à utiliser par d'autres conteneurs. Exemple, créezDockerfile
comme:DEPUIS ubuntu: 14.04
construire l'image:
$ docker build -t testing_volume .
Exécutez le conteneur, dites container1:
$ docker run -it <image-id of above image> bash
Maintenant, exécutez un autre conteneur avec l'option volumes-from comme (say-container2)
$ docker run -it --volumes-from <id-of-above-container> ubuntu:14.04 bash
Vous obtiendrez toutes les données du
/myvol
répertoire container1 dans container2 au même emplacement.-v
L'option est donnée au moment de l'exécution du conteneur qui est utilisé pour monter le répertoire du conteneur sur l'hôte. Il est simple à utiliser, il suffit de fournir une-v
option avec un argument comme<host-path>:<container-path>
. La commande entière peut être comme$ docker run -v <host-path>:<container-path> <image-id>
la source
Fondamentalement
VOLUME
, les-v
options sont presque égales. Cela signifie «monter un répertoire spécifique sur votre conteneur». Par exemple,VOLUME /data
et a-v /data
exactement la même signification. Si vous exécutez l'imageVOLUME /data
avec ou avec-v /data
option, le/data
répertoire est monté sur votre conteneur. Ce répertoire n'appartient pas à votre conteneur.Imaginez que vous ajoutez des fichiers
/data
sur le conteneur, puis que vous confiez le conteneur dans une nouvelle image. Il n'y a aucun fichier dans le répertoire de données car le/data
répertoire monté appartient au conteneur d'origine.Ce répertoire monté comme
/data
est utilisé pour stocker des données qui n'appartiennent pas à votre application. Et vous pouvez prédéfinir le répertoire de données qui n'appartient pas au conteneur à l'aide deVOLUME
.Une différence entre
Volume
et-v
option est que vous pouvez utiliser l'-v
option dynamiquement au démarrage du conteneur. Cela signifie que vous pouvez monter un répertoire dynamiquement. Et une autre différence est que vous pouvez monter votre répertoire hôte sur votre conteneur en utilisant-v
la source
Cela provient de la documentation Docker elle-même, peut être utile, simple et claire:
"Le répertoire hôte est, de par sa nature, dépendant de l'hôte. Pour cette raison, vous ne pouvez pas monter un répertoire hôte à partir de Dockerfile, l'instruction VOLUME ne prend pas en charge le passage d'un répertoire hôte, car les images construites doivent être portables. Un hôte l'annuaire ne serait pas disponible sur tous les hôtes potentiels. ".
la source