Docker & Python

В предыдущих постах «Часть 1 – терминология» мы рассмотрели основные термины и в части “Часть 2 – основные команды” провели обзор основных команд по управлению докер, “Часть 3 – файл докер” тренировались в создании своих образов. Теперь расмотрим, как организовать хранение данных наших приложений в томах докер.

Часть 4 – хранение данных

Традиционно большинство вычислительных решений используют способы хранения данных. В случае виртуальных машин виртуальный диск эмулируется, и данные, сохраненные на этом виртуальном диске, в виде файла на хост компьютер. В случае облачных провайдеров, таких как Amazon Web Services
(AWS), они предоставляют нам корневой том для хранения данных и блокируют хранилище (Elastic Block Store – EBS) для хранения данных.
С контейнерами дело обстоит иначе. Контейнеры были предназначены и предназначены для рабочих нагрузок без сохранения состояния, а дизайн слоев контейнера показывают это.

Docker образ – это шаблон только для чтения, состоящий из различных слоев, и когда
образ запускается как контейнер, контейнер содержит небольшой слой только для записи
данных. Это означает, что:

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

Для решения указанных проблем докер предлагает несколько стратегий:

  • tmpfs
  • монтирование каталогов
  • тома

Монтирование tmpfs (монтирование файловой системы из памяти компьютера)

Как следует из названия, tmpfs создает и присоединяет к образу tmpfs, которая является хранилищем временных файлов. Каталоги, смонтированные в tmpfs, отображаются как обычная файловая система, но хранится в памяти, а не в постоянном хранилище например, диске.
Монтирование tmpfs ограничено только контейнерами Docker в Linux. Tmpfs mount является временным, и данные хранятся в памяти хостов Docker. Как только контейнер останавливается, все данные с tmpfs удаляются и файлы записываются to tmpfs mount теряются.

Чтобы создать tmpfs, вы можете использовать флаг –mount или –tmpfs в момент запуска контейнера, как показано здесь:

docker run -it –name tmpfs-test –mount type=tmpfs, target=/ tmpfs-mount ubuntu bash
docker run -it –name tmpfs-test –tmpfs /tmpfs-mount ubuntu bash

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

Монтирование кталогов (Bind Mounts)

Основное отличие «монтирование каталога» от «томов» в том, что при монтировании происходит связывание каталога с хоста с каталогом внутри образа (все изменения которые происходят в этом каталоге сохраняются и на хосте), а «том» – это новый каталог, который создается в хранилище докер и им же и управляется.

Примечание: При поиске статей о монтировании или томах для докера в Интернете вы, скорее всего, найдете статьи, в которых говорится об использовании томов с флагом -v. Начиная версии 17.06 докер рекомендует  всем использовать синтаксис –mount. В примерах используются оба флага.

Посмотрим, как мы можем использовать монирование. Мы попробуем смонтировать в докер
домашний каталог с хоста в каталог, называемый host-home в контейнере.
Для этого введите следующую команду:

docker run -it –name mount-test –mount type=bind,source=”$HOME”, target=/host-home ubuntu bash
docker run -it –name mount-test -v $HOME:/host-home ubuntu bash

Обычно «монтирование каталога» используется в цикле разработки, а не в реальной работе.

Важно помнить, что изменения двух сторонние и удаление каталога или файлов на хосте деструктивно скажется на докер контейнере (в плоть до вплоть до полного нарушения его работы).

Поэтому имеется возможность создать связку только для чтения (при которой докер контейнер только читает файлы, но не может их изменять). Для этого используется параметр readonly. Например:

docker run -it –name mount-test –mount type=bind,source=”$HOME”, target=/host-home,readonly ubuntu bash

docker run -it –name mount-test -v $HOME:/host-home:ro ubuntu bash

Тома (Volume)

Тома Docker – это текущий рекомендуемый метод хранения данных хранится в контейнерах. Тома полностью управляются Docker и имеют много преимуществ:

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

Для работы с томами в докер есть специальный набор команд:

  • docker volume create
  • docker volume inspect
  • docker volume ls
  • docker volume prune
  • docker volume rm

Создание тома (create volume)

Команда создает новый именованый том:

docker volume create –name=<имя тома> [–label=<любый дополнительные данные>]

Получение информации

Команда для просмотра информации о томе (как то тип, время создания, точка монтирования):

docker volume inspect <имя тома>

Пример:

docker volume inspect nginx-volume
выдаст подобный вывод:

 
Эта команда полезна, если вы хотите скопировать / переместить / сделать резервную копию тома. Свойство mountpoint указывает на место расположение тома на хосте Docker.

Список томов

Команда выдает список всех томов, которые есть на хосте:

docker volume ls

Удаление не используемых 

Команда удаляет все не используемые локальные тома:

docker volume prune [–force]

Docker считает неиспользуемым любой том, который не используются хотя бы одним контейнером. Поскольку неиспользованные тома могут в конечном итоге потреблять значительное количество места на диске, неплохо было бы запускать команду prune через регулярные промежутки времени, особенно на локальных машинах разработки. Когда вы используете флаг –force, команда не будет запрашивать подтверждение при удалении.

Удаление тома

Команда удаляет конкретный, указанный том:

docker volume rm <имя тома>

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

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

Использование томов

Пример команды которая использует том:

docker run -it –name volume-test –mount target=/data-volume ubuntu bash
docker run -it –name volume-test -v:/data-volume

Эти команды идентичны командам монтирования каталогов, с той лишь разнице, что при использовании опции “–mount” не используется опция “source”, а при использовании опции “-v”, указан только каталог внутри образа.

При этом эта команда создаст случайное имя для тома. Обычно тома размещаются в каталоге : “/var/lib/docker/volumes/”.

Если требуется осмысленное имя (то используется docker volume create). Например:

docker volume create volume-for-test

Созданные заранее тома можно использовать при создании/ запуске контейнера. Для этого используется флаг source = с флагом –mount и параметр после -v флага. Они указывают имя тома, к которому должен быть подключен контейнер. Например:

docker run -it –name volume-test –mount source=volume-for-test,target=/data-volume ubuntu bash
docker run -it –name volume-test -v:volume-for-test:/data-volume

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

Инструкция VOLUME в докер файле (Dockerfile)

Инструкция VOLUME отмечает упомянутый после нее путь как внешний объем данных, управляемый Docker. Ее
синтаксис следующий:

VOLUME [“/путь к каталогу внутри образа”]

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

Внимание: инструкция VOLUME не поддерживает именование тома и как результат том будет иметь случайно созданное имя.

 

 

Обсуждение закрыто.