Service Mesh глазами бэкендера: умный дирижёр микросервисного оркестра

4f92be8d2dd2ed1a89f0353c4fcd982a.jpg

Service Mesh — это «умная» сеть для управления трафиком между сервисами. Углубимся в детали и разберём, как эта технология упрощает жизнь DevOps-инженеров и разработчиков.

Привет, Хабр! Алексей Ушаровский — бэкенд разработчик в международном финтехе, эксперт Skillbox по Java и Kotlin. На текущем проекте ему приходится сталкиваться не только с бэкендом, но и с технологиями DevOps. На закрытом эфире для комьюнити Skillbox Code Experts рассказал про свой опыт работы с технологией Service Mesh. Делимся с вами в этой статье.

Что же такое Service Mesh?

Если вы работаете с микросервисной архитектурой, то наверняка сталкивались с проблемами управления трафиком между сервисами, их аутентификацией и мониторингом. Здесь на помощь приходит Service Mesh — дополнительный инфраструктурный слой, который берёт на себя все эти задачи, разгружая код сервисов и упрощая их взаимодействие.

Проще говоря, Service Mesh — это «умная» сеть для сервисов, которая управляет их взаимодействием без необходимости вносить изменения в сам код. Она позволяет маршрутизировать трафик, обеспечивать его безопасность, управлять отказоустойчивостью и проводить мониторинг работы сервисов.

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

Как раньше работал Service Discovery

Когда микросервисная архитектура только появилась, одна из первых проблем, с которой столкнулись разработчики — как сервисы находят друг друга? Ведь в распределённой системе, где сервисы динамически появляются и исчезают, нельзя просто захардкодить IP-адреса.

Решением стало централизованное сервисное хранилище. Например, Netflix Eureka — один из первых механизмов Service Discovery, который работал так:

  1. Каждый сервис регистрировался в Eureka.

  2. Если сервису нужно было обратиться к другому, он запрашивал у Eureka актуальный адрес.

  3. Eureka возвращала актуальный endpoint, и сервис отправлял запрос.

Такая схема работала, но имела ряд проблем:

  • Централизованный реестр — единственная точка отказа.

  • Задержки: перед каждым вызовом приходилось делать дополнительный запрос в сервис-директорию.

  • Нагрузка: при большом количестве сервисов этот механизм становился узким местом.

Затем появились контейнерные оркестраторы, такие как Kubernetes, которые предложили встроенный механизм Service Discovery.

Как Kubernetes упростил Service Discovery

С появлением Kubernetes проблема была частично решена:

  • Каждый сервис в кластере получает DNS-имя (например, my-service.namespace.svc.cluster.local).

  • Запросы можно отправлять по предсказуемым DNS-адресам без дополнительного реестра.

  • Kubernetes автоматически перенаправляет трафик между экземплярами сервиса.

Этот механизм намного лучше, чем централизованный реестр, но он не решает всех проблем.

Что если нам нужно:

  • Динамически балансировать нагрузку между версиями сервиса.

  • Применять политики безопасности (шифрование, аутентификацию, авторизацию).

  • Контролировать таймауты, ретраи и предохранители (circuit breakers).

Тут на сцене как раз и появляется Service Mesh.

Как работает Service Mesh

Допустим, у нас есть Kubernetes-кластер (или другой оркестратор контейнеров). Внутри него работают десятки или даже сотни микросервисов, которые должны правильно взаимодействовать друг с другом. Они обмениваются запросами и передают данные — и всё это должно быть надёжным, безопасным и предсказуемым.

Service Mesh решает эту задачу за счет прокси-сервисов (sidecars), которые добавляются к каждому микросервису и перехватывают весь сетевой трафик. Таким образом, управление трафиком, аутентификация и мониторинг выполняются на уровне инфраструктуры, а не в коде самого сервиса.

Ключевые функции Service Mesh

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

Что можно получить из коробки:

  • Метрики по трафику — сколько запросов прошло, сколько было успешных/ошибочных.

  • Трассировка (Tracing) — полное понимание, как запросы перемещаются между сервисами, где происходят задержки.

  • Логирование — анализ отказов и аномалий в коммуникации.

Всё это позволяет быстрее находить и устранять узкие места. Чаще всего используются Prometheus + Grafana + Jaeger, но Service Mesh интегрируется и с другими инструментами мониторинга.

Отказоустойчивость и контроль запросов — Service Mesh помогает не только видеть проблемы, но и предотвращать их. Для этого существуют встроенные механизмы, такие как:

  • Retry Policy — повторный запрос при временных сбоях.

  • Timeouts — автоматическое завершение зависших запросов.

  • Circuit Breaking — защита от лавинообразных сбоев, когда сервис временно отключает «падающий» инстанс.

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

Рассмотрим Retry Policy.
Допустим, у нас есть сервис order-service, который иногда отвечает с задержкой. Без Service Mesh нам пришлось бы добавлять логику ретраев в код каждого клиента.

С Istio это решается декларативно:

30fdcfe5715c9cef1a0ab763cdd706a1.png

Происходит следующее:

Если сервис order-service не отвечает в течение двух секунд, Istio автоматически повторит запрос три раза.

Так мы задаём стратегию ретраев: повторять при gateway-error, connect-failure и refused-stream.

Все настройки применяются на уровне Service Mesh, код приложения остаётся неизменным.

Балансировка нагрузки. Когда мы говорим про балансировку нагрузки в Service Mesh, большинство вспоминает Round Robin — один из самых простых и популярных алгоритмов распределения трафика. Но в Service Mesh есть множество других стратегий, которые можно гибко настраивать:

  • Random — распределяет запросы случайным образом между доступными сервисами.

  • Least Connections — направляет запрос к сервису с наименьшим числом активных соединений.

  • Weighted Round Robin — учитывает вес каждого инстанса, позволяя направлять больше трафика на более мощные узлы.

  • Consistent Hashing — полезен для кэширования или сценариев, когда важно, чтобы один и тот же клиент всегда попадал на один и тот же бэкенд.

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

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

В Istio мы можем задать ограничения:

78465fe153920a13148765569a2ffdf9.png

Это работает так:

  • http1MaxPendingRequests: 100 — если в очереди более 100 запросов, новые запросы блокируются.

  • maxRequestsPerConnection: 10 — ограничивает число запросов на одно соединение.

  • consecutiveErrors: 5 — если сервис отвечает с ошибкой 5 раз подряд, Istio исключает его из пула.

  • baseEjectionTime: 30s — сервис исключается на 30 секунд, прежде чем снова попробовать отправить запросы.

Эта механика предотвращает перегрузку сервиса и делает систему более отказоустойчивой.

Безопасность взаимодействия между сервисами — одна из ключевых проблем в микросервисной архитектуре. Без Service Mesh каждая команда реализует защиту по-своему, что приводит к хаосу и уязвимостям.

Service Mesh берёт на себя:  

  • Аутентификацию сервисов — каждый сервис получает сертификат, подтверждающий его подлинность.

  • Авторизацию — можно задавать политики, кто и к каким сервисам имеет доступ.

  • Шифрование трафика — все запросы могут быть автоматически зашифрованы по TLS без изменения кода самих сервисов.

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

Развёртывание в Kubernetes и интеграция с облаками

Один из главных плюсов Service Mesh — простота развёртывания. Большинство решений, таких как Istio, Linkerd, Consul, легко интегрируются в Kubernetes-кластеры. Достаточно выполнить несколько команд — и все сервисы автоматически получают расширенные функции сетевого взаимодействия.

Что касается облачных провайдеров:

  • Google предлагает Anthos Service Mesh — свою версию Istio с глубокой интеграцией в GCP.

  • AWS развивает App Mesh, основанный на Envoy.

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

Архитектура Service Mesh: как работает Istio и Envoy Proxy

Разобравшись с основными функциями Service Mesh, давайте разберем, как эта технология устроена под капотом. Здесь нам важно понимать два ключевых компонента: Control Plane и Data Plane.

В Service Mesh архитектуре есть разделение на Control Plane и Data Plane, и это не просто формальное разделение. Каждый из этих уровней выполняет свою критически важную роль:

Control Plane — управляет конфигурацией, отслеживает сервисы, определяет правила маршрутизации.
Data Plane — обрабатывает весь реальный сетевой трафик, применяя политики, заданные Control Plane.

