В чем разница между созданием тома или монтированием в контейнерах docker?

Docker предоставляет 2 способа резервного копирования и синхронизации данных контейнера на локальном компьютере, т.е. объем и монтировать. Оба ведут себя одинаково, за исключением нескольких вещей, которые я заметил:

  1. Том всегда хранит данные в /var /lib /docker /volumes, в то время как точки монтирования могут быть созданы везде, где мы захотим.
  2. Если контейнеру, которому назначена точка монтирования, также назначается том, то все данные из точки монтирования автоматически копируются на том, в то время как обратное неверно.
  3. Мы не можем описать точку монтирования в Dockerfile, но можем указать тома в Dockerfile.

Хорошо, итак, мы можем сказать, что есть некоторые преимущества и недостатки методологии, но есть ли еще какая-то классификация или различия в терминах оптимизации.

Пожалуйста, предоставьте объясненный ответ.

На самом деле существует три типа томов:

  • Том хоста: то, что вы называете монтированием в контейнере, более распространенным термином является монтирование привязки.
  • Именованный том: любой том, управляемый docker, которому вы даете имя.
  • Анонимный том: любой том без источника, docker создаст его как локальный том с длинным уникальным идентификатором, и он будет вести себя как именованный том.

Тома имеют источник и цель. Источник определяет тип тома, поэтому путь (включая начальную косую черту) к файлу/каталогу приводит к тому, что это основной том. Если вы не укажете источник, вы получите анонимные тома. Если вы определяете том внутри файла Dockerfile, вы не можете указать там источник, поэтому по умолчанию docker будет создавать анонимные тома, если вы не укажете ему иное во время выполнения.

Для каждого типа, вот плюсы / минусы:

  • Хозяин:
    • Pro: легкий доступ к базовым файлам с хоста
    • Con: проблемы с разрешениями uid/gid возникают, когда uid пользователя контейнера не совпадает с gid хоста
    • Против: данные не инициализируются
  • Названный:
    • Pro: легко создавать повторное использование между различными контейнерами / изображениями. Если вы дадите ему только имя без каких-либо других настроек, локальный драйвер по умолчанию будет хранить ваши данные в / var / lib / docker / volumes, которые должны быть доступны только root извне docker.
    • Pro: инициализирует содержимое содержимого изображения, когда оно пустое / новое и контейнер создан. Эта инициализация включает владельцев файлов и разрешения из образа, что может решить большинство проблем с uid / gid.
    • Pro: Может подключаться ко всему, что может быть подключено командой монтирования, включая привязку или NFS-монтирование, с помощью локального драйвера. Другие драйверы позволяют вам ссылаться на данные в еще большем количестве местоположений (например, облачные провайдеры).
    • Против: управление контентом должно осуществляться с помощью контейнера.
  • Анонимный:
    • Pro: не требует планирования для использования
    • Против: данные обычно отправляются сюда, чтобы быть потерянными, поскольку нет сопоставления с томом обратно в контейнер / изображение, которое его создало. На мой взгляд, это худший способ хранения томов, и причина в том, что никто никогда не должен определять том внутри своего файла Dockerfile.

Когда это возможно, я использую именованный том. Инициализация данных и лучшая обработка проблем с uid/gid превосходят удобство хост-тома. Если мне действительно нужен прямой доступ к данным за пределами docker, я пытаюсь использовать именованный том, который указывает на привязку, вместо настроек локального драйвера по умолчанию. Простым примером этого является:

$ docker volume create --driver local \  --opt type=none \  --opt device=/home/user/test \  --opt o=bind \  test_vol

Для определения моих томов, поскольку вы не хотите делать это в Dockerfile, я использую docker-compose.yml и определяю там свои тома. Если он развернут в режиме swarm, я укажу на сервер NFS с именованным томом, чтобы обеспечить доступ к данным при миграции контейнеров на разные хосты. В противном случае это локальный именованный том, который можно легко использовать с помощью docker-compose.

Тома в dockerfile позволяют указать путь к изображению, которое всегда должно создаваться как том. Это по своей сути обходит файловую систему union, используемую docker.

Пользователи такого образа всегда будут получать том в этом месте при запуске

docker run <imagename>

т.е. нет никаких причин когда-либо добавлять -v /my/mount/point:/mount/here и, таким образом, пользователям не нужно беспокоиться об этом.

привязка монтируется (как в приведенном выше примере с -v) должны всегда присутствовать, если они требуются. и не переносятся между изображениями.

эффективные различия в оптимизации заключаются в следующем:

  • тома можно использовать там, где требуется много операций ввода-вывода, и у него есть бизнес-запись в файловой системе union (например, базы данных).
  • тома бесполезны для монтирования таких вещей, как тома данных. вы можете это сделать, но вы получаете огромный r / w-удар, потому что нет никаких причин для этого в файловой системе union.
  • монтирование, однако, сохранит это (вышеупомянутое) довольно хорошо, поскольку оно просто монтирует существующий каталог в место внутри контейнера и игнорирует объединенную файловую систему для этого каталога все вместе.

есть ли в этом смысл?