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 это решается декларативно:

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

Если сервис 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 мы можем задать ограничения:

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

  • 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:

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

  • Входящие запросы направляются на сервис 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 на новую версию сервиса).

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

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

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

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

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

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

Пример Destination Rule:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Пример:

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

  • 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:

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

  • Входящие запросы идут через 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:

Это новый рекомендуемый стандарт, если вы планируете разворачивать 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 в апреле в Москве!

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


  1. Evgenym
    14.02.2025 13:11

    Не совсем понял, что будет с уже текущими сервисами внутри кластера?

    У меня есть кластер, там взаимодействие подов идет через обычные сервисы. Если я ставлю Истио, то что будет? Коммуникация через обычные сервисы продолжит работать? Можно будет гнать траффик как через виртуальные сервисы Истио, так и через обычные? Или нужно будет перенастроить все на Истио?

    Если у меня есть network policy, как с ними будет работать Истио?


    1. usharik
      14.02.2025 13:11

      1. Istio не внедряет sidecar контейнеры в поды, которые были в созданы до установки и настройки Istio

      2. После установки Istio во все новые поды sidecar контейнер будет внедряться, т.е. их трафиком уже будет управлять Istio

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

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

      В целом Istio хорошо приспособлен к постепенному развертыванию в кластере где его раньше не использовали.


      1. Nicknnn
        14.02.2025 13:11

        Вообще в дефолтной инсталяции istio добавляет sidecar только в неймспейсы и lebel istio-injection (или както так)


    1. frkntony
      14.02.2025 13:11

      Если в namespace или project включен флаг ниже, то все новые поды получат сайдкар, а значит при установке будет помещены в Serivce Mesh.

      istio-injection=enabled

      Чтобы старые сервисы не попадали в Service Mesh, нужно добавить аннотацию в deployment

      sidecar.istio.io/inject: "false"

      Можно плавно вводить микросервисы в Istio. Например, если добавишь аннотацию

      traffic.sidecar.istio.io/excludeOutboundPorts: "9092"
      // при 
      sidecar.istio.io/inject: "true"

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

      У меня на работе Service Mesh юзают только для двух вещей
      1) Он обрубает все коннекты по дефолту и в архитектурном чеклисте это помечено как секьюрно
      2) Работа с внешними сервисами через mTLS
      3) Раньше еще фишки Observability использовали, но потом пришлось от них отказаться из-за внутренних бизнес-требований.