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

Вступление

В этом посте мы собираемся рассказать о сохранении данных в Docker и о том, как заставить ваши изображения взаимодействовать с данными вне контейнера. Если вы знакомы с Docker или уже знакомы с предыдущими статьями этой серии, переходите к следующему заголовку!

До сих пор в этой серии мы рассказывали, как получить базовый Hello World! веб-приложение, созданное с использованием Flask и Python и развернутое с помощью Docker. В части 2 мы рассмотрели пример сквозного машинного обучения, создав классификатор случайного леса для набора данных Iris и использовав его в качестве веб-приложения для прогнозирования с помощью Flask, прежде чем опубликовать его в общедоступном репозитории Docker Hub.

Если вы их пропустили:





Теперь, возможно, вы не захотите публиковать свои изображения публично во всех случаях. К счастью, у вас есть много возможностей для создания и поддержки частных репозиториев. Каждый из основных облачных провайдеров Azure, AWS и GCP имеет варианты размещенных репозиториев, которые довольно просто настроить и запустить. Для тех из вас, кто хочет использовать Azure, я также написал краткое руководство о том, как запустить частный репозиторий с помощью Docker и Azure CLI, здесь:



Если вы уже работаете и просто хотите продолжить работу с сохранением данных, приступим.

Сохранение данных

При работе с контейнерами необходимо учитывать два основных допущения:

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

У этого подхода много преимуществ. Безгражданство поддерживает масштабируемость, переносимость и отказоустойчивость. Если у вас несколько контейнеров, и один из них выйдет из строя, его просто перезапустить или запустить замену.

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

Отделение управления данными от приложения может привести к более быстрой разработке и снижению накладных расходов на обслуживание (читайте: верните нам время, то, что нужно каждому специалисту по данным!).

Есть несколько вариантов того, где удерживать это состояние извне:

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

В этой статье мы рассмотрим использование томов Docker для хранения состояния.

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

Я буду использовать стандартный образ записной книжки Jupyter из Docker Hub, чтобы подчеркнуть, насколько легко работать с данными и знакомыми приложениями в среде Docker. Вы можете вытащить образ из Docker Hub с помощью команды:

docker pull jupyter/datascience-notebook

Обратите внимание: это довольно большое изображение (4,16 ГБ), если места или времени мало, попробуйте вместо этого использовать минимальный образ записной книжки (1,49 ГБ) и соответствующим образом измените весь следующий код. Вы можете вытащить минимальное изображение, используя:

docker pull jupyter/minimal-notebook

Создание тома Docker

Прежде всего, давайте начнем с томов Docker - это ресурс, которым управляет Docker, и контейнеры могут легко получить доступ для использования в качестве хранилища. Для создания тома в Docker используйте синтаксис:

docker volume create <volume_name> 

Вы можете проверить это с помощью docker volume ls, как показано ниже.

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

Здесь мы монтируем demo-volume, который только что создали, в каталог внутри контейнера. Мы собираемся использовать /home/jovyan/demo-dir, чтобы поместить его прямо в расположение по умолчанию для Jupyter. Синтаксис следующий:

docker run -v <volume_name>:<container_directory> <image_name>

Поскольку мы здесь используем Jupyter, нам также нужно не забыть сопоставить порты. Таким образом, команда выглядит так:

docker run -p 8888:8888 -v demo-volume:/home/jovyan/demo-dir jupyter/datascience-notebook

Затем вам просто нужно перейти по ссылке с токеном и (второй в выводе у меня работает более стабильно):

http://127.0.0.1:8888/?token=a7a30a23821b5764d7f754838af13099b6b134c8687c415f

Вы должны пройти аутентификацию и перенаправить вас, после чего вы увидите знакомый передний экран Jupyter и наш demo-dir, установленный прямо там, где мы его видим:

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

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

Заключение

В этом посте мы рассмотрели некоторые варианты сохранения данных при использовании Docker. Мы также рассмотрели один из наиболее удобных подходов к сохранению данных вне вашего контейнера и между контейнерами, работающими на одном хосте.

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

дальнейшее чтение

В Docker есть еще много возможностей для сохранения данных. В этой статье Лоренца Вантилло рассматривается подключение ваших контейнеров Docker к базе данных PostgreSQL:



И здесь Тьяго С. Адриано написал отличное руководство по подключению к SQL Server:



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