====== ISTIO Service mesh ====== ===== Info ===== **Service mesh** (сервисная сетка) - инфраструктурный слой, который отвечает за управление сетевым взаимодействием между микросервисами (маршрутизация, балансировка, шифрование, аутентификация, авторизация запросов, сбор метрик, логов, политики доступа и проч)\\ Позволяет избавить прикладные приложения от необходимости реализации всей этой истории\\ **Istio** одна из реализаций **Service mesh**, логически разделен на **control plane** и **data plane**\\ **Control plane** административная структура (компоненты Pilot, Mixer, Citadel и Galley) * **Pilot** - маршрутизация, управляет конфигурацией **Envoy Proxy** (+ балансировка и возможность распределения трафика между разными версиями ПО) * **Mixer** - обрабатывает метрики, логи и политики контроля доступа * **Citadel** - генерирует и управляет сертификатами (mTLS), + аутентификация и авторизация * **Galley** - проверяет и распространяет конфигурацию, обеспечивает согласованность ==== Типы объектов ==== * **Мониторинг** * **kind: ServiceMonitor** - сбор метрик * **kind: IstioOperator** - отслеживание путей запросов с помощью Jaeger или Zipkin * **Безопасность** * **kind: PeerAuthentication** - автоматическое шифрование всего трафика между микросервисами с mTLS (mutual TLS) * **kind: AuthorizationPolicy** - аутентификация/авторизация на уровне сервисов * **Маршрутизация** - * **kind: VirtualService** - правила маршрутизации (например направление на разные версии сервисов), так же настраиваются повторные потытки и таймауты ==== Gateway ==== Точка входа в Service mesh\\ Указываем тип трафика, протокол, который хотим пустить в istio service mesh для дальнейшей маршрутизации к месту назначения\\
:!: Пример apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: demo-gtwy spec: selector: app: demo services: - port: number: 443 name: https protocol: HTTPS hosts: - demo.vs.com tls: mode: SIMPLE credentialName: demo-tls-cert * как только веб-трафик попадает на балансировщик нагрузки, он направляется на Istio gateway, тот позволяет трафику входить в сервис-меш через указанный порт (в даном случае 443) * на этом этапе маршрутизации к backend svc не происходит * gateway ищет достоверность CNAME чрез секретный ключ TLS (учетные данные) * как только gateway подтвердит и разрешит трафик от host, virtual service выполнит маршрутизацию к цели назначения
==== Virtual Service ==== Определяет как запросы маршрутизируются к сервисам внутри Service mesh (здесь можно задать сложные правила для маршрутизации)\\
:!: Конфигурация Основные поля это **hosts** (хосты для которых применяются правила) и **http/tcp/tls** (тип трафика для которого применяются правила)\\ В этом примере 80% трафика на v1, 20 на v2\\ apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - route: - destination: weight: 80 host: reviews subnet: v1 - destination: weight: 20 host: reviews subnet: v2
:!: Пример подробнее apiVersion: networking.istio/v1alpha3 kind: VirtualService metadata: name: demo-vs spec: hosts: - demo.vs.com http: - match: - headers: end-user: exact: /api route: - destination: host: / * запись **hosts** включает домен (или CNAME) приложения * затем мы переходим к **http routing** и настраиваем соответствующий **backend service** (видимо k8s svc) на определенный host/destination * конфигурация **"backend service"** находится в разделе **"match"** * **http section** включает правила маршрутизации, которые перенаправляются к **destination** * как только трафик (запрос) попадает на шлюз **Istio**, он ищет запись своего **CNAME/FQDN**. При совпадении он переводит трафик на **VirtualService**, который маршрутизирует его на соответствующий **k8s service**
==== DestinationRule ==== Определяет политики для подключения к целевым сервисам после примеренения маршрутизации\\ Кажется что опциональный элемент, применяется и к ServiceEntry тоже, для доп настроек, например инициирования mTLS либо еще какие то правила\\
:!: Конфигурация Основные поля: **host**, **subsets** (подмножества для различных веррсий или конфигураций сервиса) и **trafficPolicy** (политики для управления трафиком)\\ В этом примере определяются два подмножества (собсна две сетки из предыдущего примера) и определяется политика балансировки\\ apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: reviews spec: host: reviews subnets: - name: v1 labels: version: v1 - name: v2 labels: version: v2 trafficPolicy: loadBalancer: simple: ROUND_ROBIN
==== ServiceEntry ==== Позволяет добавить дополнительные записи во внутренний реестр служб Istio, чтобы автоматически обнаруженные службы в сетке могли получать доступ/маршрутизировать эти вручную указанные службы. Например добавление сервисов в сеть ISTIO, которые не находятся в вашем кластере k8s\\ Может открыть прямой трафик на внешнюю службу, если не применить связку "Gateway", "VirtualService"\\
:!: Пример, доступ к БД Postgres для пода # Добавляет доступ к указанным адресам (endpoints) # Можно указать только hosts, тогда по нему и порту будет доступно # можно еще указать addresses, тогда и по этому адресу будет доступ из пода --- apiVersion: networking.istio.io/v1beta1 kind: ServiceEntry metadata: name: se-postgres spec: hosts: - my-postgres-my-ns-1 # addresses: # - 10.10.10.10 exportTo: - '.' ports: - name: postgres-5432 number: 5432 protocol: tcp resolution: DNS location: MESH_EXTERNAL endpoints: - address: 10.10.10.10 Можно дополнительно применить DestinationRule для настройки mTLS\\ (не проверено) apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: mtls-mongocluster spec: host: my-postgres-my-ns-1 trafficPolicy: tls: mode: MUTUAL clientCertificate: /etc/certs/myclientcert.pem privateKey: /etc/certs/client_private_key.pem caCertificates: /etc/certs/rootcacerts.pem
:!: Объявление службы и маршрутизация при обращении к ней ServiceEntry + VirtualService \\ Используется комбинация входа в службу и маршрутизации TLS в виртуальной службе для направления трафика на основе значения SNI на внутренний выходной брандмауэр apiVersion: networking.istio.io/v1alpha3 kind: ServiceEntry metadata: name: external-svc-redirect spec: hosts: - wikipedia.org - "*.wikipedia.org" location: MESH_EXTERNAL ports: - number: 443 name: https protocol: TLS resolution: NONE И связанная с ней VirtualService для маршрутизации на основе значения SNI. apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: tls-routing spec: hosts: - wikipedia.org - "*.wikipedia.org" tls: - match: - sniHosts: - wikipedia.org - "*.wikipedia.org" route: - destination: host: internal-egress-firewall.ns1.svc.cluster.local При отсутствии виртуальной службы трафик будет перенаправлен на домены wikipedia.
:!: Параметры ServiceEntry **hosts** (обязат)\\ Хосты связанные с ServiceEntry. Используется для выбора соответствующих хостов в VirtualService и DestinationRule (SNI в т.ч.)\\ Если "resolution" == "DNS" и "endpoints" не указаны то "hosts" будет использоваться в качестве DNS имени для маршрутизации\\ **ports** (обязат)\\ порты связанные с внешней службой\\ **addresses**\\ Вирт IP адреса связанные со службой. Если указано то используется при маршрутизации, если нет то маршрутизация к этой точке будет только по порту **location**\\ Считать ли службу внешней по отношению к мешу или внутренней\\ Видимо тут только два варианта: "MESH_EXTERNAL" и "MESH_INTERNAL"\\ **resolution** (обязат)\\ Режим обнаружения служб для хостов\\ Если указать "None" без сопутствующих IP-адресов, то будет разрешен трафик на любой IP по этому порту (т.е. 0.0.0.0:port)\\ **endpoints**\\ Одна или несколько конечных точек связанных с сервисом\\ **exportTo**\\ Неймспейсы для применения политик, текущий (.) по умолчанию глобальный (*) \\ **subjectAltNames**\\ Для проверки альтернативного имени\\
==== Service ==== Для каждого **Service ISTIO** создает адрес в формате **"service-name.namespace.svc.cluster.local"**, т.к. ISTIO использует DNS для маршрутизации трафика между сервисами\\
:!: База
==== Envoy (proxy) sidecar ==== Перехватывает входящие и исходящие вызовы для сервисов, предоставляя hooks, необходимые для внешнего управления\\ Весь входящий и исходящий трафик приложения проходит через этот прокси. Это достигается путем изменения таблицы маршрутизации в контейнере приложения, чтобы весь трафик был перенаправлен на прокси \\ Взаимодействие между sidecar-прокси и "istio-egressgateway" происходит через gRPC-соединение. \\ ==== Примеры ====
:!: База
:!: Включение mTLS и авторизации Для включения mTLS всех сервисов в кластере создайте объект **PeerAuthentication** с политикой строгого mTLS (STRICT)\\ apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: default namespace: istio-system spec: mtls: mode: STRICT Чтобы обеспечить доступ к сервисам только авторизованным сервисам и пользователям, создайте объект **AuthorizationPolicy**\\ Например разрешить доступ к "httpbin" только "sleep"\\ apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: httpbin-policy namespace: default spec: selector: matchLabels: app: httpbin rules: - from: - source: principals: ["cluster.local/ns/default/sa/sleep"]
:!: Маршрутизация с помощью HTTP-заголовков apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: header-based-routing spec: hosts: - my-service http: - match: - headers: user-agent: prefix: "Mozilla" route: - destination: host: my-service subset: v2 - route: - destination: host: my-service subset: v1
:!: