Докер: как закрепить и развернуть несколько экземпляров приложения LAMP
Мне нужно развернуть многие экземпляры одного и того же приложения LAMP (или LEMP):
- каждый экземпляр будет доступен из субдомена, с фронтальным loadbalancer/proxy
- каждый экземпляр должен иметь свои данные и данные данных db.
- каждый экземпляр может отслеживаться
- ограничение памяти /cpu может быть установлено для каждого экземпляра приложения
- легко автоматизировать развертывание нового экземпляра webapp
- среда может быть легко воспроизведена для тестирования и разработки.
Приложение требует:
- процессы dameon (
Nginx
, MariaDB
, PHPFPM
)
- двоичные файлы (
composer
, bower
,...)
- другие системы, специфичные для libs и config
После прочтения документации Docker и многих способов, я вижу разные решения для докеретизации этого веб-приложения:
Решение 1. Используйте контейнер "все-в-одном"
Весь стек находится в одном контейнере:
- исходные файлы webapp, процессы демона EMP, двоичные файлы,...
- смонтированные тома для
mysql
и файлов данных webapp
Примеры:
Профи (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?
Ответы
Ответ 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.