Микросервисы — это самый масштабируемый способ для разработки программного обеспечения. Но это громкое заявление мало что значит, если мы не выберем для себя правильный способ развёртывания микросервисов: процессы или контейнеры? Запускать на своих серверах или использовать облачные? Нужен ли мне Kubernetes? Когда дело доходит до микросервисной архитектуры, существует такое изобилие вариантов, что трудно понять, какой из них лучше.
Сегодня мы убедимся, что идеальное место для размещения микросервисного приложения во многом определяется его размером и требованиями к масштабированию. Итак, давайте рассмотрим 5 основных способов развёртывания микросервисов.
5 способов развёртывания микросервисов
Микросервисные приложения могут работать разными способами, каждый из которых имеет свои компромиссы и структуру затрат. То, что работает для небольших приложений, состоящих из нескольких сервисов, скорее всего, не подойдёт для крупномасштабных систем.
Вот пять способов запуска микросервисов — от простого к сложному:
- Одна машина, несколько процессов: купите или арендуйте сервер и запускайте микросервисы как процессы.
- Несколько машин, несколько процессов: очевидный следующий шаг — добавление дополнительных серверов и распределение нагрузки, что обеспечит лучшую масштабируемость и доступность.
- Контейнеры: упаковка микросервисов в контейнер облегчает их развёртывание и запуск вместе с другими сервисами. Это также будет первым шагом к Kubernetes.
- Оркестратор: оркестраторы, такие как Kubernetes или Nomad, представляют собой полноценные платформы, предназначенные для одновременного запуска тысяч контейнеров.
- Бессерверный: бессерверный способ позволяет забыть о процессах, контейнерах и серверах и выполнять код непосредственно в облаке.
Впереди два пути: один тянется от процессов к контейнерам и, в конце концов, к Kubernetes. Другой — подразумевает бессерверность.
Прим. переводчика: Артефакт — вспомогательный элемент продукта, так или иначе входящий в его состав.
Давайте рассмотрим каждый из них более подробно.
Вариант 1: одна машина, несколько процессов
На самом начальном уровне мы можем запустить микросервисное приложение в виде нескольких процессов на одной машине. Каждый сервис слушает свой порт и обменивается данными через loopback интерфейс.
В базовой форме развёртывания микросервисов используется всего одна машина. Приложение представляет собой группу процессов, объединённых балансировщиком нагрузки.
Прим. переводчика: bare metal — это серверная платформа без операционной системы, которая позволяет программному обеспечению получать прямой доступ к аппаратной части.
Этот простой подход имеет ряд очевидных преимуществ:
- Легковесность: нет накладных расходов, поскольку это просто процессы, выполняющиеся на сервере.
- Удобство: это отличный способ познакомиться с микросервисами без затрат времени на обучение, которого требуют другие инструменты.
- Простота устранения неполадок: всё находится в одном месте, поэтому поиск проблемы или возврат к рабочей конфигурации в случае неполадок очень прост, если у вас налажена непрерывная доставка.
- Фиксированная стоимость: мы точно знаем, сколько нам придётся платить каждый месяц.
Подход «сделай сам» лучше всего подходит для небольших приложений с небольшим количеством микросервисов. После того как приложение разрастётся — он становится неэффективным по ряду причин:
- Отсутствие масштабируемости: как только вы исчерпаете ресурсы сервера, на этом всё и закончится.
- Единая точка отказа: если сервер выходит из строя, приложение выходит из строя вместе с ним.
- Нестабильное развёртывание: нужны кастомные скрипты развёртывания и мониторинга, чтобы обеспечить правильную установку и работу сервисов.
- Отсутствие ограничений на ресурсы: любой процесс микросервиса может потреблять произвольные объёмы ресурсов процессора или памяти, что потенциально может привести к остановке работы других сервисов и деградации всего приложения.
Непрерывная интеграция (CI) для этого варианта будет работать по той же схеме: сборка и тестирование артефакта в конвейере CI, затем развёртывание с помощью непрерывного развёртывания (CD).
Для развёртывания исполняемых файлов, созданных в конвейере CI, требуются кастомные скрипты.
Это лучший вариант для изучения основ микросервисов, так как для ознакомления достаточно запустить одно небольшое микросервисное приложение. Его хватит надолго, пока не возникнет необходимость в расширении, и тогда вы сможете перейти к следующему варианту.
Вариант 2: несколько машин и процессов
Этот вариант, по сути, является усовершенствованием первого варианта. Когда приложение превышает возможности сервера, мы можем масштабировать его по вертикали (модернизировать сервер) или по горизонтали (добавить больше серверов). В случае микросервисов горизонтальное масштабирование на две или более машин имеет больше смысла, поскольку в качестве бонуса мы получаем улучшенную доступность. И как только у нас будет распределённая установка, мы всегда сможем расширить масштабирование путём модернизации серверов.
Балансировщик нагрузки по-прежнему является единой точкой отказа. Чтобы избежать этого, можно использовать несколько балансировщиков, работающих параллельно.
Горизонтальное масштабирование, однако, не лишено проблем. При переходе от одной машины проявляется несколько критических моментов, которые значительно усложняют поиск и устранение неисправностей, и возникают типичные проблемы, часто всплывающие при использовании микросервисной архитектуры:
- Как соотнести файлы журналов, распределённые между несколькими серверами?
- Как собирать необходимые статистические данные?
- Как справиться с обновлениями и простоями?
- Как реагировать на скачки и падения трафика?
Все эти проблемы присущи распределённым вычислениям. Как только вы задействуете более одной машины — вы обязательно столкнётесь с ними и будете вынуждены их решать.
Этот вариант отлично подходит, если у вас есть несколько свободных машин и вы хотите повысить доступность вашего приложения. Пока вы сохраняете упрощённую структуру и используете более или менее однородные сервисы (один и тот же язык, схожие фреймворки), всё будет в порядке. Как только вы преодолеете определённый порог комплексности, для обеспечения большей гибкости вам понадобятся контейнеры.
Вариант 3: развёртывание микросервисов с помощью контейнеров
Хотя запуск микросервисов непосредственно как процессов — очень эффективен, он сопряжён с определёнными издержками:
- Сервер должен тщательно обеспечиваться необходимыми зависимостями и инструментами.
- Запущенный процесс может поглотить всю память и ресурсы процессора.
- Развёртывание и мониторинг микросервисов — сложный процесс.
Все эти недостатки можно устранить с помощью контейнеров. Контейнеры — это пакеты, содержащие всё необходимое для работы программы. Образ контейнера — это самодостаточная единица, которая может запускаться на любом сервере без предварительной установки каких-либо зависимостей или инструментов (кроме самой среды выполнения контейнера).
Контейнеры обеспечивают достаточную виртуализацию для изолированного запуска программ. С их помощью мы получаем следующие преимущества:
- Изоляция: находящиеся в контейнере процессы изолированы друг от друга и от ОС. Каждый контейнер имеет частную файловую систему, поэтому конфликты зависимостей невозможны (при условии, что вы не злоупотребляете томами).
- Параллельность: мы можем запускать несколько экземпляров одного и того же образа контейнера без конфликтов.
- Меньше нагрузки: поскольку нет необходимости загружать целую ОС, контейнеры куда более легковесны, чем виртуальные машины.
- Развёртывание без установки: установка контейнера — это просто загрузка и запуск образа. Установка не требуется.
- Контроль ресурсов: мы можем установить ограничения на ресурсы процессора и памяти для контейнеров, чтобы они не дестабилизировали работу сервера.
Контейнерные рабочие нагрузки требуют этапа сборки образа на CI/CD.
Мы можем запускать контейнеры двумя способами: прямо на серверах или через удалённое управление.
Контейнеры на серверах
Этот подход заменяет процессы контейнерами, поскольку они дают нам большую гибкость и контроль. Как и в варианте 2, мы можем распределить нагрузку на любое количество машин.
Упаковка микросервисных процессов в контейнеры делает их более портативными и гибкими.
Бессерверные контейнеры
Все варианты, описанные до этого момента, были основаны на серверах. Но компании, производящие программное обеспечение, не занимаются управлением серверами (их необходимо настраивать, исправлять и обновлять) — они занимаются решением проблем с помощью кода. Поэтому не стоит удивляться, что многие компании предпочитают избегать использования серверов, когда это возможно.
Предложения типа Containers-as-a-Service (Контейнер-как-Услуга), такие как AWS Fargate и Heroku, позволяют запускать контейнерные приложения без необходимости иметь дело с серверами. Нам нужно только создать образ контейнера и направить его облачному провайдеру, который позаботится обо всём остальном: предоставит виртуальные машины, загрузит, запустит и проконтролирует образы. Такие управляемые услуги обычно включают встроенный балансировщик нагрузки, а это ещё на один повод для беспокойства меньше.
Elastic Container Service (сервис эластичных контейнеров) с Fargate позволяет нам запускать контейнеры без необходимости арендовать серверы. Они обслуживаются облачным провайдером.
Вот некоторые из преимуществ, которыми обладает управляемый контейнерный сервис:
- Отсутствие серверов: нет необходимости в обслуживании или патчах для сервера.
- Простота развёртывания: достаточно создать образ контейнера и попросить службу использовать его.
- Автомасштабирование: облачный провайдер может предоставить дополнительные мощности при резком росте нагрузки или остановить все контейнеры при полном отсутствии трафика.
Однако прежде чем вступать в бой, вы должны знать о нескольких существенных недостатках:
- Привязка к поставщику: это самый важный момент. Последующий переход от удалённого управления всегда сложен, поскольку поставщик облака предоставляет и контролирует большую часть инфраструктуры.
- Ограниченные ресурсы: управляемые услуги накладывают ограничения на использование процессора и памяти, которые невозможно обойти.
- Меньше контроля: у нас нет того уровня контроля, который мы получаем при использовании других вариантов. Вам не повезло, если вам нужна функциональность, которая не предоставляется управляемыми услугами.
Любой из вариантов контейнеров подойдёт для небольших и средних микросервисных приложений. Если вас устраивает ваш поставщик, проще воспользоваться управляемым контейнерным сервисом, поскольку он позаботится о многих деталях за вас.
Для крупномасштабных развёртываний, разумеется, оба варианта не подойдут. Как только вы достигнете определённого размера, у вас, скорее всего, появятся члены команды, имеющие опыт работы с такими инструментами, как Kubernetes (или желающие изучить их), которые полностью меняют способ управления контейнерами.
Вариант 4: оркестраторы
Оркестраторы — это платформы, специализирующиеся на распределении контейнерных рабочих нагрузок по группе серверов. Наиболее известным оркестратором является Kubernetes, проект с открытым исходным кодом, созданный Google и поддерживаемый Cloud Native Computing Foundation (фонд облачных вычислений).
Помимо управления контейнерами, оркестраторы предоставляют широкие сетевые возможности, такие как маршрутизация, безопасность, балансировка нагрузки и централизованные журналы — всё, что может понадобиться для запуска микросервисного приложения.
Kubernetes использует поды в качестве единицы планирования. Под — это группа из одного или нескольких контейнеров, имеющих общий сетевой адрес.
С Kubernetes мы уходим от кастомных скриптов для развёртывания. Вместо этого — мы кодируем желаемое состояние с помощью манифеста и позволяем кластеру позаботиться обо всём остальном.
Конвейер непрерывного развёртывания отправляет манифест на кластер, который предпринимает шаги, необходимые для его выполнения.
Kubernetes поддерживается всеми облачными провайдерами и является де-факто основной платформой для развёртывания микросервисов. Вы даже можете подумать, что это абсолютно лучший способ для запуска микросервисов и для многих компаний — это действительно так, но есть несколько моментов, о которых следует помнить:
- Сложность: оркестраторы известны своей сложной процедурой обучения. Нередко можно наделать глупостей, если не соблюдать осторожность. Для простых приложений оркестратор — это излишество.
- Бремя администрирования: обслуживание установки Kubernetes требует значительного опыта. К счастью, каждый приличный поставщик облачных решений предлагает управляемые кластеры, которые снимают всю работу по администрированию.
- Набор навыков: Разработка Kubernetes требует специальных навыков. Чтобы разобраться во всех тонкостях и научиться устранять неполадки при неудачном развёртывании, могут потребоваться недели. Переход на Kubernetes может быть медленным и привести к снижению вашей продуктивности, пока команда не освоится с новыми инструментами.
Kubernetes — самый популярный вариант для компаний, активно использующих контейнеры. Если это вы, то выбор в пользу оркестратора может оказаться единственно верным решением. Однако перед тем, как всё же перейти на Kubernetes, учтите, недавний опрос показал, что самая большая проблема для большинства компаний — поиск квалифицированных инженеров. Поэтому, если вы беспокоитесь о поиске разработчиков, следующий вариант может стать для вас лучшим выбором.
Вариант 5: развёртывание микросервисов как бессерверных функций
Бессерверные функции отличаются от всего остального, что мы обсуждали до этого. Вместо серверов, процессов или контейнеров мы будем использовать облако, чтобы просто запускать нужный код по мере необходимости. Бессерверные предложения, такие как AWS Lambda и Google Cloud Functions, обрабатывают все детали инфраструктуры, необходимые для масштабируемых и высокодоступных сервисов, оставляя нам возможность сосредоточиться на написании кода.
Бессерверные функции масштабируются автоматически и имеют тарификацию по факту использования.
Это совершенно другая парадигма с разными плюсами и минусами. С положительной стороны мы получаем:
- Простота использования: мы можем разворачивать функции на лету без компиляции или создания образов контейнеров, что отлично подходит для пробных запусков и создания прототипов.
- Простота масштабирования: вы получаете (по сути) бесконечную масштабируемость. Облако предоставит достаточно ресурсов, чтобы удовлетворить ваши потребности.
- Оплата за использование: вы платите в соответствии с потребляемыми ресурсами. Если ресурсы не используются — плата не взимается.
Тем не менее — недостатки могут быть значительными, что делает бессерверную систему непригодной для некоторых типов микросервисов:
- Привязка к поставщику: как и в случае с управляемыми контейнерами, вы покупаете экосистему поставщика. Переход от одного поставщика к другому может оказаться сложным.
- Холодные запуски: редко используемые функции могут запускаться очень долго. Это происходит потому, что поставщик облачных услуг «раскручивает» ресурсы, подключённые к неиспользуемым функциям.
- Ограниченные ресурсы: у каждой функции есть лимит памяти и времени — они не могут быть долгоиграющими процессами.
- Ограниченное время выполнения: поддерживается только несколько языков и фреймворков. Возможно, вы будете вынуждены использовать язык, который вам неудобен.
- Непредсказуемые счета: поскольку стоимость основана на использовании, трудно предсказать размер счёта в конце месяца. Всплеск использования может привести к неприятному сюрпризу.
Бессерверная система обеспечивает решение для масштабирования без вашего вмешательства. По сравнению с Kubernetes — он не даёт вам столько контроля, но с ним легче работать, поскольку для работы с бессерверными системами не нужны специализированные навыки. Бессерверная технология — отличный вариант для небольших быстрорастущих компаний, если они могут смириться с её недостатками и ограничениями.
Заключение
Лучший способ запуска микросервисного приложения определяется многими факторами. Один сервер с использованием контейнеров (или процессов) — это идеальная отправная точка для экспериментов или тестирования прототипов.
Если приложение уже развитое и включает в себя множество сервисов, вам потребуется что-то более надёжное, например, управляемые контейнеры или бессерверная система, а позднее, по мере роста приложения, возможно, и Kubernetes.
Ничто не мешает вам смешивать и сочетать различные варианты. На самом деле, большинство компаний используют сочетание bare metal серверов, виртуальных машин и Kubernetes. Сочетание таких решений, как запуск основных сервисов на Kubernetes, нескольких старых сервисов на ВМ и резерв бессерверных решений для важных стратегических функций, позволит прибегать к облаку, когда это необходимо и использовать его эффективнее.
Спасибо за внимание!
НЛО прилетело и оставило здесь промокод для читателей нашего блога:
— 15% на все тарифы VDS (кроме тарифа Прогрев) — HABRFIRSTVDS.
Комментарии (2)
dph
19.08.2022 16:33Насколько я помню, у AWS Lambda основная проблема - резкий рост нагрузки на хранилище, так как нет возможности какого-то кэширование контекста, все приходится вытаскивать из хранилища. Для каких-то простых операций с основной нагрузкой на проц вполне подходит. Для чего-то долговременного (видео отконвертировать) или связанного с взаимодействием (вызвать чужой сервис) или с данными (обогащение данных в запросе парочкой классификаторов) подобный подход вообще не применим.
Ну и у контейнеров не все так идеально с развертыванием. Как только возникают вопросы версионирования, миграции данных, откатов, сложных стратегий для canary и так далее - то сразу появляется куча проблем, которые решать совсем не просто и нужно писать свои скрипты для развертывания. Хотя, конечно, для домашних страничек или пет-проектов все просто.
zartdinov
Не думаю, что в бессерверных контейнерах на самом деле есть эти минусы. Можешь написать любой Dockerfile, подобрать мощности или развернуть свой образ у другого провайдера.
Просто у большинства компаний нормально не реализована эта услуга. В первую очередь предоставляют или просто Kubernetes (оркестрация), или серверные функции (привязка), ну максимум умирающие микроконтейнеры с тарификацией за каждый запрос. Может есть десяток компаний, где нормально сделано, пользовался AppPlatform от DigitalOcean.