томи кріплення докера на хості


135

Мені успішно вдалося поділитися папками між контейнером docker з використанням томів

docker run -v /host/path:/container/path ...

Але моє питання полягає в тому, в чому різниця між цим та використанням VOLUMEкоманди в Dockerfile

VOLUME /path

Я використовую зображення з VOLUMEкомандою, і я хотів би знати, як поділитися ним зі своїм хостом. Я зробив це за допомогою -vкоманди, наведеної вище, але я не знав, чи потрібно мені -vі VOLUME.

Відповіді:


155

VOLUMEКоманда буде монтувати каталог всередині вашого контейнера і зберігати будь-які файли , створені або відредаговані в цій папці на диску хостів поза структурою контейнера файлу , минаючи об'єднання файлової системи.

Ідея полягає в тому, що ваші томи можна розділити між докерними контейнерами, і вони залишатимуться до тих пір, поки є контейнер (запущений або зупинений), який посилається на них.

Ви можете мати інші контейнери змонтувати наявні томи (ефективно розподіляти їх між контейнерами), використовуючи --volumes-fromкоманду під час запуску контейнера.

Принципова відмінність між VOLUMEі -vполягає в наступному: -vбуде монтувати існуючі файли з вашої операційної системи всередині Docker контейнера і VOLUMEбуде створювати новий порожній обсяг на хості і встановити його всередині контейнера.

Приклад:

  1. У вас є Dockerfile, який визначає a VOLUME /var/lib/mysql.
  2. Ви будуєте зображення докера і тегуєте його some-volume
  3. Ви запускаєте контейнер

І потім,

  1. У вас є ще одне зображення докера, яким ви хочете використовувати цей том
  2. Ви запускаєте контейнер докер із наступним: docker run --volumes-from some-volume docker-image-name:tag
  3. Тепер у вас працює контейнер докера, який матиме об'єм від some-volumeвстановленого/var/lib/mysql

Примітка. Використання --volumes-fromдозволить встановити гучність над тим, що існує в місці тома. Тобто, якщо у вас були речі /var/lib/mysql, вона буде замінена вмістом тома.


12
Що станеться, якщо я використовую -v у каталозі, який вже був визначений у VOLUME?
Jeff Storey

6
--volumes-fromбуде кріпити VOLUMEверх над усім, що ви вказали -v. Цікаво, що схоже на те, що запуск контейнера у привілейованому режимі ( docker run --privileged), а umounting /var/lib/mysqlпросто залишить порожній dir, щоб ваше -vкріплення повністю ігнорувалось, коли воно конфліктує з a VOLUME.
Кріс Маккіннель

2
Ви кажете, що обсяги зберігаються до тих пір, поки контейнер посилається на них, і я бачив це деінде. docs.docker.com/userguide/dockervolumes говорить: " Об'єм даних призначений для збереження даних незалежно від життєвого циклу контейнера. Тому Docker ніколи не видаляє автоматично томи, коли ви виймаєте контейнер, і він не" збирає сміття "об'ємів, які більше не є. на який посилається контейнер. " Одне з цих тверджень повинно бути неправильним.
mc0e

1
Файли, що містяться в томі, зберігаються на диску, коли контейнер більше не посилається на нього, але сам том більше не можна використовувати (якщо ви точно не знаєте, як вручну підключити об'єм до контейнера, але навіть тоді я цього не роблю ' не знаю, чи можливо це). Коли я кажу, що більше не можна використовувати, я маю на увазі, що ви не можете використовувати - volumes-from, щоб використовувати його. Коли вони кажуть "збирання сміття" вище, вони означають видалення файлів з вашого диска, які були в обсязі.
Кріс Маккіннель

1
Вони можуть бути використані за допомогою -v, але не - об'ємів-від. Volumes-from приймає ім’я контейнера для отримання даних про обсяг (я вважаю, він займає ВСІ точки тома). Для самого -v, однак, керівництво згадує, що ви можете надати названий том до -v у вигляді named-volume:/path/in/container. Безіменним томам надаються хеші для імен, і ці хеші можуть бути надані замість хоста для доступу до осиротілих томів. :) Будьте в курсі, volume lsможе не показувати їх усім - спробуйте docker volume ls -f dangling=trueтакож.
Жасмін Гегман