Как работает Istiod

В случае Istio, основной компонент Control Plane — это Istiod. Он отвечает за:

  • Обнаружение сервисов — понимает, какие поды есть в кластере и как они связаны.

  • Генерацию конфигурации для прокси (Envoy Proxy).

  • Применение политик безопасности, маршрутизации, аутентификации.

Также в Control Plane входят два важных компонента:
Ingress Gateway — точка входа для внешнего трафика.
Egress Gateway — точка выхода, если необходимо контролировать исходящий трафик.

Sidecar-контейнеры и Envoy Proxy

Теперь о Data Plane. Здесь вся магия происходит за счет sidecar-контейнеров, которые автоматически встраиваются в поды и перехватывают трафик.

Это работает так:

  1. Istiod отслеживает namespace, помеченный лейблом injection=enabled

  2. При старте нового пода в этом namespace автоматически добавляется контейнер с Envoy Proxy.

  3. Сетевые настройки пода меняются так, чтобы весь трафик сначала проходил через Envoy.

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

Envoy Proxy: сердце Service Mesh

Если вы хотите глубже понять, как работает Istio, вам стоит изучить Envoy Proxy — мощный, высокопроизводительный прокси-сервер, поддерживающий:

  • Динамическую маршрутизацию — может менять поведение в реальном времени.

  • TLS-шифрование на любом уровне.

  • Продвинутую балансировку нагрузки.

  • Глубокую интеграцию с мониторингом (Prometheus, Grafana, Jaeger).

Настраивать его можно через YAML-конфигурации или REST API, что делает его гибким инструментом для управления трафиком в микросервисной архитектуре.

Как Istiod узнаёт, куда вставлять прокси?

Всё просто — нам нужно пометить namespace меткой:

kubectl label namespace my-namespace istio-injection=enabled

После этого Istiod начнёт автоматически добавлять sidecar-контейнеры во все новые поды в этом namespace.

Важно! При включении Istio-Injection на работающие поды ничего не изменится. Это одна из особенностей: уже существующие поды не затрагиваются. Чтобы изменения вступили в силу, поды нужно пересоздать.

kubectl delete pod --all -n my-namespace

Не делайте это на продакшне:)

После этого каждый новый под будет автоматически включен в Service Mesh.

«Невидимость» Istio: почему кажется, что ничего не изменилось?

Когда я только начинал разбираться с Istio, возникало ощущение, что ничего не происходит. Вы разворачиваете Service Mesh, запускаете сервисы — и всё продолжает работать, как будто изменений нет.

Но разница всё же есть:

  • Весь внутренний трафик теперь проходит через Envoy Proxy.

  • Можно включать шифрование, балансировку, мониторинг на уровне сети без изменения кода сервисов.

  • Гибкость в управлении трафиком: например, вы можете настроить канареечные деплои или аварийное переключение на другой сервис.

И самое крутое: всё это делается через конфигурацию Istio, без изменения бизнес-логики приложений.

Маршрутизация трафика в Service Mesh: Virtual Service, Destination Rule и балансировка нагрузки

После установки Service Mesh (например, Istio) весь внешний трафик проходит через Ingress Gateway. Но чтобы трафик действительно начал маршрутизироваться так, как нам нужно, необходимо настроить связь с этими шлюзами и задать корректные правила маршрутизации.

Настройка маршрутизации: Virtual Service

В Istio основным инструментом маршрутизации является Virtual Service. Когда мы устанавливаем Istio в Kubernetes-кластер, в системе появляются дополнительные кастомные ресурсы (CRD), и один из ключевых — это как раз Virtual Service.

Что он делает?

  • Определяет, как направлять входящий трафик внутри Service Mesh.

  • Задаёт правила маршрутизации на основе URL-путей, заголовков, веса трафика и других параметров.

  • Контролирует, как трафик распределяется между разными версиями сервисов.

Пример Virtual Service:

7c7e890a5dea8fd9da2907f809f6cb98.png

Разберём, что тут происходит:

  • Входящие запросы направляются на сервис my-service.

  • Если URL начинается с /api/v1/ → запрос уйдёт на версию v1.

  • Если URL начинается с /api/v2/ → запрос уйдёт на версию v2.

