Привет, Хабр!

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

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

Строим архитектуру мультикластерного сервиса

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

 

Исходный код наших приложений, как и артефакты для развёртывания (ресурсы Kubernetes, Helm-чарты или, например, шаблоны OpenShift), — всё размещается в системе версионного контроля. Дополнительно исходный код доступен в подготовленном для развёртывания виде — готовые docker-образы размещаются в корпоративном хранилище образов.

Теперь, когда у нас есть всё необходимое для развёртывания приложения, давайте подумаем, что нужно для того, чтобы сделать этот сервис мультикластерным.

Первая задача, которую надо решить, — деплоймент приложения. Когда у нас один кластер, это решается просто. Достаточно использовать kubectl apply либо более продвинутые подходы с шаблонами, например helm или шаблонизатор OpenShift.

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

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

  1. использует стандартные артефакты (образ приложения и манифесты с возможностью шаблонизации) для развёртывания;

  2. разворачивает приложение по заданному списку кластеров с обеспечением отката изменений по заданному набору критериев (например, при неуспешном деплойменте в один из кластеров);

  3. обеспечивает непрерывную доставку изменений с автоматической поддержкой консистентности деплоймента в мультикластерной среде.

Теперь давайте отразим этот сервис в архитектуре и посмотрим на промежуточную схему.

Вторая задача — обеспечение балансировки и аварийного переключения для внешних запросов.

«Однокластерный» подход начинается с использования Ingress Controller на границе Kubernetes. Дополнительно необходим балансировщик нагрузки, который обеспечит распределение трафика между узлами кластера, где запущены экземпляры Ingress Controller. Такой балансировщик может предоставляться облачным провайдером для managed-кластеров, а может быть настроен вручную для on-premise-инсталляций.

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

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

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

  1. предоставляет пользователю единый ресурс для публикации приложений в мультикластерной топологии;

  2. обеспечивает генерацию всех необходимых сетевых ресурсов в рамках всех кластеров для балансировки и аварийного переключения внешних запросов;

  3. обеспечивает непрерывную доставку изменений с автоматической поддержкой консистентности в мультикластерной среде.

Таким образом, после решения второй задачи наша архитектура выглядит как на рисунке ниже:

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

Таким образом, нам необходим сервис, который:

  1. обеспечивает возможность публикации сервисов из удалённых кластеров в текущем, при этом удалённые сервисы доступны для вызова тем же способом, что и локальные;

  2. в ситуации, когда удалённый сервис имеет экземпляры и в текущем кластере, обеспечивается объединение удалённых и локальных экземпляров в рамках единого вызываемого адреса;

  3. для удалённых сервисов, в том числе и с локальными экземплярами, обеспечивается балансировка и аварийное переключение по заданным правилам. Например, в случае недоступности локальных экземпляров удалённого сервиса трафик переключается на удалённые экземпляры в других кластерах.

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

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

Для обеспечения достаточного уровня обозреваемости нам потребуется сервис, который:

  1. агрегирует журналы приложений, данные трассировки и данные мониторинга (метрики) с учётом мультикластерной топологии развёртывания;

  2. предоставляет унифицированный доступ к агрегированным данным.

В итоге мы получаем готовую архитектуру мультикластерного сервиса:

Реализуем архитектуру

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

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

А ещё данная архитектура может быть легко имплементирована на базе продуктов Platform V Synapse. Это позволит не тратить ресурсы, не привязываться к сервису конкретного облака и сконцентрироваться исключительно на бизнес-логике.

Platform V Synapse — cloud-native децентрализованная интеграционная платформа для импортозамещения любых корпоративных сервисных шин. Входит в состав Platform V — облачной платформы для разработки бизнес-приложений, которая стала основой цифровизации Сбера.

Synapse построена на основе современного технологического стека и использует передовые open sourсe и cloud native технологии: Envoy, Kafka, Flink, Ceph, Kiali, Docker и другие.

В составе 6 ключевых модулей:

  • Synapse Service Mesh — надёжная интеграция и оркестрация микросервисов в облаке;

  • Synapse Nerve — безопасная передача файловой информации между системами и микросервисами в облаке, со встроенными средствами визуализации, мониторинга и анализа данных;

  • Synapse EDA — потоковая обработка событий;

  • Synapse AI — предиктивное управление трафиком, обогащаемое при помощи искусственного интеллекта и машинного обучения;

  • Synapse AppSharding — реализация горизонтального масштабирования для БД, не поддерживающих sharding «из коробки»;

  • Synapse API Management — публикация, управление доступом и аналитика использования API.

Сбер использует Platform V Synapse уже больше двух лет. За это время платформа позволила уменьшить среднее время задержки отклика систем с 50 мс до 8 мс, снять ограничения по масштабированию и снизить связанность систем. Synapse продемонстрировала отказоустойчивость 99,99%, выдержала нагрузки более 50 000 tps и сократила стоимость разработки на 54%.

В Сбере Synapse стала базой для миграции с legacy на микросервисный подход. Теперь продукт поставляется бизнесу и государству по модели PaaS и on-premise.

Комментарии (1)


  1. AlexGluck
    29.04.2022 23:21
    +1

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