Технология в деталях №19, ноябрь 2023

Эволюция облачных вычислений: от сырой инфраструктуры к облаку бессерверных приложений

Фото аватара
Билгин Ибрям

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

Рис. 1. Облачные вычисления, превращающие стек приложений в продукт.

Дооблачная эпоха 2000- Эпоха (становления) облачной инфраструктуры 2010- Эпоха облачных приложений 2020-
Monolith Монолитное приложение Microservices Микросервисы Business logic Бизнес-логика, логика функционирования приложения
On-premise infra Локальная инфраструктура Kubernetes Кубернетес Infrastructure cloud Облачная инфраструктура
Dev Разработка,Dev Cloud Infra Облачная инфраструктура Application APIs Программные интерфейсы приложения
Ops Операции, Ops Cloud native APIs Облачно-ориентированные программные интерфейсы (API) Runtime APIs Программные интерфейсы  среды выполнения
Operating system APIs API-интерфейсы операционной системы Dev Разработка,  Dev
Ops Операции,  Ops
Application cloud Облако приложений
App blended with the cloud Приложение, объединенное с облаком

В данной статье мы рассмотрим основные этапы эволюции, характеризующиеся присущими им тенденциями развития инфраструктуры и архитектуры приложений, а также выполняемыми функциями. Для наглядности мы будем использовать AWS (Amazon Web Services; веб-сервисы Amazon), но те же тенденции можно наблюдать и у других облачных сервисов. Также мы рассмотрим, посредством каких типов API взаимодействуют приложения и инфраструктура и как функции приложений смещаются в сторону инфраструктуры, прежде чем стать продуктом облачных сервисов.

Дооблачная эра

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

Рис. 2. Дооблачная эра монолитных приложений и статической инфраструктуры.

monolithic application Монолитное приложение
business logic Бизнес-логика
Asynchronous interactions Асинхронные взаимодействия
Stateful workflow orchestration Оркестрация рабочих процессов с сохранением состояния
Runtime management Управление временем выполнения
Synchronous communication Синхронная коммуникация
Operating system API API операционной системы
Native protocols Платформо-зависимые протоколы
Operating system APIs API операционной системы
Static IPs Статические IP-адреса
Storage Хранилище
Compute Вычисление
Network Сеть
self-managed static infra Самоуправляемая статическая инфраструктура

 

Статическая инфраструктура

С точки зрения инфраструктуры, это время до появления Kubernetes и первых дней внедрения AWS EC2. Основной характеристикой этой эпохи является статичный характер инфраструктуры, состоявшей из больших виртуальных машин. Элементы этой инфраструктуры содержат множество приложений и даже некоторые динамические компоненты с отслеживанием состояния, такие как базы данных, брокеры сообщений и хранилища контента.

Монолитные приложения

Наилучшими представителями этой архитектуры со стороны приложения являются SOA (сервис-ориентированная архитектура) и ее реализация — Enterprise Service Bus (сервисная шина предприятия). Эти приложения имели большое монолитное развертывание, способное удовлетворить такие потребности, как:

  • Развертывание в среде выполнения: новые релизы обычно упаковываются в виде библиотек и планируются к выполнению на заранее выбранных узлах с возможностью ручного отката.
  • Синхронное взаимодействие: возможность обнаружения сервисов, балансировки нагрузки, повторного выполнения операции, разрыва цепи и т.д. Важно не только перераспределение трафика и пробный релиз, но и то, что новые выпуски будут выполняться за один раз для всего приложения и иметь взаимодействие с архитектурой in-memory.
  • Асинхронное взаимодействие: наличие обширного ассортимента соединителей с возможностью преобразования, фильтрации и маршрутизации сообщений и событий.
  • Рабочие процессы с отслеживанием состояния: основной характеристикой монолитной архитектуры является общее для всех элементов состояние, что упрощает выполнение оркестровок с отслеживанием состояния, идемпотентности, кеширования, запланированных задач и т.д.

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

Операционная система как аппаратно-программный интерфейс

В дооблачную эру отсутствуют общие абстракции приложений и инфраструктуры, а также технологии и практики, совместно используемые командами разработчиков и операторов. Эти разрозненные команды используют операционную систему, фиксированные IP-адреса и виртуальные машины в качестве разграничения стека приложений. Операционная группа отвечает за подготовку виртуальных машин и обеспечение достаточного количества дополнительных мощностей для будущего роста приложений. Разработчики отвечают за реализацию всех аспектов распределенного приложения, работающего на этой инфраструктуре. Из-за отсутствия универсального формата пакетирования и API для развертывания и размещения каждое приложение будет выпускаться в виде уникальной коллекции библиотек с инструкциями, написанными в удобной для восприятия человеком «вики-форме», а не в виде машинного исполняемого файла, который можно воспроизвести. API, с которыми взаимодействуют приложение и инфраструктура, — это API операционной системы в виде запуска процесса, его завершения, фиксированных IP-адресов машин, а не абстракции приложений. В эпоху инфраструктурного подхода приложение является «гражданином второго сорта», и разработчикам приходится адаптировать и приспосабливать приложение к форме и интерфейсам инфраструктуры.

Эпоха инфраструктурно-центричных облаков

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

Рис. 3. Эпоха инфраструктурных облаков микросервисов и Kubernetes.

Infra cloud era Эпоха (становления) облачной инфраструктуры 2010-
Self-managed integration Самоуправляемая интеграция
Microservices Микросервисы
Asynchronous interactions
Spring Integration, Apache Camel, Dapr, Knative WSO2, Mulesoft Spring Integration, Apache Camel, Dapr, Knative WSO2, Mulesoft
Stateful workflows Рабочие процессы с отслеживанием состояния
Netflix’s Conductor

Uber’s

Cadence JBPM, Camunda

Temporal KSQL

Netflix’s Conductor

Uber’s

Cadence JBPM, Camunda

Temporal KSQL

Synchronous communication Синхронное взаимодействие
Istio

Linkerd

Cillium

Apollo/GraphQL

Dapr

Istio

Linkerd

Cillium

Apollo/GraphQL

Dapr

Runtime mgmt Управление выполнением
AWS EKS/Kubernetes AWS EKS/Kubernetes
(Cloud-native APIs) (Облачные API)
Infrastructure-centric cloud Инфраструктурно-ориентированное облако
managed runtime Управляемая среда исполнения
DevOps & GitOps DevOps & GitOps
Containers & Kubernetes APIs Контейнерные и Kubernete API
Virtual networks/HTTPS Виртуальные сети/HTTPS

 

Облачно-ориентированная инфраструктура

В эту эпоху происходят два крупных инфраструктурных сдвига. Во-первых, это внедрение облачной инфраструктуры и переход на EC2, ELB, RDS и т.д. Эти облачные сервисы предлагают те же массивные инфраструктурные единицы и API, что и локальная инфраструктура, но перекладывают ответственность за управление, мониторинг, масштабируемость и надежность от внутренней операционной группы к облачным провайдерам. Вторая важная тенденция — появление контейнеров и Kubernetes, которые приводят к управляемому жизненному циклу приложений. Контейнеры обеспечили универсальный формат пакетирования, изоляции и выполнения приложений. А Kubernetes представил абстракции и декларативные API для массовой оркестровки приложений, при этом заботясь о жизненном цикле и сетевых проблемах. Благодаря этим двум скачкам исходная инфраструктура была перенесена в облако, а ответственность за жизненный цикл приложений перешла к инфраструктурным подразделениям. Давайте посмотрим, как это повлияло на прикладной уровень.

Микросервисная архитектура

Поскольку монолитные приложения распадались на независимые развертывания, первоначальные микросервисы содержали в себе слишком много инфраструктуры. С появлением контейнеров и технологий Kubernetes и Service Mesh эти обязанности были вынесены за пределы стека приложений. Проблемы жизненного цикла и развертывания, такие как тестирование работоспособности, масштабирование и конфигурирование, стали частью уровня инфраструктуры, будь то Kubernetes Pods, AWS Beanstalk или Heroku Dynos. Сетевые проблемы также вышли за рамки прикладного уровня. Обнаружение служб, балансировка нагрузки, mTLS, отказоустойчивость сети – все это начало переходить сначала к связанным приложениям, таким как Envoy, затем к агенту общего узла, такому как Ztunnel от Istio, а некоторые функции, такие как наблюдаемость и mTLS, даже дальше, в ядро Linux через eBPF и Cilium. В результате интеграция, управляемая событиями, и обязанности по рабочему процессу, влияющие на поток управления приложением и бизнес-логику, на данный момент остаются в пределах приложения и досягаемости разработчиков. Но вместо встраивания в монолитное приложение они будут развернуты как автономные промежуточные программы, некоторые из которых ориентированы на обработку событий (например, экосистема Kafka), некоторые – на отслеживание состояния (Camunda), а некоторые – на другие библиотеки, предлагающие возможности интеграции без сохранения состояния (например, Apache Camel).

Kubernetes как API

