Веб-интерфейсы, связанные с модулем: istio

Таблица совместимости поддерживаемых версий

Версия Istio Версии K8S, поддерживаемые Istio Статус в текущем релизе D8
1.16 1.22*, 1.23*, 1.24*, 1.25* Устарела и будет удалена
1.19 1.25*, 1.26, 1.27, 1.28, 1.29, 1.30 Поддерживается

* — версия Kubernetes НЕ поддерживается в текущем релизе Deckhouse Kubernetes Platform.

Задачи, которые решает Istio

Istio — фреймворк централизованного управления сетевым трафиком, реализующий подход Service Mesh.

В частности, Istio прозрачно решает для приложений следующие задачи:

Рекомендуем ознакомиться с видео, где мы обсуждаем архитектуру 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 и пр.);
  • лейблы пода или namespace источника запросов;
  • dst-IP или dst-порт для не-HTTP-запросов.

Управление балансировкой запросов между endpoint’ами сервиса

Основной ресурс для управления балансировкой запросов — DestinationRule, он позволяет настроить нюансы исходящих из подов запросов:

  • лимиты/таймауты для TCP;
  • алгоритмы балансировки между endpoint’ами;
  • правила определения проблем на стороне endpoint’а для выведения его из балансировки;
  • нюансы шифрования.

Важно! Все настраиваемые лимиты работают для каждого пода клиента по отдельности! Если настроить для сервиса ограничение на одно TCP-соединение, а клиентских подов — три, то сервис получит три входящих соединения.

Observability

Трассировка

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

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

Grafana

В стандартной комплектации с модулем предоставлены дополнительные доски:

  • доска для оценки производительности и успешности запросов/ответов между приложениями;
  • доска для оценки работоспособности и нагрузки на control plane.

Kiali

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

Архитектура кластера с включенным Istio

Компоненты кластера делятся на две категории:

  • control plane — управляющие и обслуживающие сервисы. Под control plane обычно подразумевают поды istiod.
  • data plane — прикладная часть Istio. Представляет собой контейнеры sidecar-proxy.

Архитектура кластера с включенным Istio

Все сервисы из 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 для своих служебных нужд.
    • Автоматическая подстройка манифестов, определяющих прикладные поды через механизм Kubernetes Mutating Webhook:
      • внедрение дополнительного служебного контейнера sidecar-proxy;
      • внедрение дополнительного init-контейнера для адаптации сетевой подсистемы (настройка DNAT для перехвата прикладного трафика);
      • перенаправление readiness- и liveness-проб через sidecar-proxy.
  • operator — компонент, отвечающий за установку всех ресурсов, необходимых для работы control plane определенной версии.
  • kiali — панель управления и наблюдения за ресурсами Istio и пользовательскими сервисами под управлением Istio, позволяющая следующее:
    • Визуализировать связи между сервисами.
    • Диагностировать проблемные связи между сервисами.
    • Диагностировать состояние control plane.

Для приема пользовательского трафика требуется доработка Ingress-контроллера:

  • К подам контроллера добавляется sidecar-proxy, который обслуживает только трафик от контроллера в сторону прикладных сервисов (параметр IngressNginxController enableIstioSidecar у ресурса IngressNginxController).
  • Сервисы не под управлением Istio продолжают работать как раньше, запросы в их сторону не перехватываются сайдкаром контроллера.
  • Запросы в сторону сервисов под управлением Istio перехватываются сайдкаром и обрабатываются в соответствии с правилами Istio (подробнее о том, как активировать Istio для приложения).

Контроллер istiod и каждый контейнер sidecar-proxy экспортируют собственные метрики, которые собирает кластерный Prometheus.

Архитектура прикладного сервиса с включенным Istio

Особенности

  • Каждый под сервиса получает дополнительный контейнер — sidecar-proxy. Технически этот контейнер содержит два приложения:
    • Envoy — проксирует прикладной трафик и реализует весь функционал, который предоставляет Istio, включая маршрутизацию, аутентификацию, авторизацию и пр.
    • pilot-agent — часть Istio, отвечает за поддержание конфигурации Envoy в актуальном состоянии, а также содержит в себе кэширующий DNS-сервер.
  • В каждом поде настраивается DNAT входящих и исходящих прикладных запросов в sidecar-proxy. Делается это с помощью дополнительного init-контейнера. Таким образом, трафик будет перехватываться прозрачно для приложений.
  • Так как входящий прикладной трафик перенаправляется в sidecar-proxy, readiness/liveness-трафика это тоже касается. Подсистема Kubernetes, которая за это отвечает, не рассчитана на формирование проб в формате Mutual TLS. Для адаптации все существующие пробы автоматически перенастраиваются на специальный порт в sidecar-proxy, который перенаправляет трафик на приложение в неизменном виде.
  • Для приема запросов извне кластера необходимо использовать подготовленный Ingress-контроллер:
    • Поды контроллера аналогично имеют дополнительный контейнер sidecar-proxy.
    • В отличие от подов приложения, sidecar-proxy Ingress-контроллера перехватывает только трафик от контроллера к сервисам. Входящий трафик от пользователей обрабатывает непосредственно сам контроллер.
  • Ресурсы типа Ingress требуют минимальной доработки в виде добавления аннотаций:
    • nginx.ingress.kubernetes.io/service-upstream: "true" — Ingress-контроллер в качестве upstream будет использовать ClusterIP сервиса вместо адресов подов. Балансировкой трафика между подами теперь занимается 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-запросы изнутри подов прозрачно перенаправляются на обработку в sidecar-proxy:
    • Требуется для разыменования DNS-имен сервисов из соседних кластеров.

Жизненный цикл пользовательского запроса

Приложение с выключенным Istio

Приложение с включенным Istio

Как активировать Istio для приложения

Основная цель активации — добавить sidecar-контейнер к подам приложения, после чего Istio сможет управлять трафиком.

Рекомендованный способ добавления sidecar-ов — использовать sidecar-injector. Istio умеет «подселять» к вашим подам sidecar-контейнер с помощью механизма Admission Webhook. Настраивается с помощью лейблов и аннотаций:

  • Лейбл к namespace — обращает внимание компонента sidecar-injector на ваш namespace. После применения лейбла к новым подам будут добавлены sidecar-контейнеры:
    • istio-injection=enabled — использует глобальную версию Istio (spec.settings.globalVersion в ModuleConfig);
    • istio.io/rev=v1x16 — использует конкретную версию Istio для этого namespace.
  • Аннотация к поду sidecar.istio.io/inject ("true" или "false") позволяет локально переопределить политику sidecarInjectorPolicy. Эти аннотации работают только в namespace, обозначенных лейблами из списка выше.

Также существует возможность добавить sidecar к индивидуальному поду в 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 сервиса вместо адресов подов. Балансировкой трафика между подами теперь занимается sidecar-proxy. Используйте эту опцию, только если у вашего сервиса есть ClusterIP;
    • nginx.ingress.kubernetes.io/upstream-vhost: "myservice.myns.svc" — sidecar-proxy Ingress-контроллера принимает решения о маршрутизации на основе заголовка Host. Без данной аннотации контроллер оставит заголовок с адресом сайта, например Host: example.com.

Федерация и мультикластер

Доступно только в редакции Enterprise Edition.

Поддерживаются две схемы межкластерного взаимодействия:

Принципиальные отличия:

  • Федерация объединяет суверенные кластеры:
    • у каждого кластера собственное пространство имен (для namespace, Service и пр.);
    • доступ к отдельным сервисам между кластерами явно обозначен.
  • Мультикластер объединяет созависимые кластеры:
    • пространство имен у кластеров общее — каждый сервис доступен для соседних кластеров так, словно он работает на локальном кластере (если это не запрещают правила авторизации).

Федерация

Требования к кластерам

  • У каждого кластера должен быть уникальный домен в параметре clusterDomain ресурса ClusterConfiguration. По умолчанию значение параметра — cluster.local.
  • Подсети подов и сервисов в параметрах podSubnetCIDR и serviceSubnetCIDR ресурса ClusterConfiguration не должны быть уникальными.

Общие принципы федерации

  • Федерация требует установления взаимного доверия между кластерами. Соответственно, для установления федерации нужно в кластере A сделать кластер Б доверенным и аналогично в кластере Б сделать кластер А доверенным. Технически это достигается взаимным обменом корневыми сертификатами.
  • Для прикладной эксплуатации федерации необходимо также обменяться информацией о публичных сервисах. Чтобы опубликовать сервис bar из кластера Б в кластере А, необходимо в кластере А создать ресурс ServiceEntry, который описывает публичный адрес ingress-gateway кластера Б.

Включение федерации

При включении федерации (параметр модуля istio.federation.enabled = true) происходит следующее:

  • В кластер добавляется сервис ingressgateway, чья задача — проксировать mTLS-трафик извне кластера на прикладные сервисы.
  • В кластер добавляется сервис, который экспортит метаданные кластера наружу:
    • корневой сертификат Istio (доступен без аутентификации);
    • список публичных сервисов в кластере (доступен только для аутентифицированных запросов из соседних кластеров);
    • список публичных адресов сервиса ingressgateway (доступен только для аутентифицированных запросов из соседних кластеров).

Управление федерацией

Для построения федерации необходимо сделать следующее:

  • В каждом кластере создать набор ресурсов IstioFederation, которые описывают все остальные кластеры.
    • После успешного автосогласования между кластерами, в ресурсе IstioFederation заполнятся разделы status.metadataCache.public и status.metadataCache.private служебными данными, необходимыми для работы федерации.
  • Каждый ресурс(service), который считается публичным в рамках федерации, пометить лейблом federation.istio.deckhouse.io/public-service=.
    • В кластерах из состава федерации, для каждого service создадутся соответствующие ServiceEntry, ведущие на ingressgateway оригинального кластера.

Важно чтобы в этих service, в разделе .spec.ports у каждого порта обязательно было заполнено поле name.

Мультикластер

Требования к кластерам

  • Домены кластеров в параметре clusterDomain ресурса ClusterConfiguration должны быть одинаковыми для всех членов мультикластера. По умолчанию значение параметра — cluster.local.
  • Подсети подов и сервисов в параметрах podSubnetCIDR и serviceSubnetCIDR ресурса ClusterConfiguration должны быть уникальными для каждого члена мультикластера.

Общие принципы

  • Мультикластер требует установления взаимного доверия между кластерами. Соответственно, для построения мультикластера нужно в кластере A сделать кластер Б доверенным и в кластере Б сделать кластер А доверенным. Технически это достигается взаимным обменом корневыми сертификатами.
  • Для сбора информации о соседних сервисах Istio подключается напрямую к API-серверу соседнего кластера. Данный модуль Deckhouse берет на себя организацию соответствующего канала связи.

Включение мультикластера

При включении мультикластера (параметр модуля istio.multicluster.enabled = true) происходит следующее:

  • В кластер добавляется прокси для публикации доступа к API-серверу посредством стандартного Ingress-ресурса:
    • Доступ через данный публичный адрес ограничен авторизацией на основе Bearer-токенов, подписанных доверенными ключами. Обмен доверенными публичными ключами происходит автоматически средствами Deckhouse при взаимной настройке мультикластера.
    • Непосредственно прокси имеет read-only-доступ к ограниченному набору ресурсов.
  • В кластер добавляется сервис, который экспортит метаданные кластера наружу:
    • Корневой сертификат Istio (доступен без аутентификации).
    • Публичный адрес, через который доступен API-сервер (доступен только для аутентифицированных запросов из соседних кластеров).
    • Список публичных адресов сервиса ingressgateway (доступен только для аутентифицированных запросов из соседних кластеров).
    • Публичные ключи сервера для аутентификации запросов к API-серверу и закрытым метаданным (см. выше).

Управление мультикластером

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

Накладные расходы

Внедрение Istio повлечёт за собой дополнительные расходы ресурсов, как для control-plane (контроллер istiod), так и для data-plane (istio-сайдкары приложений).

control-plane

Контроллер istiod непрерывно наблюдает за конфигурацией кластера, компонует настройки для istio-сайдкаров data-plane и рассылает их по сети. Соответственно, чем больше приложений и их экземпляров, чем больше сервисов и чем чаще эта конфигурация меняется, тем больше требуется вычислительных ресурсов и больше нагрузка на сеть. При этом, поддерживается два подхода для снижения нагрузки на экземпляры контроллеров:

  • горизонтальное масштабирование (настройка модуля controlPlane.replicasManagement) — чем больше экземпляров контроллеров, тем меньше экземпляров istio-сайдкаров обслуживать каждому из них и тем меньше нагрузка на CPU и на сеть.
  • сегментация data-plane с помощью ресурса Sidecar (рекомендуемый подход) — чем меньше область видимости у отдельного istio-сайдкара, тем меньше требуется обновлять данных в data-plane и тем меньше нагрузка на CPU и на сеть.

Примерная оценка накладных расходов для экземпляра control-plane, который обслуживает 1000 сервисов и 2000 istio-сайдкаров — 1 vCPU и 1.5GB RAM.

data-plane

На потребление ресурсов data-plane (istio-сайдкары) влияет множество факторов:

  • количество соединений,
  • интенсивность запросов,
  • размер запросов и ответов,
  • протокол (HTTP/TCP),
  • количество ядер CPU,
  • сложность конфигурации Service Mesh.

Примерная оценка накладных расходов для экземпляра istio-сайдкара — 0.5 vCPU на 1000 запросов/сек и 50MB RAM.

istio-сайдкары также вносят задержку в сетевые запросы — примерно 2.5мс на запрос.