44

Дозвольте додати свою власну відповідь, тому що я вважаю, що інші бракують точки Докера.

Використання VOLUMEв Dockerfile - це правильний шлях ™, тому що ви повідомляєте Докер про те, що певний каталог містить постійні дані. Docker створить об'єм для цих даних і ніколи не видаляє їх, навіть якщо ви видалите всі контейнери, які ними користуються.

Він також обходить файлову систему об'єднання, так що том насправді є фактичним каталогом, який встановлюється (читати-записувати чи читати лише) у потрібному місці у всіх контейнерах, які їм діляться.

Тепер, щоб отримати доступ до цих даних від хоста, вам потрібно лише перевірити ваш контейнер:

# docker inspect myapp
[{
    .
    .
    .
    "Volumes": {
        "/var/www": "/var/lib/docker/vfs/dir/b3ef4bc28fb39034dd7a3aab00e086e6...",
        "/var/cache/nginx": "/var/lib/docker/vfs/dir/62499e6b31cb3f7f59bf00d8a16b48d2...",
        "/var/log/nginx": "/var/lib/docker/vfs/dir/71896ce364ef919592f4e99c6e22ce87..."
    },
    "VolumesRW": {
        "/var/www": false,
        "/var/cache/nginx": true,
        "/var/log/nginx": true
    }
}]

Зазвичай я робимо символьні посилання в стандартному місці, наприклад / srv , щоб я міг легко отримувати доступ до томів і керувати даними, які вони містять (лише для томів, які вам цікаві):

ln -s /var/lib/docker/vfs/dir/b3ef4bc28fb39034dd7a3aab00e086e6... /srv/myapp-www
ln -s /var/lib/docker/vfs/dir/71896ce364ef919592f4e99c6e22ce87... /srv/myapp-log

Що робити, якщо хост докера працює в VM? Наприклад, boot2docker на mac. Тоді ці томи доступні лише віддалено. Також при використанні томів у Dockerfile, як ви описали, вміст зображення буде скопійовано в том. Однак при монтажі до локального каталогу цього копіювання не відбувається. Чи знаєте ви, чому це так? Чи є спосіб мати локально встановлений об'єм, але все-таки "починати свіжим" з файлами із зображення?
LostSalad

4
з docker-compose ви можете точно це зробити, встановити гучність на певному місці хоста OS . Ніяких посилань не потрібно ...
Hugo Koopmans

@Tobia: приклад docker-compose див. Docs docs.docker.com/compose/compose-file/…
Hugo Koopmans

11

VOLUME використовується Dockerfileдля експонування об'єму, який слід використовувати для інших контейнерів. Наприклад, створіть Dockerfileяк:

ВІД ubuntu: 14.04

RUN mkdir /myvol  
RUN echo "hello world" > /myvol/greeting  
VOLUME /myvol

побудувати зображення:

$ docker build -t testing_volume .

Запустіть контейнер, скажімо контейнер1:

$ docker run -it <image-id of above image> bash

Тепер запустіть інший контейнер з опцією томів як (скажімо-контейнер2)

$ docker run -it --volumes-from <id-of-above-container> ubuntu:14.04 bash

Ви отримаєте всі дані з /myvolкаталогу1 в каталог2 в тому ж місці.

-vопція задається під час виконання контейнера, який використовується для монтажу каталогу контейнера на хості. Користуватися просто, просто надайте -vпараметр з аргументом як <host-path>:<container-path>. Вся команда може бути такою ж$ docker run -v <host-path>:<container-path> <image-id>


8

В основному 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і -vопцією полягає в тому, що ви можете використовувати -vпараметр динамічно для запуску контейнера. Це означає, що ви можете динамічно монтувати деякий каталог. І ще одна відмінність полягає в тому, що ви можете змонтувати свій хост-каталог на контейнері, використовуючи-v


8

Це з самої документації на Докер, може бути корисною, простою та зрозумілою:

"Каталог хостів за своєю природою залежить від хоста. З цієї причини ви не можете монтувати каталог хостів з Dockerfile, інструкція VOLUME не підтримує передачу хост-dir, оскільки вбудовані зображення повинні бути портативними. Хост каталог не буде доступний для всіх потенційних хостів. "

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.