Когда необработанная инфраструктура стала продуктом, поставщики облачных услуг переключили свое внимание на уровень приложений. Контейнеры и API Kubernetes стали общепринятыми для упаковки приложений и управления жизненным циклом ресурсов. Это первый случай, когда появляется общепринятый API-интерфейс, ориентированный на приложение, который управляет жизненным циклом и сетевыми аспектами приложения, а не всей виртуальной машиной. После упаковки приложения в образ контейнера с указанием портов и проверок работоспособности приложение можно передать команде эксплуатации для масштабного запуска в виде «черного ящика» без каких-либо ручных вмешательств. Что касается сети, HTTP и REST стали нормой для синхронного взаимодействия приложений, а реализации Service Mesh использовались для управления этим трафиком с помощью функций переключения, наблюдаемости, mTLS и отказоустойчивости. Это время, когда разработчики и рабочие группы начали использовать общие инструменты и практики, такие как GitOps и DevOps, что в целом привело к улучшению сотрудничества между ними. Это означало, что существует общий API для жизненного цикла приложения и сетевых аспектов, который создает основу для следующего этапа превращения в продукт того, что осталось от прикладного уровня.

Эра облачных технологий, ориентированных на приложения

Сегодня жизненный цикл приложения и работа в сети управляются в основном прозрачно для приложения. За исключением одной или двух конечных точек работоспособности разработчикам не нужно ничего кодировать в приложении, чтобы облачная среда выполнения могла запускать, масштабировать и направлять трафик в приложение. Эти сервисы облачной среды исполнения работают прозрачно для приложения, используя абстракции на основе контейнеров для жизненного цикла и методов маршрутизации трафика HTTP/TCP. Но это не относится к аспектам интеграции (речь идет о рабочих процессах на основе событий или с отслеживанием состояния) распределенных приложений, которые напрямую взаимодействуют с потоками управления приложениями и бизнес-логикой. То, что я здесь называю «Облаком приложений», это совокупность облачных сервисов, имеющих отдельные API-интерфейсы и взаимодействующих с приложением через специально созданные конечные точки.

Рис. 4. Приложения в сочетании с облачными сервисами среды выполнения и интеграции.

Application Cloud Era Эпоха облачных приложений
Managed integration Управляемая интеграция
Apps blended with cloud Приложения, совмещенные с облаком
Asynchronous interactions Асинхронное взаимодействие
AWS EventBridge
Confluent CloudDiagrid Cloud (Dapr)
AWS EventBridge
Confluent CloudDiagrid Cloud (Dapr)
Integration APIs, used by Devs Технический стандарт сопряжения информационных систем, используемый разработчиками
Stateful workflows Рабочие процессы с отслеживанием состояния
AWS Simple Workflow AWS Step Functions Orkes (Netflix Conductor) Instaclustr Cadence Temporal Cloud

Diagrid Cloud (Dapr)

Upstash

Momento

AWS Simple Workflow AWS Step Functions Orkes (Netflix Conductor) Instaclustr Cadence Temporal Cloud

Diagrid Cloud (Dapr)

Upstash

Momento

Synchronous communication Синхронное взаимодействие
AWS API gateway AWS App Mesh AWS ALB AWS AppSync AWS API gateway AWS App Mesh AWS ALB AWS AppSync
Runtime mgmt Управление выполнением
AWS ECS AWS Fargate AWS App Runner AWS Lambda AWS ECS AWS Fargate AWS App Runner AWS Lambda
Plug apps into APIs Приложения, подключенные к API
Govern apps & cloud Управление приложениями и облаком
Developers Разработчики
SRES SRES

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

Инфраструктура, ориентированная на приложения

В этой только что начавшейся облачной эволюции облачные сервисы «сырой» инфраструктуры (такие как AWS EC2) отодвигаются на задний план и становятся прозрачными для разработчиков. Возникает новое облако бессерверной инфраструктуры, такое как AWS App Runner, которое работает на уровне детализации приложения, а не виртуальной машины, отвечает за выполнение приложения, масштабирование, конфигурацию и сетевое взаимодействие. Облачная инфраструктура трансформируется в ориентированную на приложения бессерверную среду выполнения и сетевого взаимодействия.
Более интересный аспект этой эпохи — появление облачных сервисов, которые сочетаются с потоками управления приложениями. Это службы интеграции для организации рабочего процесса, управляемого событиями. Эти службы отслеживают состояния и взаимодействуют с приложением непосредственно через конечные точки приложения. Такие облачные сервисы могут быть явно подготовлены и сконфигурированы или динамически созданы по запросу из DSL в коде приложения. В качестве примера можно привести пошаговые функции AWS, рабочие процессы Google Cloud или рабочие процессы Temporal Cloud, которые организуют последовательность операций, выполняемых в вашем приложении. Или AWS Event Bridge, который доставляет отфильтрованные и преобразованные события в ваше приложение, или EventArc от Google. Или бессерверная служба Dapr, которая связывает сторонние API, триггеры на основе Cron и другие приложения с вашим. Эти новые службы «Облака приложений» связаны с приложением на более глубоком уровне, чем бессерверная служба среды выполнения, отвечающая только за жизненный цикл приложения.

