Мне удалось поделиться папками между докер-контейнером с томами, используя
docker run -v /host/path:/container/path ...
Но мой вопрос в том, в чем разница между этим и использованием VOLUMEкоманды в Dockerfile.
VOLUME /path
Я использую изображение с VOLUMEкомандой, и я хотел бы знать, как поделиться им с моим хостом. Я сделал это с помощью приведенной -vвыше команды, но не знал, нужны ли мне и -vи VOLUME.
Команда VOLUMEсмонтирует каталог внутри вашего контейнера и сохранит все файлы, созданные или отредактированные внутри этого каталога, на диске вашего хоста вне файловой структуры контейнера , минуя файловую систему union.
Идея состоит в том, что ваши тома могут быть разделены между вашими контейнерами докеров, и они будут оставаться там, пока есть контейнер (запущенный или остановленный), который ссылается на них.
Вы можете заставить другие контейнеры монтировать существующие тома (эффективно разделяя их между контейнерами), используя --volumes-fromкоманду при запуске контейнера.
Фундаментальное различие между VOLUMEи -vзаключается в следующем: -vбудет монтировать существующие файлы из вашей операционной системы внутри контейнера докеров, а VOLUMEтакже создать новый пустой том на вашем хосте и смонтировать его внутри контейнера.
Пример:
У вас есть Dockerfile, который определяет VOLUME /var/lib/mysql.
Вы создаете образ докера и помечаете его some-volume
Вы запускаете контейнер
А потом,
У вас есть другой образ докера, который вы хотите использовать на этом томе
Вы запускаете контейнер докеров со следующим:
docker run --volumes-from some-volume docker-image-name:tag
Теперь у вас есть Docker контейнер работает , что будет иметь объем от some-volumeмонтажа в/var/lib/mysql
Примечание. Использование --volumes-fromпозволит монтировать том поверх всего, что находится в месте расположения тома. Т.е., если у вас был материал /var/lib/mysql, он будет заменен содержимым тома.
Что произойдет, если я использую -v для каталога, который уже был указан в VOLUME?
Джефф Стори,
6
--volumes-fromустановит вас VOLUMEповерх всего, что вы укажете -v. Интересно, что похоже, что запуск контейнера в привилегированном режиме ( docker run --privileged) и umounting /var/lib/mysqlпросто оставит пустой каталог, поэтому ваше -vмонтирование полностью игнорируется, когда оно конфликтует с файлом VOLUME.
Крис МакКиннел
2
Вы говорите, что тома хранятся до тех пор, пока на них ссылается контейнер, и я видел это в другом месте. В docs.docker.com/userguide/dockervolumes говорится: «Тома данных предназначены для хранения данных независимо от жизненного цикла контейнера. Поэтому Docker никогда не удаляет тома автоматически, когда вы удаляете контейнер, и он не будет« собирать мусор »тома, которые больше не являются на который ссылается контейнер ". Одно из этих утверждений должно быть неверным.
mc0e
1
Файлы, находящиеся в томе, хранятся на диске, когда контейнер больше не ссылается на него, но сам том больше не может использоваться (если вы точно не знаете, как вручную подключить том к контейнеру, но даже тогда я не не знаю, возможно ли это). Когда я говорю, что больше нельзя использовать, я имею в виду, что вы не можете использовать --volumes-from, чтобы использовать его. Когда они говорят выше «сборщик мусора», они имеют в виду удаление файлов с вашего диска, которые были в томе.
Крис МакКиннел
1
Их можно использовать с -v, но не с -volumes-from. Volumes-from принимает имя контейнера для извлечения данных тома (я считаю, что для этого нужны ВСЕ точки объема). Однако для самой -v в руководстве упоминается, что вы можете предоставить именованный том для -v в форме named-volume:/path/in/container. Безымянным томам присваиваются хэши для имен, и эти хэши могут быть предоставлены вместо пути к хосту для доступа к потерянным томам. :) Учтите, volume lsможет не все показать - docker volume ls -f dangling=trueтоже попробуйте .
Jasmine Hegman
44
Позвольте мне добавить свой собственный ответ, потому что я считаю, что другие упускают из виду Docker.
Использование VOLUMEв Dockerfile - это правильный путь ™, потому что вы даете Docker знать, что определенный каталог содержит постоянные данные. Docker создаст том для этих данных и никогда не удалит его, даже если вы удалите все контейнеры, которые его используют.
Он также обходит файловую систему union, так что том фактически является фактическим каталогом, который монтируется (для чтения-записи или только для чтения) в нужном месте во всех контейнерах, которые его используют.
Теперь, чтобы получить доступ к этим данным с хоста, вам нужно только проверить свой контейнер:
Обычно я создаю символические ссылки в каком-нибудь стандартном месте, таком как / srv , чтобы я мог легко получить доступ к томам и управлять данными, которые они содержат (только для томов, которые вам нужны ):
Что делать, если хост-докер запущен на виртуальной машине? Например, boot2docker на Mac. Тогда эти тома доступны только удаленно. Кроме того, при использовании томов в Dockerfile, как вы описали, содержимое образа будет скопировано на том. Однако при монтировании в локальный каталог этого копирования не происходит. Вы знаете, почему это так? Есть ли способ иметь локально смонтированный том, но при этом «начать все заново» с файлами из образа?
ОБЪЕМ используется Dockerfileдля отображения объема, который будет использоваться другими контейнерами. Пример, создать Dockerfileкак:
ОТ убунту: 14.04
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol
построить образ:
$ docker build -t testing_volume .
Запустите контейнер, скажем, container1:
$ docker run -it <image-id of above image> bash
Теперь запустите другой контейнер с опцией volume-from как (say-container2)
$ docker run -it --volumes-from <id-of-above-container> ubuntu:14.04 bash
Вы получите все данные из /myvolкаталога container1 в контейнер2 в том же месте.
-vПараметр задается во время выполнения контейнера, который используется для монтирования каталога контейнера на хосте. Его просто использовать, просто -vукажите параметр с аргументом как <host-path>:<container-path>. Вся команда может быть такой$ docker run -v <host-path>:<container-path> <image-id>
В принципе VOLUMEи -vвариант практически равны. Это означает «смонтировать конкретный каталог в вашем контейнере». Например, VOLUME /dataи -v /dataимеет точно такое же значение. Если вы запустите образ VOLUME /dataс -v /dataопцией или с опцией, /dataкаталог будет смонтирован для вашего контейнера. Этот каталог не принадлежит вашему контейнеру.
Представьте, что вы добавляете несколько файлов /dataв контейнер, а затем фиксируете контейнер в новом образе. В каталоге данных нет файлов, потому что смонтированный /dataкаталог принадлежит исходному контейнеру.
$ 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#
Этот смонтированный каталог как бы /dataиспользуется для хранения данных, не принадлежащих вашему приложению. И вы можете заранее определить каталог данных, который не принадлежит контейнеру, используя VOLUME.
Разница между Volumeи -voption заключается в том, что вы можете -vдинамически использовать option при запуске контейнера. Это означает, что вы можете монтировать какой-либо каталог динамически. И еще одно отличие состоит в том, что вы можете смонтировать каталог хоста в контейнере, используя-v
Это из самой документации Docker, может помочь, просто и ясно:
"Каталог хоста по своей природе зависит от хоста. По этой причине вы не можете смонтировать каталог хоста из Dockerfile, инструкция VOLUME не поддерживает передачу host-dir, потому что собранные образы должны быть переносимыми. Хост каталог не будет доступен на всех потенциальных хостах. ".
--volumes-from
установит васVOLUME
поверх всего, что вы укажете-v
. Интересно, что похоже, что запуск контейнера в привилегированном режиме (docker run --privileged
) иumount
ing/var/lib/mysql
просто оставит пустой каталог, поэтому ваше-v
монтирование полностью игнорируется, когда оно конфликтует с файломVOLUME
.named-volume:/path/in/container
. Безымянным томам присваиваются хэши для имен, и эти хэши могут быть предоставлены вместо пути к хосту для доступа к потерянным томам. :) Учтите,volume ls
может не все показать -docker volume ls -f dangling=true
тоже попробуйте .Позвольте мне добавить свой собственный ответ, потому что я считаю, что другие упускают из виду Docker.
Использование
VOLUME
в Dockerfile - это правильный путь ™, потому что вы даете Docker знать, что определенный каталог содержит постоянные данные. Docker создаст том для этих данных и никогда не удалит его, даже если вы удалите все контейнеры, которые его используют.Он также обходит файловую систему union, так что том фактически является фактическим каталогом, который монтируется (для чтения-записи или только для чтения) в нужном месте во всех контейнерах, которые его используют.
Теперь, чтобы получить доступ к этим данным с хоста, вам нужно только проверить свой контейнер:
Обычно я создаю символические ссылки в каком-нибудь стандартном месте, таком как / srv , чтобы я мог легко получить доступ к томам и управлять данными, которые они содержат (только для томов, которые вам нужны ):
источник
ОБЪЕМ используется
Dockerfile
для отображения объема, который будет использоваться другими контейнерами. Пример, создатьDockerfile
как:ОТ убунту: 14.04
построить образ:
$ docker build -t testing_volume .
Запустите контейнер, скажем, container1:
$ docker run -it <image-id of above image> bash
Теперь запустите другой контейнер с опцией volume-from как (say-container2)
$ docker run -it --volumes-from <id-of-above-container> ubuntu:14.04 bash
Вы получите все данные из
/myvol
каталога container1 в контейнер2 в том же месте.-v
Параметр задается во время выполнения контейнера, который используется для монтирования каталога контейнера на хосте. Его просто использовать, просто-v
укажите параметр с аргументом как<host-path>:<container-path>
. Вся команда может быть такой$ docker run -v <host-path>:<container-path> <image-id>
источник
В принципе
VOLUME
и-v
вариант практически равны. Это означает «смонтировать конкретный каталог в вашем контейнере». Например,VOLUME /data
и-v /data
имеет точно такое же значение. Если вы запустите образVOLUME /data
с-v /data
опцией или с опцией,/data
каталог будет смонтирован для вашего контейнера. Этот каталог не принадлежит вашему контейнеру.Представьте, что вы добавляете несколько файлов
/data
в контейнер, а затем фиксируете контейнер в новом образе. В каталоге данных нет файлов, потому что смонтированный/data
каталог принадлежит исходному контейнеру.Этот смонтированный каталог как бы
/data
используется для хранения данных, не принадлежащих вашему приложению. И вы можете заранее определить каталог данных, который не принадлежит контейнеру, используяVOLUME
.Разница между
Volume
и-v
option заключается в том, что вы можете-v
динамически использовать option при запуске контейнера. Это означает, что вы можете монтировать какой-либо каталог динамически. И еще одно отличие состоит в том, что вы можете смонтировать каталог хоста в контейнере, используя-v
источник
Это из самой документации Docker, может помочь, просто и ясно:
"Каталог хоста по своей природе зависит от хоста. По этой причине вы не можете смонтировать каталог хоста из Dockerfile, инструкция VOLUME не поддерживает передачу host-dir, потому что собранные образы должны быть переносимыми. Хост каталог не будет доступен на всех потенциальных хостах. ".
источник