Если вы когда-либо настраивали Nginx, Traefik или HAProxy, вам эта логика должна быть знакома. Но в отличие от традиционных прокси-серверов, в Istio маршрутизация управляется через API, что делает её динамической и более гибкой.

Гибкость правил маршрутизации

Virtual Service позволяет мэтчить трафик не только по URL-префиксам, но и по:

  • HTTP-заголовкам (например, User-Agent, Authorization).

  • Методам (GET, POST, PUT, DELETE).

  • IP-адресам отправителя.

  • Cookie (можно, например, направлять трафик пользователей с определённым cookie на новую версию сервиса).

Пример маршрутизации по заголовку:

cf3e80f95e7275e7b555910cadad224a.png

Если запрос пришёл от браузера Mozilla — он попадёт в v1. Все остальные пользователи — в v2.

Это позволяет гибко тестировать новые версии API или направлять разные типы клиентов (мобильные, десктопные) на разные бекенды.

Канареечные деплои и A/B-тесты

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

Это делается через балансировку трафика между версиями. Для этого создаём Destination Rule, в котором указываем разные subset’ы (версии сервиса).

Пример Destination Rule:

c8c58ae9f55ae1a1a95ec5cd82150d82.png

Теперь мы можем в Virtual Service направлять часть трафика на новую версию:

09d5f68354dab492314b02ef0a65de45.png

75% запросов остаются на старой версии. 25% запросов направляются на новую.

Если в логах и метриках всё хорошо, можно постепенно увеличивать процент трафика на новую версию и плавно раскатывать её на продакшен.

Балансировка нагрузки в Istio

По умолчанию Istio использует Round Robin, но у нас есть и другие возможности:

ROUND_ROBIN — запросы равномерно распределяются между всеми подами.

LEAST_CONN — запрос отправляется на под с наименьшей нагрузкой.

RANDOM — запрос направляется случайному поду.

PASSTHROUGH — запрос идёт напрямую в сервис без балансировки.

CONSISTENT_HASH — запросы одного клиента направляются на один и тот же под (полезно для кэширования).

Пример конфигурации балансировки по наименьшему количеству соединений:

a94a894965bde61f41da2383e304329d.png

Если у вас неравномерная нагрузка на сервисы, LEAST_CONN поможет равномерно распределять запросы.

Когда применять Service Mesh маршрутизацию

Использование Virtual Service + Destination Rule особенно полезно в таких случаях:

  • Канареечные деплои — раскатываем новую версию плавно.

  • A/B-тестирование — направляем трафик на разные версии сервиса.

  • Фолловеры / резервные инстансы — если один сервис падает, можно отправлять трафик на альтернативный.

  • Роутинг по географии / клиентам — например, мобильные запросы направлять в один кластер, десктопные — в другой.

Шифрование трафика, управление шлюзами и документация по Istio

Теперь давайте поговорим про безопасность трафика, шифрование, настройку gateway и документацию.

Шифрование трафика между сервисами

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

  • Запросы содержат чувствительную информацию (например, персональные данные, платежную информацию).

  • Кластер разделяет разные команды или даже клиентов (multi-tenant).

  • Мы работаем в облаке или на хостинге, где потенциально возможен MITM-атакующий.

Здесь нам на помощь приходит Istio, который умеет автоматически шифровать весь межсервисный трафик без необходимости настраивать HTTPS на каждом отдельном сервисе.

Как включить автоматическое шифрование трафика

В Istio это включается всего одной настройкой. Мы просто указываем в Destination Rule, что внутри определённого namespace весь трафик должен быть зашифрован. Учтите, что это делается ценой роста CPU на 5%.

Пример:

c01e0297433b08975689ca0b77d04c51.png

Разберём, что здесь происходит:

  • mode: ISTIO_MUTUAL — включает mTLS (mutual TLS) между сервисами внутри Service Mesh.

  • Все сервисы, работающие внутри этого namespace, автоматически начинают шифровать трафик.

  • Сами сервисы не знают, что их трафик теперь шифруется — им не нужно настраивать HTTPS или управлять сертификатами.

Ротация сертификатов — всё автоматизировано

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

  • Он автоматически генерирует и обновляет сертификаты.

  • Контрольный сервис Citadel управляет сертификатами.

  • При любом изменении он перекатывает ключи и перезапускает соединения.

Никаких проблем с истекающими сертификатами или самоподписанными сертификатами, которые сложно обновлять.

Ingress и Egress Gateway — управление внешним трафиком

В Service Mesh весь внешний трафик проходит через Ingress Gateway, а исходящий — через Egress Gateway.

  • Ingress Gateway — это точка входа, через которую внешний трафик попадает в сервисы внутри кластера.

  • Egress Gateway — точка выхода, через которую сервисы внутри кластера ходят во внешний мир (например, в сторонние API).

Для работы с этими шлюзами в Istio есть специальный ресурс Gateway.

Пример Ingress Gateway:

bdb915970c1402f275b50e4f51800911.png

Разберём, что здесь важно:

  • Входящие запросы идут через Ingress Gateway.

  • Шлюз слушает 443-й порт (HTTPS).

  • Подключен TLS-сертификат (my-tls-secret).

  • Принимает трафик с доменного имени myapp.example.com.

Таким же образом можно настроить Egress Gateway, если мы хотим контролировать исходящий трафик. Например, разрешать запросы только к определённым API или мониторить исходящий трафик.

Что такое Gateway API?

Для управления трафика в Kubernetes обычно используют Ingress rules, но Istio поддерживает Gateway API — более мощная и гибкая альтернатива, продвинутая версия маршрутизации, разработанная Google.

  • Gateway API — это не Istio, а общий стандарт для работы с Ingress Gateway.

  • Istio — одна из его реализаций.

  • Gateway API заменяет стандартный Kubernetes Ingress, но с расширенной функциональностью.

Пример Gateway API:

2b6a40c502f222c693a332190ba6cf85.png

Это новый рекомендуемый стандарт, если вы планируете разворачивать Ingress в современных кластерах.

Документация по Istio — нужна ли она?

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

  • Проблема документации Istio — слишком сухой язык и сложная терминология.

  • Если вы новичок, то понять, что происходит, будет тяжело.

  • Лучший способ разобраться — начать с книги «Istio in Action». Эта книга лучше документации, потому что объясняет, как работает Service Mesh с нуля, почему Istio устроен именно так, как развернуть его правильно и избежать проблем, как оптимизировать производительность и не перегружать сервисы.

Если вам нужно не просто «поставить и забыть» Istio, а глубоко разобраться, эта книга — must-read.

Вывод

Многие компании пытались решать проблемы маршрутизации, балансировки и отказоустойчивости по-разному:

  • Писали собственные библиотеки для ретраев, балансировки и шифрования.

  • Использовали сторонние инструменты (например, Netflix Hystrix).

  • Добавляли костыли в код приложений, что делало их сложными и запутанными.

Istio предлагает единое решение:

  • Не нужно встраивать инфраструктурную логику в код.

  • Можно гибко управлять политиками без изменений в приложениях.

  • Работает в любой среде Kubernetes и совместим с облачными провайдерами.

Поэтому Service Mesh — это не просто «ещё один инструмент», а критически важная технология для управления микросервисами. Она:  

  • Упрощает балансировку трафика.

  • Повышает безопасность без изменения кода.

  • Даёт мощные инструменты мониторинга.

  • Помогает сделать систему более отказоустойчивой.

  • Шифрование трафика между сервисами (mTLS) включается одной настройкой — никакого дополнительного кода в сервисах.

  • Сертификаты ротации управляются автоматически, вам не нужно вручную обновлять их.

  • Ingress и Egress Gateway позволяют контролировать внешний трафик, работать с HTTPS и балансировать нагрузку.

  • Gateway API — новая альтернатива Kubernetes Ingress, рекомендуется для новых проектов.

Если вы уже работаете с Kubernetes и микросервисной архитектурой, использование Service Mesh — это логичный следующий шаг.

Хотите узнать больше про современные DevOps технологии? Приходите на Профессиональную конференцию по интеграции процессов разработки, тестирования и эксплуатации DevOpsConf в апреле в Москве!

Habrahabr.ru прочитано 5041 раз