Облачные приложения

«Облако приложений» не определяет, основано ли ваше приложение на микросервисах, функциях или чем-то еще. В этой модели часть логики интеграции и управления приложениями выгружается в облако и используется как услуга. Это форма использования сложных и повторяющихся специализированных конструкций разработчика посредством четких API-интерфейсов и гарантированных соглашений об уровне обслуживания, а не их реализация или импорт в приложение. Эти конструкции могут быть службой соединения, вызывающей метод приложения, службой оркестровки с отслеживанием состояния, которые вызывают конечные точки приложения для фиксации бизнес-транзакции или точку выхода в случае сбоя. Это может быть просто конечная точка распределенной блокировки, триггер на основе Cron или уведомление об обновлении конфигурации. Используя эти примитивы в качестве бессерверной службы, разработчики приложений могут сосредоточиться на реализации уникальной бизнес-логики, а операционные группы — на управлении и контроле лучших в своем классе реализаций служб.

Открытый исходный код как источник де-факто API

Чтобы «Облако приложений» могло связываться с приложением таким образом, чтобы его можно было заменить другими сервисами, ему необходим четкий API, который может вызываться приложением или наоборот. В идеале этот API должен быть общепринятым, многоязычным и независящим от облака, точно так же, как контейнеры и Kubernetes абстрагируют инфраструктуру и сеть. Такие API-интерфейсы должны получить широкое распространение и стать стандартом де-факто в своих областях, точно так же как контейнеры используются для упаковки и изоляции ресурсов, а Kubernetes — для их оркестровки. Сегодня одним из проверенных способов создания таких стандартов API де-факто является использование модели разработки с открытым исходным кодом в сочетании с прозрачной моделью управления нейтральной программной основой. Удачными примерами этих API являются такие проекты, как Open Tracing, Prometheus для метрик, Kafka для журналов событий, Dapr для интеграции и т.д. Есть также примеры отраслевых стандартов, которые возникли не из среды открытого исходного кода и открытого управления, например, GraphQL для запроса данных, AWS S3 для хранилища объектов и другие. Все это примеры стандартов API, которые фактически используются в приложениях и в конечном итоге становятся доступными в виде облачных сервисов сами по себе.

Краткий итог

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

 Приложения, сочетающиеся с облачными сервисами среды выполнения и интеграции

Дооблачная эпоха (2000) Эпоха становления облачной инфраструктуры (2010 г.) Эпоха облачных приложений (2020 г.)
Архитектура приложения Монолит (например: SOA/ESB) Микросервисы, функции Микросервисы и функции, связанные с облаком
Обмен сообщениями и рабочие процессы [управляются разработчиками] Контейнеризованное промежуточное программное обеспечение [управляется операторами] Новое «облако приложений» [управляется облаком]
Жизненный цикл и сеть [управляются разработчиками] Kubernetes и сервисная сетка (управляется операторами или облаком) «Облако среды выполнения» в первую очередь для приложений [управляется облаком]
внутренняя инфраструктура Локальная

[управляется операторами]

Облачная

[управляется облаком]

Скрытая [управляется облаком]

В условиях, когда все крупные облачные провайдеры переключают внимание на среду выполнения, ориентированную на приложения и сервисы интеграции, самый масштабный переход еще впереди. Увеличивается число облачных сервисов приложений для организации событий и управления состоянием. Это новое поколение сервисов, которые объединяются с приложением для предоставления надежно защищенного способа разработки. Эти прикладные сервисы изменят взгляд на архитектуру приложений, превратив ее из единого модуля развертывания в единое целое с облаком. Создание нового поколения облачных сервисов, образующих новое «Облако приложений», только началось.

Литература:

[1] https://www.diagrid.io/blog/evolution-of-cloud-computing

Об авторе:

Билгин Ибрям (Bilgin Ibryam), руководитель продукта в Diagrid, работающий над API-интерфейсами для повышения производительности разработчиков, https://www.diagrid.io/contact-us