Вы можете создать одно монолитное веб-приложение или службу и развернуть их как контейнер. Само приложение может не иметь монолитную внутреннюю структуру и состоять из нескольких библиотек, компонентов или даже уровней (прикладной уровень, уровень домена, уровень доступа к данным и т. д.). Но внешне оно будет представлять собой единый контейнер — единый процесс, единое веб-приложение или единую службу.
Для управления этой моделью вы развертываете один контейнер, представляющий собой приложение. Чтобы увеличить емкость, вы используете горизонтальное масштабирование, то есть просто добавляете больше копий с подсистемой балансировки нагрузки спереди. Управлять одним развертыванием в одном контейнере или виртуальной машине гораздо проще.
Рис. 4-1. Пример архитектуры монолитного приложения в контейнере
Вы можете включить в один контейнер несколько компонентов, библиотек или внутренних уровней, как показано на рисунке 4-1. Монолитное контейнерное приложение содержит большую часть функциональности в одном контейнере с внутренними слоями или библиотеками и горизонтально масштабируется путем клонирования контейнера на нескольких серверах или виртуальных машинах. Такой монолитный шаблон может конфликтовать с принципом контейнера: "контейнер выполняет одно дело и в одном процессе", — но в некоторых случаях это не проблема.
Недостаток этого подхода становится очевидным, когда приложение разрастается и его необходимо масштабировать. Если можно масштабировать приложение целиком, все получится. Но в большинстве случаев необходимо масштабировать всего несколько частей приложения, пока другие компоненты работают нормально.
Например, в типичном приложении для электронной коммерции, скорее всего, придется масштабировать подсистему сведений о продуктах, поскольку клиенты чаще просматривают продукты, чем покупают. Клиенты чаще складывают товары в корзину, чем оплачивают их. Не так много клиентов пишут комментарии или просматривают историю покупок. И у вас может быть всего несколько сотрудников, которые управляют содержимым и маркетинговыми кампаниями. При масштабировании монолитной конструкции весь код для различных задач развертывается несколько раз и масштабируется в одинаковой степени.
Существует несколько способов масштабирования приложения — горизонтальное копирование, разделение различных областей приложения и секционирование схожих бизнес-концепций или данных. Но, во первых, необходимо масштабировать все компоненты, а во-вторых, изменения в одном компоненте требуют полного повторного тестирования всего приложения и полного повторного развертывания всех экземпляров.
Все же монолитная конструкция широко распространена, поскольку на начальном этапе разрабатывать такое приложение проще, чем использовать микрослужбы. Поэтому такой архитектурный подход используется во многих организациях. И хотя некоторым удалось достичь достаточно хороших результатов, другие сталкиваются с серьезными ограничениями. Во многих организациях приложения строились по такой модели, поскольку несколько лет назад с помощью существующих инструментов и инфраструктуры слишком сложно было создавать архитектуры, ориентированные на службы (SOA), и проблем не возникало, пока приложение не начинало разрастаться.
С точки зрения инфраструктуры, каждый сервер может выполнять множество приложений в одном узле и применять допустимое соотношение эффективности использования ресурсов, как показано на рисунке 4-2.
Рис. 4-2. Монолитная конструкция: узел выполняет несколько приложений, каждое приложение выполняется как контейнер
Монолитные приложения в Microsoft Azure можно развертывать с использованием выделенных виртуальных машин для каждого экземпляра. Кроме того, с помощью масштабируемых наборов виртуальных машин Azure можно легко масштабировать виртуальные машины. Служба приложений Azure также может выполнять монолитные приложения и легко масштабировать экземпляры, и вам не придется управлять виртуальными машинами. С 2016 года службы приложений Azure также могут выполнять отдельные экземпляры контейнеров Docker, упрощая развертывание.
В качестве среды контроля качества или ограниченной рабочей среды можно развертывать несколько виртуальных машин с Docker и распределять нагрузку с помощью средства балансировки Azure, как показано на рисунке 4-3. Так вы сможете управлять масштабированием, не используя крупные элементы, поскольку все приложение размещено в одном контейнере.
Рис. 4-3. Пример масштабирования приложения в одном контейнере с помощью нескольких узлов
Развертыванием на различных узлах можно управлять с помощью традиционных методов развертывания. Узлами Docker можно управлять с помощью вводимых вручную команд docker run или docker-compose или автоматизированно, например с помощью конвейеров непрерывной поставки (CD).
Развертывание монолитного приложения в контейнере
Использование контейнеров для управления развертываниями монолитных приложений имеет свои преимущества. Масштабировать экземпляры контейнера гораздо быстрее и проще, чем развертывать дополнительные виртуальные машины. Даже при использовании масштабируемых наборов виртуальных машин им необходимо время на запуск. При развертывании в виде традиционных экземпляров приложений вместо контейнеров настройками приложения приходится управлять в рамках виртуальной машины, и это не лучшее решение.
Развертывание обновлений в виде образов Docker выполняется гораздо быстрее и эффективнее с точки зрения использования сети. Образы Docker обычно запускаются за считанные секунды, что позволяет ускорить выпуск. Остановить образ Docker можно с помощью команды docker stop, и обычно это происходит моментально.
Поскольку контейнеры неизменны по своей природе, вам не придется беспокоиться о поврежденных виртуальных машинах. Напротив, скрипты обновления для виртуальной машины могут не учесть определенную конфигурацию или забыть файл на диске.
Docker имеет много плюсов для монолитных приложений, но это еще не полный список преимуществ. Дополнительные возможности при управлении контейнерами открываются благодаря развертыванию с помощью оркестраторов контейнеров, которые управляют различными экземплярами и жизненным циклом каждого экземпляра контейнера. Когда вы разбиваете монолитное приложение на подсистемы, которые затем можно масштабировать, разрабатывать и развертывать по отдельности, вы переходите на уровень микрослужб.
Публикация приложения в одном контейнере в службе приложений Azure
Когда вы хотите проверить контейнер, развернутый в Azure, или когда приложение содержится в одном контейнере, вы можете воспользоваться удобными службами масштабирования контейнеров в службе приложений Azure. Использовать службу приложений Azure очень просто. Она прекрасно интегрируется с Git, так что вы можете взять свой код, скомпилировать его в Visual Studio и развернуть прямо в Azure.
Рис. 4-4. Публикация приложения в одном контейнере в Службе приложений Azure из Visual Studio 2022
Если вам понадобятся другие возможности, платформы или зависимости, не поддерживаемые службой приложений Azure, без Docker пришлось бы ждать, пока команда Azure обновит эти зависимости в службе приложений. Или пришлось бы переключиться на другие службы, например Облачные службы Azure, или даже виртуальные машины, где у вас было бы больше возможностей и можно было бы установить необходимый компонент или платформу для приложения.
Благодаря поддержке контейнеров в Visual Studio 2017 и более поздних версий вы можете включать в среду приложения любые компоненты, как показано на рисунке 4-4. Поскольку приложение выполняется в контейнере, при добавлении зависимости можно включить ее в Dockerfile или образ Docker.
На рисунке 4-4 также показано, что поток публикации отправляет образ через реестр контейнеров. Это может быть реестр контейнеров Azure (реестр, близкий к вашим развертываниям в Azure и защищенный группами и учетными записями в Azure Active Directory) или другой реестр Docker, например центр Docker или локальный реестр.