Управление данными в Docker

По умолчанию все файлы, созданные внутри контейнера, хранятся на доступном для записи слое контейнера. Это означает, что:

  • Данные не сохраняются, когда контейнер перестает существовать, и может быть трудно извлечь данные из контейнера, если они понадобятся другому процессу.

  • Записываемый уровень контейнера тесно связан с хост-машиной, на которой запущен контейнер. Вы не можете легко переместить данные в другое место.

  • Для записи в записываемый слой контейнера требуется драйвер накопителя для управления файловой системой. Драйвер хранилища предоставляет объединенную файловую систему, используя ядро Linux. Эта дополнительная абстракция снижает производительность по сравнению с использованием томов данных, которые записываются непосредственно в файловую систему хоста.

В Docker есть две опции для контейнеров, позволяющие хранить файлы на хост-машине так, чтобы они сохранялись даже после остановки контейнера: volumes (тома) и bind mounts (связываемые монтирования).

Docker также поддерживает контейнеры, хранящие файлы в памяти на хост-машине. Такие файлы не сохраняются. Если вы запускаете Docker на Linux, для хранения файлов в системной памяти хоста используется tmpfs монтирование. Если вы запускаете Docker на Windows, для хранения файлов в системной памяти хоста используется именованный конвейер (named pipe).

Продолжайте читать, чтобы узнать больше о сохранении данных или использовании преимуществ файлов в памяти.

Выбор правильного типа монтирования

Независимо от того, какой тип монтирования вы выберете, данные выглядят одинаково из контейнера. Они представлены в виде каталога или отдельного файла в файловой системе контейнера.

Простой способ визуализировать разницу между томами, связующими монтированиями и монтированиями tmpfs - подумать о том, где данные находятся на хосте Docker.

типы монтирования и где они живут на хосте Docker
  • Тома хранятся в части файловой системы хоста, которая управляется Docker (/var/lib/docker/volumes/ в Linux). Процессы, не относящиеся к Docker, не должны изменять эту часть файловой системы. Тома - это лучший способ хранения данных в Docker.

  • Связующие монтирования (Bind mounts) могут храниться в любом месте на хост-системе. Это могут быть даже важные системные файлы или каталоги. Процессы, не относящиеся к Docker, на хосте Docker или в контейнере Docker могут изменять их в любое время.

  • tmpfs монтирования хранятся только в памяти хост-системы и никогда не записываются в файловую систему хост-системы.

Более подробная информация о типах монтирования

  • Тома: Создается и управляется Docker. Вы можете создать том явно, используя команду docker volume create, или Docker может создать том во время создания контейнера или службы.

Когда вы создаёте том, он хранится в каталоге на хосте Docker. Когда вы монтируете том в контейнер, именно этот каталог монтируется в контейнер. Это похоже на то, как работает связывающее монтирование, за исключением того, что тома управляются Docker и изолированы от основной функциональности хост-машины.

Данный том может быть смонтирован в несколько контейнеров одновременно. Когда ни один из запущенных контейнеров не использует том, том все ещё доступен для Docker и не удаляется автоматически. Вы можете удалить неиспользуемые тома с помощью docker volume prune.

Когда вы монтируете том, он может быть именным или анонимным. Анонимные тома не имеют явного имени при первом монтировании в контейнер, поэтому Docker присваивает им случайное имя, которое гарантированно будет уникальным в пределах данного хоста Docker. Помимо имени, именованные и анонимные тома ведут себя одинаково.

Тома также поддерживают использование драйверов тома, которые позволяют хранить данные на удаленных хостах или у облачных провайдеров, среди прочих возможностей.

  • Связующее монтирование (Bind mounts): Доступно с первых дней существования Docker. Связное монтирование имеет ограниченную функциональность по сравнению с томами. При использовании связывающего монтирования файл или каталог на хост-машине монтируется в контейнер. Ссылка на файл или каталог осуществляется по его полному пути на хост-машине. Файл или каталог не обязательно должен уже существовать на хосте Docker. Он создаётся по требованию, если ещё не существует. Связующие монтирования очень эффективны, но они зависят от наличия в файловой системе хост-машины определенной структуры каталогов. Если вы разрабатываете новые приложения Docker, подумайте об использовании именованных томов. Вы не можете использовать команды Docker CLI для прямого управления связующими монтированиями.

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

    Одним из побочных эффектов использования связывающего монтирования, к лучшему или худшему, является то, что вы можете изменять файловую систему хоста через процессы, запущенные в контейнере, включая создание, изменение или удаление важных системных файлов или каталогов. Это мощная способность, которая может иметь последствия для безопасности, включая воздействие на процессы, не относящиеся к Docker, в хост-системе.

  • Монтирования tmpfs: Монтирование tmpfs не сохраняется на диске ни на хосте Docker, ни внутри контейнера. Оно может использоваться контейнером в течение всего срока службы контейнера для хранения неперсистентного состояния или конфиденциальной информации. Например, внутренние службы swarm используют монтирование tmpfs для монтирования секретов в контейнеры службы.

  • Именованные конвейеры (named pipes): Монтирование npipe может использоваться для связи между хостом Docker и контейнером. Обычный случай использования - запуск стороннего инструмента внутри контейнера и подключение к API Docker Engine с помощью именованного конвейера.

