====== 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
:!: