Веб-интерфейсы, связанные с модулем: istio
На данный момент поддерживаются следующие версии istio:
- 1.12 (устарела, скоро будет снята с поддержки)
- 1.13 (устарела, скоро будет снята с поддержки)
- 1.16
Задачи, которые решает Istio
Istio — фреймворк централизованного управления сетевым трафиком, реализующий подход Service Mesh.
В частности, Istio прозрачно решает для приложений следующие задачи:
- Использование Mutual TLS:
- Взаимная достоверная аутентификация сервисов.
- Шифрование трафика.
- Авторизация доступа между сервисами.
- Маршрутизация запросов:
- Canary-deployment и A/B тестирование — позволяет отправлять часть запросов на новую версию приложения.
- Управление балансировкой запросов между Endpoint’ами сервиса:
- Circuit Breaker:
- Временное исключение endpoint’а из балансировки если превышен лимит ошибок.
- Настройка лимитов на количество TCP-соединений и количество запросов в сторону одного endpoint’а.
- Выявление зависших запросов и обрывание их с кодом ошибки (HTTP request timeout).
- Sticky Sessions:
- Привязка запросов от конечных пользователей к endpoint’у сервиса.
- Locality Failover — позволяет отдавать предпочтение endpoint’ам в локальной зоне доступности.
- Балансировка gRPC-сервисов.
- Circuit Breaker:
- Повышение Observability:
- Сбор и визуализация данных для трассировки прикладных запросов с помощью Jaeger.
- Сбор метрик о трафике между сервисами в Prometheus и визуализация их в Grafana.
- Визуализация состояния связей между сервисами и состояния служебных компонентов Istio с помощью Kiali.
- Организация мульти-ЦОД кластера за счёт объединения кластеров в единый Service Mesh (мультикластер).
- Объединение разрозненных кластеров в федерацию с возможностью предоставлять стандартный (в понимании Service Mesh) доступ к избранным сервисам.
Рекомендуем ознакомиться с видео, где мы обсуждаем архитектуру Istio и оцениваем накладные расходы.
Mutual TLS
Данный механизм — это главный метод взаимной аутентификации сервисов. Принцип основывается на том, что при всех исходящих запросах проверяется серверный сертификат, а при входящих — клиентский. После проверок, sidecar-proxy получает возможность идентифицировать удалённый узел и использовать эти данные для авторизации, либо в прикладных целях.
Каждый сервис получает собственный идентификатор в формате <TrustDomain>/ns/<Namespace>/sa/<ServiceAccount>
, где TrustDomain
в нашем случае — это домен кластера. Каждому сервису можно выделять собственный ServiceAccount или использовать стандартный “default”. Полученный идентификатор сервиса можно использовать как в правилах авторизации, так и в прикладных целях. Именно этот идентификатор используется в качестве удостоверяемого имени в TLS-сертификатах.
Данные настройки можно переопределить на уровне Namespace.
Авторизация
Управление авторизацией осуществляется с помощью ресурса AuthorizationPolicy. В момент, когда для сервиса создаётся этот ресурс, начинает работать следующий алгоритм принятия решения о судьбе запроса:
- Если запрос попадает под политику DENY — запретить запрос.
- Если для данного сервиса нет политик ALLOW — разрешить запрос.
- Если запрос попадает под политику ALLOW — разрешить запрос.
- Все остальные запросы — запретить.
Иными словами, если явно что-то запретить, то работает только запрет. Если же что-то явно разрешить, то будут разрешены только явно одобренные запросы (запреты, при этом, имеют приоритет).
Для написания правил авторизации можно использовать аргументы:
- идентификаторы сервисов и wildcard на их основе (
mycluster.local/ns/myns/sa/myapp
илиmycluster.local/*
), - namespace,
- диапазоны IP,
- HTTP-заголовки,
- JWT-токены из прикладных запросов.
Маршрутизация запросов
Основной ресурс для управления маршрутизацией — VirtualService, он позволяет переопределять судьбу HTTP или TCP-запроса. Доступные аргументы для принятия решения о маршрутизации:
- Host и любые другие заголовки,
- URI,
- метод (GET, POST и пр.),
- лейблы Pod’а или namespace источника запросов,
- dst-IP или dst-порт для не-HTTP запросов.
Управление балансировкой запросов между Endpoint-ами сервиса
Основной ресурс для управления балансировкой запросов — DestinationRule, он позволяет настроить нюансы исходящих из Pod’ов запросов:
- лимиты/таймауты для TCP,
- алгоритмы балансировки между Endpoint-ами,
- правила определения проблем на стороне Endpoint-а для выведения его из балансировки,
- нюансы шифрования.
Важно! Все настраиваемые лимиты работают для каждого Pod’а клиента по отдельности! Если настроить для сервиса ограничение на одно TCP-соединение, а клиентских Pod’а три, то сервис получит три входящих соединения.
Observability
Трассировка
Istio позволяет осуществлять сбор трейсов с приложений и инъекцию трассировочных заголовков если таковых нет. При этом важно понимать:
- Если запрос инициирует на сервисе вторичные запросы, то для них необходимо наследовать трассировочные заголовки средствами приложения.
- Jaeger для сбора и отображения трейсов потребуется устанавливать самостоятельно.
Grafana
В стандартной комплектации с модулем предоставлены дополнительные доски:
- Доска для оценки производительности и успешности запросов/ответов между приложениями.
- Доска для оценки работоспособности и нагрузки на control plane.
Kiali
Инструмент для визуализации дерева сервисов вашего приложения. Позволяет быстро оценить обстановку в сетевой связности благодаря визуализации запросов и их количественных характеристик непосредственно на схеме.
Архитектура кластера с включенным Istio
Компоненты кластера делятся на две категории:
- control plane — управляющие и обслуживающие сервисы. Под control plane обычно подразумевают Pod’ы istiod.
- data plane — прикладная часть Istio. Представляет собой контейнеры sidecar-proxy.
Все сервисы из data plane группируются в mesh. Его характеристики:
- Общее пространство имён для генерации идентификатора сервиса в формате
<TrustDomain>/ns/<Namespace>/sa/<ServiceAccount>
. Каждый mesh имеет идентификатор TrustDomain, который в нашем случае совпадает с доменом кластера. Например:mycluster.local/ns/myns/sa/myapp
. - Сервисы в рамках одного mesh имеют возможность аутентифицировать друг друга с помощью доверенных корневых сертификатов.
Элементы control plane:
istiod
— ключевой сервис, обеспечивающий решение следующих задач:- Непрерывная связь с API Kubernetes и сбор информации о прикладных сервисах.
- Обработка и валидация с помощью механизма Kubernetes Validating Webhook всех Custom Resources, которые связаны с Istio.
- Компоновка конфигурации для каждого sidecar-proxy индивидуально:
- Генерация правил авторизации, маршрутизации, балансировки и пр.
- Распространение информации о других прикладных сервисах в кластере.
- Выпуск индивидуальных клиентских сертификатов для организации схемы Mutual TLS. Эти сертификаты не связаны с сертификатами, которые использует и контролирует сам Kubernetes для своих служебных нужд.
- Автоматическая подстройка манифестов, определяющих прикладные Pod’ы через механизм Kubernetes Mutating Webhook:
- внедрение дополнительного служебного контейнера sidecar-proxy.
- внедрение дополнительного init-контейнера для адаптации сетевой подсистемы (настройка DNAT для перехвата прикладного трафика).
- перенаправление readiness и liveness-проб через sidecar-proxy.
operator
— компонент, отвечающий за установку всех ресурсов, необходимых для работы control plane определённой версии.kiali
— панель управления и наблюдения за ресурсами Istio и пользовательскими сервисами под управлением Istio. Позволяет:- Визуализировать связи между сервисами.
- Диагностировать проблемные связи между сервисами.
- Диагностировать состояние control plane.
Для приёма пользовательского трафика требуется доработка Ingress-контроллера:
- К Pod’ам контроллера добавляется sidecar-proxy, который обслуживает только трафик от контроллера в сторону прикладных сервисов (параметр IngressNginxController
enableIstioSidecar
у ресурса IngressNginxController). - Сервисы не под управлением Istio продолжают работать как раньше, запросы в их сторону не перехватываются сайдкаром контроллера.
- Запросы в сторону сервисов под управлением Istio перехватываются сайдкаром и обрабатываются в соответствии с правилами Istio (подробнее о том, как активировать Istio для приложения).
Контроллер istiod и каждый контейнер sidecar-proxy экспортируют собственные метрики, которые собирает кластерный Prometheus.
Архитектура прикладного сервиса с включенным Istio
Особенности
- Каждый Pod сервиса получает дополнительный контейнер — sidecar-proxy. Технически этот контейнер содержит два приложения:
- Envoy — проксирует прикладной трафик и реализует весь функционал, который предоставляет Istio, включая маршрутизацию, аутентификацию, авторизацию и пр.
- pilot-agent — часть Istio, отвечает за поддержание конфигурации Envoy в актуальном состоянии, а также содержит в себе кеширующий DNS-сервер.
- В каждом Pod’е настраивается DNAT входящих и исходящих прикладных запросов в sidecar-proxy. Делается это с помощью дополнительного init-контейнера. Таким образом, трафик будет перехватываться прозрачно для приложений.
- Так как входящий прикладной трафик перенаправляется в sidecar-proxy, то readiness/liveness-трафика это тоже касается. Подсистема Kubernetes, которая за это отвечает, не рассчитана на формирование проб в формате Mutual TLS. Для адаптации, все существующие пробы автоматически перенастраиваются на специальный порт в sidecar-proxy, который перенаправляет трафик на приложение в неизменном виде.
- Для приёма запросов извне кластера, необходимо использовать подготовленный Ingress-контроллер:
- Pod’ы контроллера аналогично имеют дополнительный контейнер sidecar-proxy.
- В отличие от Pod’ов приложения, sidecar-proxy Ingress-контроллера перехватывает только трафик от контроллера к сервисам. Входящий трафик от пользователей обрабатывает непосредственно сам контроллер.
- Ресурсы типа Ingress требуют минимальной доработки в виде добавления аннотаций:
nginx.ingress.kubernetes.io/service-upstream: "true"
— Ingress-контроллер в качестве upstream будет использовать ClusterIP сервиса вместо адресов Pod’ов. Балансировкой трафика между Pod’ами теперь занимается sidecar-proxy. Используйте эту опцию только если у вашего сервиса есть ClusterIP.nginx.ingress.kubernetes.io/upstream-vhost: "myservice.myns.svc"
— sidecar-proxy Ingress-контроллера принимает решения о маршрутизации на основе заголовка Host. Без данной аннотации, контроллер оставит заголовок с адресом сайта, напримерHost: example.com
.
- Ресурсы типа Service не требуют адаптации и продолжают выполнять свою функцию. Приложениям всё так же доступны адреса сервисов вида servicename, servicename.myns.svc и пр.
- DNS-запросы изнутри Pod’ов прозрачно перенаправляются на обработку в sidecar-proxy:
- Требуется для разыменования DNS-имён сервисов из соседних кластеров.
Жизненный цикл пользовательского запроса
Приложение с выключенным Istio
Приложение с включенным Istio
Как активировать Istio для приложения
Основная цель активации — добавить sidecar-контейнер к Pod’ам приложения, после чего Istio сможет управлять трафиком.
Рекомендованный способ добавления sidecar-ов — использовать sidecar-injector. Istio умеет “подселять” к вашим Pod’ам sidecar-контейнер с помощью механизма Admission Webhook. Настраивается с помощью лейблов и аннотаций:
- Лейбл к namespace — обращает внимание sidecar-injector-а на ваш namespace, после установки лейбла, к новым Pod’ам будут подселяться sidecar-ы:
istio-injection=enabled
— использовать самую свежую установленную версию Istio.istio.io/rev=v1x13
— использовать конкретную версию Istio для данного namespace.
- Аннотация к Pod’у —
sidecar.istio.io/inject
("true"
или"false"
), позволяет локально переопределить политикуsidecarInjectorPolicy
. Эти аннотации работают только в namespace, обозначенных лейблами из списка выше.
Также существует возможность добавить sidecar к индивидуальному Pod’у в namespace без установленных лейблов istio-injection=enabled
или istio.io/rev=vXxYZ
путём установки лейбла sidecar.istio.io/inject=true
.
Важно! Istio-proxy, который работает в качестве sidecar-контейнера тоже потребляет ресурсы и добавляет накладные расходы:
- Каждый запрос DNAT-ится в envoy, который обрабатывает это запрос и создаёт ещё один. На принимающей стороне — аналогично.
- Каждый envoy хранит информацию обо всех сервисах в кластере, что требует памяти. Больше кластер — больше памяти потребляет envoy. Решение — CustomResource Sidecar.
Также важно подготовить Ingress-контроллер и Ingress-ресурсы приложения:
- включить
enableIstioSidecar
у ресурса IngressNginxController, - добавить аннотации на Ingress-ресурсы приложения:
nginx.ingress.kubernetes.io/service-upstream: "true"
— Ingress-контроллер в качестве upstream будет использовать ClusterIP сервиса вместо адресов Pod’ов. Балансировкой трафика между Pod’ами теперь занимается sidecar-proxy. Используйте эту опцию только если у вашего сервиса есть ClusterIP.nginx.ingress.kubernetes.io/upstream-vhost: "myservice.myns.svc"
— sidecar-proxy Ingress-контроллера принимает решения о маршрутизации на основе заголовка Host. Без данной аннотации, контроллер оставит заголовок с адресом сайта, напримерHost: example.com
.
Федерация и мультикластер
Доступно только в редакции Enterprise Edition.
Поддерживается две схемы межкластерного взаимодействия:
Принципиальные отличия:
- Федерация объединяет суверенные кластеры:
- у каждого кластера собственное пространство имён (для Namespace, Service и пр.),
- доступ к отдельным сервисам между кластерами явно обозначен.
- Мультикластер объединяет созависимые кластеры:
- пространство имён у кластеров общее — каждый сервис доступен для соседних кластеров так, словно он работает на локальном кластере (если это не запрещают правила авторизации).
Федерация
Общие принципы федерации
- Федерация требует установления взаимного доверия между кластерами. Соответственно, для установления федерации, нужно в кластере A сделать кластер Б доверенным, и аналогично в кластере Б сделать кластер А доверенным. Технически это достигается взаимным обменом корневыми сертификатами.
- Для прикладной эксплуатации федерации необходимо также обменяться информацией о публичных сервисах. Чтобы опубликовать сервис bar из кластера Б в кластере А, необходимо в кластере А создать ресурс ServiceEntry, который описывает публичный адрес ingress-gateway кластера Б.
Включение федерации
При включении федерации (параметр модуля istio.federation.enabled = true
) происходит следующее:
- В кластер добавляется сервис
ingressgateway
, чья задача проксировать mTLS-трафик извне кластера на прикладные сервисы. - В кластер добавляется сервис, который экспортит метаданные кластера наружу:
- корневой сертификат Istio (доступен без аутентификации),
- список публичных сервисов в кластере (доступен только для аутентифицированных запросов из соседних кластеров),
- список публичных адресов сервиса
ingressgateway
(доступен только для аутентифицированных запросов из соседних кластеров).
Управление федерацией
Для построения федерации необходимо:
- В каждом кластере создать набор ресурсов
IstioFederation
, которые описывают все остальные кластеры. - Каждый ресурс, который считается публичным в рамках федерации, необходимо пометить лейблом
federation.istio.deckhouse.io/public-service=
.
Мультикластер
Общие принципы
- Мультикластер требует установления взаимного доверия между кластерами. Соответственно, для построения мультикластера, нужно в кластере A сделать кластер Б доверенным, и в кластере Б сделать кластер А доверенным. Технически это достигается взаимным обменом корневыми сертификатами.
- Для сбора информации о соседних сервисах, Istio подключается напрямую к API-серверу соседнего кластера. Данный модуль Deckhouse берёт на себя организацию соответствующего канала связи.
Включение мультикластера
При включении мультикластера (параметр модуля istio.multicluster.enabled = true
) происходит следующее:
- В кластер добавляется прокси для публикации доступа к API-серверу посредством стандартного Ingress-ресурса:
- Доступ через данный публичный адрес ограничен авторизацией на основе Bearer-токенов, подписанных доверенными ключами. Обмен доверенными публичными ключами происходит автоматически средствами Deckhouse при взаимной настройке мультикластера.
- Непосредственно прокси имеет read-only доступ к ограниченному набору ресурсов.
- В кластер добавляется сервис, который экспортит метаданные кластера наружу:
- Корневой сертификат Istio (доступен без аутентификации).
- Публичный адрес, через который доступен API-сервер (доступен только для аутентифицированных запросов из соседних кластеров).
- Список публичных адресов сервиса
ingressgateway
(доступен только для аутентифицированных запросов из соседних кластеров). - Публичные ключи сервера для аутентификации запросов к API-серверу и к закрытым метаданным данным (выше).
Управление мультикластером
Для сборки мультикластера необходимо в каждом кластере создать набор ресурсов IstioMulticluster
, которые описывают все остальные кластеры.
Накладные расходы
Примерная оценка накладных расходов при использовании Istio. Для ограничения потребления ресурсов путём ограничения поля видимости sidecar, возможно использование ресурса Sidecar.