Введение

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

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

Цель этого блога - охватить информацию, которая требуется знать о контейнерах, что такое контейнеры, почему они полезны и как использовать их в рамках проектов на основе ИИ.

Этот пост не касается информации о Dev-Ops, поскольку я этого не знаю. Этот пост о создании концепции и понимания и не касается синтаксиса / команд докера.

Развертывание приложений ???

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

Это один из основных этапов SDLC. Существуют различные способы развертывания приложения, и они развивались с течением времени.

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

Я попытаюсь объяснить, основываясь на уровне абстракции, который обеспечивает каждый подход.

Устаревший способ - отдельный сервер - БЕЗ АБСТРАКЦИИ

Устаревший способ развертывания приложения - запросить отдельный сервер для размещения вашего приложения. Выделенное оборудование будет использоваться для размещения вашего приложения.

В этом подходе вам нужно будет запросить машину (оборудование), затем вам нужно будет настроить ОС, затем установить программное обеспечение и зависимости, а затем поместить на нее код приложения. Это утомительный и трудоемкий процесс, в долгосрочной перспективе такие серверы становится трудно обслуживать, он не использует оборудование оптимальным образом, вызывает проблемы в коде приложения из-за обновления ОС, зависимостей и т. Д.

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

Промышленности требовалось решение для этого, и оно породило концепцию под названием «Виртуализация».

Вирутализация - аппаратная абстракция

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

В этом подходе аппаратное обеспечение («голый металл») абстрагируется за счет использования «гипервизоров».

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

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

Это выглядит так.

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

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

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

Почти все эти проблемы были решены с помощью красивой концепции под названием «контейнеризация».

КОНТЕЙНЕРЫ - АБСТРАКЦИЯ ОС - ВИРТУАЛИЗАЦИЯ ОПЕРАЦИОННОЙ СИСТЕМЫ

Контейнеры в основном создают более высокий уровень абстракции за счет виртуализации операционной системы. Они нарушают связь между кодом приложения и ОС.

Благодаря этому они очень легкие и содержат именно то, что необходимо для запуска приложения.

Контейнеры содержат код приложения и зависимости.

Поскольку контейнеры не содержат ОС, такие вещи, как обновление ОС и т. Д., Не повлияли на них. Контейнеры - это моментальный снимок кода и зависимостей, поэтому управление зависимостями можно легко реализовать. Два разных приложения могут использовать разные версии одних и тех же зависимостей, не создавая конфликта. Мы также можем контролировать обновления зависимостей для каждого приложения.

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

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

Некоторые преимущества контейнеров перечислены как:

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

Как создать контейнер?

Для создания контейнера мы можем использовать популярный фреймворк с открытым исходным кодом под названием «Docker».

Общий процесс создания контейнера выглядит так:

Пример контейнеризации

Теперь давайте рассмотрим пример приложения AI для классификации текста. Это приложение состоит из трех частей:

а) Оркестровка / промежуточное ПО, написанное на Java, которое собирает данные.

б) Модуль предварительной обработки данных на Python. Представлен как REST API. Построен на таких библиотеках, как numpy, spacy и т. Д.

c) Механизм классификации Python, который запускает модель глубокого обучения. Представлен как REST API. Построен на Pytorch, использует встраивание слов и т. Д.

Чтобы поместить в контейнер все это приложение, нам нужно кое-что сделать.

  1. Определитесь с количеством контейнеров. У нас может быть один контейнер для каждого модуля, чтобы лучше обрабатывать приложение. В этом случае у нас есть три модуля, поэтому мы можем создать 3 контейнера.
  2. Нам нужен способ хранения данных. У каждого контейнера будет своя собственная память, но нам нужен способ, чтобы контейнеры могли совместно использовать данные. Такие вещи, как наш код, файл конфигурации и файлы данных, должны храниться таким образом, чтобы все три контейнера могли получить к ним доступ.

Это можно сделать с помощью «КОНТЕЙНЕР ОБЪЕМА». Объемные контейнеры - это особый тип контейнеров, в которых могут храниться данные. Контейнеры приложений (контейнеры кода) могут монтировать контейнеры томов. Все контейнеры приложений, устанавливающие один и тот же контейнер тома, могут читать / писать в него. Вот как данные могут быть разделены между контейнером.

3. Нужно привязать контейнер к порту. Таким образом, Контейнер может запускать его на этом порту.

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

Это можно сделать с помощью «СЕТИ». Нам потребуется создать докер СЕТЬ. Таким образом, все контейнеры в одной сети могут взаимодействовать друг с другом. В этом случае они выполняют REST-вызовы друг друга.

URI для вызовов REST будет выглядеть так

https: // имя_контейнера: bind_port / api_endpoint

Всего есть два шага:

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

Пример файла Docker выглядит так:

FROM ubuntu:18.04     ## Select a base image                                          
##install python
RUN apt-get update -y && \               
apt-get install -y python3 python3-pip python3-dev
##copy python dependencies. they are specified in requirement.txt
COPY ./requirements.txt /app/requirements.txt
## change the working directory.
WORKDIR /app
##install python dependencies
RUN python3 -m pip install -r requirements.txt
COPY . /app                                              
## start the app
ENTRYPOINT [ "python3" ]
CMD [ "main.py" ]

Образец файла приложения:

#create network                       
docker network create my_network
# Create volume container using volume image                      
docker run -idt --name my_volume --net=my_network my_volume:latest
docker attach IMAGE_ID
## Create data pre-processing container using pre-processor image
docker run -idt -p 9097:9097  --volumes-from my_volume --name preprocessor --net=create my_network preprocessor:latest
docker attach IMAGE_ID

Я видел путаницу вокруг Docker «запускать» и «запускать». Запуск Docker - это комбинация сборки (создания нового контейнера) и ее последующего запуска. Выполнить необходимо, если вы хотите создать и запустить контейнер с помощью одной команды.

Если вы просто хотите создать контейнер, просто выполните сборку докеров. Контейнер не запустится. И вы можете запустить контейнер с Docker «start».

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

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

Удачного обучения !!