Подтвердить что ты не робот

Докер: как закрепить и развернуть несколько экземпляров приложения LAMP

Мне нужно развернуть многие экземпляры одного и того же приложения LAMP (или LEMP):

  • каждый экземпляр будет доступен из субдомена, с фронтальным loadbalancer/proxy
  • каждый экземпляр должен иметь свои данные и данные данных db.
  • каждый экземпляр может отслеживаться
  • ограничение памяти /cpu может быть установлено для каждого экземпляра приложения
  • легко автоматизировать развертывание нового экземпляра webapp
  • среда может быть легко воспроизведена для тестирования и разработки.

Приложение требует:

  • процессы dameon (Nginx, MariaDB, PHPFPM)
  • двоичные файлы (composer, bower,...)
  • другие системы, специфичные для libs и config

После прочтения документации Docker и многих способов, я вижу разные решения для докеретизации этого веб-приложения:


Решение 1. Используйте контейнер "все-в-одном"

Весь стек находится в одном контейнере:

  • исходные файлы webapp, процессы демона EMP, двоичные файлы,...
  • смонтированные тома для mysql и файлов данных webapp

Примеры:

  • Tutum предоставляет контейнер "все-в-одном" для приложения Wordpress: https://github.com/tutumcloud/tutum-docker-wordpress
  • Phusion, который обеспечивает базовое изображение, оптимизированное для Docker, уточняет документацию (https://github.com/phusion/baseimage-docker#docker_single_process):

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

Профи (IMHO):

  • Кажется, легко автоматизировать deploiement, контролировать, уничтожать....
  • Простота использования в среде prod, test и dev.

Против (IMHO):

  • Монолитные
  • Трудно масштабировать
  • Не использует всю силу Docker

Решение 2: Использовать стек контейнеров для экземпляра webapp

Для каждого развертывания webapp развертывается стек контейнеров:

  • Один контейнер для процесса: Nginx, mysql, PHP-FPM,
  • Двоичные контейнеры (composer, bower,...) также могут быть задокументированы или объединены в контейнер phpfpm
  • тома монтирования для файлов данных mysql и webapp

Примеры:

Pro (IMHO):

  • отсоединенных
  • процессы изолированы на каждый экземпляр
  • Один процесс в контейнере, не нужен диспетчер демонов как RUnit или Supervisord

Против (IMHO):

  • Сложнее работать
  • Трудно поддерживать, видеть "общую картину" всех состояний контейнеров, ссылок, версий...

Решение 3. Смешайте два предыдущих решения

  • Один контейнер приложения с файлами приложения src, nginx, phpfmp, composer, git..
  • Один контейнер для db mysql, который может быть общим или нет с контейнером приложения

Я больше Dev, чем Ops, и это смутило меня.

Итак, вопросы:

  • Каковы критерии, плюсы и минусы для рассмотрения при выборе между этими решениями?
  • Как управлять всеми стеками контейнеров, если я выберу решение 2, чтобы иметь "общую картину" всех состояний контейнеров, ссылок, версии...?
  • Файлы приложения src (PHP) могут быть созданы в контейнере или установлены как тома, например. /var/www?
4b9b3361

Ответ 1

Недавно я провел анализ Docker для такого типа настроек. Я знаю, что есть некоторые, кто рассматривает Docker как своего рода MicroVM, но мой подход - философия Докера больше ориентирована на единый процесс на контейнер. Это хорошо отслеживается с принципом единой ответственности в программировании. Чем больше контейнер Docker, тем менее многоразовым и сложнее управлять. Я разместил здесь все свои мысли:

http://software.danielwatrous.com/a-review-of-docker/

Затем я продолжил сборку LEMP-стека с помощью Docker. Я не нашел большой ценности для разделения процессов PHP и Nginx на отдельные контейнеры Docker, но функции Web и Database находятся в отдельных контейнерах. Я также показываю, как управлять связыванием и распределением томов, чтобы избежать использования демонов SSH в ваших контейнерах. Вы можете следить за тем, что я здесь сделал, в качестве ориентира.

http://software.danielwatrous.com/use-docker-to-build-a-lemp-stack-buildfile/

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

Ответ 2

Оба решения возможны. Однако я бы пошел с решением 2 - один контейнер на процесс - поскольку он более совместим с философией Докера.

Хорошая вещь о Docker заключается в том, что вы можете создать стек приложений (например, ваш) с независимыми строительными блоками (изображениями отдельных приложений). Вы можете объединить эти строительные блоки и повторно использовать их. Если вы посмотрите официальный реестр Docker , вы найдете большинство ваших компонентов в качестве готовых образов. Например. вы найдете Nginx в https://registry.hub.docker.com/u/dockerfile/nginx и базу данных MySQL в https://registry.hub.docker.com/_/mysql. Таким образом, настройка вашего стека становится довольно простой, если вы решите использовать один контейнер для каждого процесса/приложения:

(Заметьте, это просто пример, я не знаком с PHP и т.д.)

Получить изображения:

docker pull mysql
docker pull dockerfile/nginx
docker pull tutum/apache-php

docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=mysecretpassword -d mysql
docker run -d -p 80:80 -v <sites-enabled-dir>:/etc/nginx/sites-enabled -v <log-dir>:/var/log/nginx dockerfile/nginx
docker run -d -p 80:80 tutum/apache-php

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

Самое сложное в этом решении - настроить ваш стек. Чтобы связать свои контейнеры, просмотрите https://docs.docker.com/userguide/dockerlinks. Вы можете использовать этот подход для ссылки, например. ваш контейнер приложения с вашим контейнером MySQL.