Дизайн Docker: обмениваться данными между контейнерами или поместить несколько процессов в один контейнер? - PullRequest
1 голос
/ 06 марта 2019

В текущем проекте мне необходимо выполнить следующие задачи (среди прочих):

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

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

Поскольку мне нужно увеличить разрешение входного сигнала для детектора объектов при сохранении разрешения потока для пользовательского интерфейса, я должен искать альтернативные способы получения сшитой панорамы (полное разрешение) (~ 10 МБ на кадр) из контейнера брошюровщика в контейнер детектора.

Мои мысли о возможных решениях:

  • общий объем.Потенциальный недостаток: одна дополнительная запись и чтение на кадр может быть слишком медленной?
  • Использование очереди сообщений или, например, redis.Потенциальный недостаток: еще один компонент в архитектуре.
  • , объединяющий два контейнера.Потенциальный недостаток (и): Мало того, что это не кажется правильным, но два контейнера имеют совершенно разные базовые образы и зависимости.Плюс мне придется беспокоиться о распараллеливании.

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

Ответы [ 2 ]

1 голос
/ 06 марта 2019

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

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

Если вы пытаетесь масштабировать это в рабочей среде: Я бы добавил какую-то общую файловую систему и систему очередей сообщений, такую ​​как RabbitMQ.Для локальной работы это может быть Docker с именем том или смонтированный на привязке хост-каталог;облачное хранилище вроде Amazon S3 тоже будет работать нормально.Настройка выглядит следующим образом:

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

В этой настройке каждый компонент не имеет состояния.Если вы обнаружите, что, например, компонент машинного обучения медленнее, вы можете запустить его дубликаты.Если что-то сломается, RabbitMQ запомнит, что данное сообщение не было полностью обработано (подтверждено);и снова из-за изолированности вы можете запустить этот конкретный компонент локально, чтобы воспроизвести и исправить проблему.

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

Выполняя это локально, я бы совершенно отдельно держал отдельные задачи в отдельных контейнерах (особенно, если индивидуальная обработка изображений и задачи ML стоят дорого).Для установки, которую я предлагаю, нужна как очередь сообщений (для отслеживания работы), так и общая файловая система (поскольку очереди сообщений обычно не оптимизированы для отдельных сообщений размером более 10 МБ).Вы можете выбрать между именованными томами Docker и хост-связыванием хоста как легкодоступное общее хранилище.Связывание монтируется легче для проверки и администрирования, но на некоторых платформах легендарно медленно.Именованные тома, я думаю, достаточно быстрые, но вы можете получить к ним доступ только из контейнеров Docker, что означает необходимость запуска большего количества контейнеров для выполнения базовых задач, таких как резервное копирование и сокращение.

0 голосов
/ 06 марта 2019

Хорошо, давайте распакуем это:

  • IMHO Shared Volume работает просто отлично, но со временем становится слишком грязным.Особенно, если вы работаете с сервисами Stateful.
  • MQ: На мой взгляд, это лучший вариант.Да, это еще один компонент в вашей архитектуре, но имеет смысл иметь его вместо того, чтобы поддерживать беспорядочные общие тома или обрабатывать массивные образы контейнеров (если вам удастся объединить 2 образа контейнеров)
  • Да, вы могли бы сделать это потенциальноно не очень хорошая идея.Рассматривая ваш вариант использования, я собираюсь пойти дальше и предположить, что у вас есть огромный список зависимостей, которые потенциально могут привести к конфликту.Кроме того, много зависимостей = большее изображение = большая поверхность атаки - что с точки зрения безопасности не очень хорошая вещь.

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

https://docs.docker.com/config/containers/multi-service_container/

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