Связывающие монтирования и тома можно монтировать в контейнеры с помощью флага -v или --volume, но синтаксис для каждого из них немного отличается. Для монтирования tmpfs можно использовать флаг --tmpfs. Мы рекомендуем использовать флаг --mount как для контейнеров, так и для служб, для связывающего монтирования, томов или монтирования tmpfs, поскольку синтаксис более понятен.

Хорошие примеры использования томов

Тома являются предпочтительным способом сохранения данных в контейнерах и службах Docker. Некоторые примеры использования томов включают:

  • Совместное использование данных несколькими запущенными контейнерами. Если вы не создаёте его явно, том создаётся при первом монтировании в контейнер. Когда этот контейнер останавливается или удаляется, том продолжает существовать. Несколько контейнеров могут одновременно монтировать один и тот же том в режиме чтения-записи или только чтения. Тома удаляются только при явном удалении.

  • Когда хост Docker не гарантированно имеет заданный каталог или файловую структуру. Тома помогают отделить конфигурацию узла Docker от времени выполнения контейнера.

  • Когда вы хотите хранить данные контейнера не локально, а на удалённом хосте или у облачного провайдера.

  • Когда вам нужно создать резервную копию, восстановить или перенести данные с одного узла Docker на другой, тома - лучший выбор. Вы можете остановить контейнеры, использующие том, а затем создать резервную копию каталога тома (например, /var/lib/docker/volumes/<volume-name>).

  • Когда вашему приложению требуется высокопроизводительный ввод-вывод на Docker Desktop. Тома хранятся в виртуальной машине Linux, а не на хосте, что означает, что чтение и запись имеют гораздо меньшую задержку и более высокую пропускную способность.

  • Когда вашему приложению требуется полностью «родное» поведение файловой системы на Docker Desktop. Например, движок базы данных требует точного контроля над очисткой диска для обеспечения долговечности транзакций. Тома хранятся в виртуальной машине Linux и могут обеспечить такие гарантии, в то время как связывающие монтирования удаляются в macOS или Windows, где файловые системы ведут себя несколько иначе.

Хорошие варианты использования связующего монтирования

В общем, по возможности следует использовать тома. Связующие монтирования подходят для следующих типов использования:

  • Передача конфигурационных файлов с хост-машины в контейнеры. Именно так Docker обеспечивает разрешение DNS для контейнеров по умолчанию, монтируя /etc/resolv.conf с хост-машины в каждый контейнер.

  • Совместное использование исходного кода или артефактов сборки между средой разработки на хосте Docker и контейнером. Например, вы можете смонтировать каталог Maven target/ в контейнер, и каждый раз, когда вы собираете проект Maven на хосте Docker, контейнер получает доступ к перестроенным артефактам.

Если вы используете Docker для разработки таким образом, ваш производственный Dockerfile будет копировать готовые к производству артефакты непосредственно в образ, а не полагаться на связующее монтирование (bind mount).

  • Когда файловая структура или структура каталогов хоста Docker гарантированно соответствует связующему монтированию, которые требуются контейнерам.

Хорошие варианты использования tmpfs монтирования

Монтирование tmpfs лучше всего использовать в случаях, когда вы не хотите, чтобы данные сохранялись ни на хост-машине, ни внутри контейнера. Это может быть сделано по соображениям безопасности или для защиты производительности контейнера, когда вашему приложению нужно записать большой объём данных о состоянии, не являющихся постоянными.

Советы по использованию связующих монтирований или томов

Если вы используете либо связывающее монтирование, либо тома, помните о следующем:

  • Если вы монтируете пустой том в каталог в контейнере, в котором существуют файлы или каталоги, эти файлы или каталоги распространяются (копируются) в том. Аналогично, если вы запускаете контейнер и указываете том, который еще не существует, для вас создаётся пустой том. Это хороший способ предварительно заполнить данные, которые нужны другому контейнеру.

  • Если вы монтируете связующее монтирование (bind mount) или непустой том в каталог в контейнере, в котором существуют некоторые файлы или каталоги, эти файлы или каталоги будут скрыты монтированием, как если бы вы сохранили файлы в /mnt на хосте Linux, а затем смонтировали USB-накопитель в /mnt. Содержимое /mnt будет скрыто содержимым USB-накопителя до тех пор, пока USB-накопитель не будет размонтирован. Непонятные файлы не удаляются и не изменяются, но они недоступны, пока монтируется привязка или том.

Следующие шаги