Service Mesh і політика трафіку
1) Навіщо потрібен Service Mesh
Service Mesh - інфраструктурний шар для east-west трафіку (міжсервісні зв'язки), що дає однакові можливості без переписування коду:- Типова безпека: mTLS, автоматична видача/ротація сертифікатів, ідентичності сервісів.
- Політика трафіку: маршрутизація L7, канарські/АВ-тести, деградація і стійкість.
- Спостережуваність: метрики, логи, трасування, золоті сигнали на кожному виклику.
- Операції: єдині політики для всіх мов/фреймворків.
Відмінність від API-шлюзу: шлюз - north-south периметр; mesh - east-west всередині кластера/організації. Часто працюють разом.
2) Архітектура: площини і патерни
Data Plane: sidecar-проксі (Envoy/Linkerd-proxy/haproxy), перехоплюючий трафік пода/ВМ.
Control Plane: розподіляє конфігурації (маршрути, політики, сертифікати), зберігає стан, публікує сервіс-дисковері.
Identity: зазвичай SPIFFE ID і автоматичні X.509-сертифікати (SPIRE/вбудований CA).
Точки входу/виходу: ingress/egress-gateway для контролю граничних потоків.
Режими впровадження: sidecar на кожен під; пер-вузлові/ambient-моди в нових реалізаціях.
3) Політика безпеки і zero-trust
1. mTLS by default: шифрування і взаємна автентифікація servis↔servis.
2. AuthN/AuthZ:- AuthN: довіряємо тільки ідентичностям, виданим CA mesh'a (SPIFFE).
- AuthZ: декларативні правила «хто може до кого і як» (RBAC/ABAC).
- Дозволені домени/підмережі; примусовий вихід через egress-gateway.
- Блокування прямих виходів з подів.
3. Ізоляція та egress-контроль:
4. Ротація секретів: короткоживучі сертифікати, автоматична переконфігурація проксі.
yaml apiVersion: security. istio. io/v1beta1 kind: PeerAuthentication metadata: { name: default, namespace: istio-system }
spec:
mtls: { mode: STRICT }
Istio (приклад: дозволити тільки inventory→billing на gRPC):
yaml apiVersion: security. istio. io/v1beta1 kind: AuthorizationPolicy metadata: { name: billing-allow, namespace: prod }
spec:
selector: { matchLabels: { app: billing } }
rules:
- from:
- source: { principals: ["spiffe://corp. local/ns/prod/sa/inventory"] }
to:
- operation: { ports: ["8080"], methods: ["POST"], paths: ["/proto. Billing/"] }
4) Політика трафіку: стійкість і маршрутизація
4. 1 Таймаути і ретраї
Timeouts: обов'язково задаються на виклик (connect/read/overall).
Retries: тільки для ідемпотентних операцій; backoff + джиттер; ліміти per-try timeout.
yaml apiVersion: networking. istio. io/v1beta1 kind: VirtualService metadata: { name: orders }
spec:
hosts: ["orders"]
http:
- route:
- destination: { host: orders, subset: v1, port: { number: 8080 } }
timeout: 5s retries:
attempts: 2 perTryTimeout: 2s retryOn: "5xx,connect-failure,reset"
4. 2 Circuit Breaker и outlier detection
CB: обмежує одночасні запити/підключення, захищаючи апстріми.
Outlier: викидає «погані» інстанси помилково/латентності.
yaml apiVersion: networking. istio. io/v1beta1 kind: DestinationRule metadata: { name: orders }
spec:
host: orders trafficPolicy:
connectionPool:
http: { http1MaxPendingRequests: 1024, maxRequestsPerConnection: 100 }
outlierDetection:
consecutive5xxErrors: 5 interval: 5s baseEjectionTime: 30s maxEjectionPercent: 50
4. 3 Канарські і за-умовами
Weighted: розділення трафіку за вагами v1/v2.
Header-based: прапори/куки/tenant → перекидати в нову версію.
Session affinity: хеш по ключу (акуратно з масштабуванням).
yaml http:
- match: [{ headers: { "x-experiment": { exact: "new" } } }]
route: [{ destination: { host: orders, subset: v2 } }]
- route:
- destination: { host: orders, subset: v1, weight: 90 }
- destination: { host: orders, subset: v2, weight: 10 }
4. 4 Fault Injection і деградація
Ін'єкція затримок/помилок для тесту стійкості і SLO.
yaml fault:
delay: { fixedDelay: 300ms, percentage: { value: 10 } }
abort: { httpStatus: 503, percentage: { value: 1 } }
5) Мережеві межі: ingress/egress і зовнішні сервіси
Ingress-gateway: єдина точка входу для зовнішніх клієнтів в mesh; інтеграція з WAF/OIDC/ratelimits.
Egress-gateway: центральний вихід зі списком дозволених хостів, TLS-інспекція, запис телеметрії.
ServiceEntry: оголошує зовнішні SNI/host як частину mesh (політики і mTLS-origination застосовні).
yaml apiVersion: networking. istio. io/v1beta1 kind: ServiceEntry metadata: { name: payments-external }
spec:
hosts: ["api. payments. com"]
ports: [{ number: 443, name: https, protocol: TLS }]
resolution: DNS location: MESH_EXTERNAL
6) Multi-cluster, multi-network і гібрид
Загальна PKI/траст-домен: єдині SPIFFE-ідентичності між кластерами.
Endpoint discovery: кулі сервісів між регіонами; локальний пріоритет і failover.
Зональна ізоляція: регіональні політики, ліміти та пріоритети.
ВМ в mesh: підключення legacy/Stateful систем до проксі і тих же політиків.
7) Спостережуваність, SLO та експлуатація
Метрики: `requests_total`, `request_duration_ms{p50,p95,p99}`, `5xx_rate`, `retry_attempts`, `cb_state`, `mTLS_authz_denied`.
Логи доступу: структурні, з'traceparent','user/tenant','response _ flags'.
Трейсинг: авто-ін'єкція заголовків (W3C Trace Context), семплювання, спани на hop-рівні.
SLO: цілі за р99/помилками на маршруті (service→service).
Алерти: сплеск'5xx', зростання'reset','outlier _ ejections', деградація mTLS (handshake failures).
8) Продуктивність і вартість
Sidecar додає накладні (CPU/RAM/latency). Оптимізуємо:- Зернистість: включати політику там, де потрібна; не включати важкі фільтри скрізь.
- Пули: розділити шляхи (критичні/фонові) на різні маршрути і ліміти.
- Профілювання: p99 на «холодних» маршрутах, обсяг телеметрії (rate-limit логів/трейсів).
- Розглянути ambient/sidecarless режими, якщо підтримуються і підходять під вимоги.
9) Безпека та комплаєнс
Мінімально необхідний доступ: явно вирішувати напрямки і методи.
Політики щодо неймспейсів/тенантів: мережеві/авторизаційні межі.
Ротація ключів/СА: планова та аварійна; короткі TTL сертифікатів.
PII/секрети: маскування в логах/трейсах; шифрування на дроті/в спокої.
Аудит: хто, коли і яку політику змінив; двоетапні апруви.
10) Інтеграція з K8s-рівнем
Mesh-політики доповнюють, а не замінюють NetworkPolicy.
В ingress/egress-gateway можна вішати PodSecurity/PSA рівнем нижче.
НРА/автоскейлінг: враховуйте ретраї/СВ - вони змінюють навантаження.
Плани релізів: канарні ваги через VirtualService + автоматичне просування по SLO.
11) Чек-лист впровадження
- Визначено межі довіри та включено STRICT mTLS.
- Включені AuthZ-політики: хто до кого, на яких портах/методах.
- Налаштовані timeouts/retries і outlier detection, визначені ідемпотентні шляхи.
- Прописані канарські маршрути і rollback-план; fault-injection - тільки в не-прод.
- Винесені зовнішні залежності через egress-gateway і ServiceEntry.
- Налаштовані метрики, логи, траси; дашборди та алерти на p99/5xx/CB.
- Передбачені квоти/ліміти per-tenant/namespace.
- Підготовлені runbooks: витік сертифіката, відмова CA, деградація апстріму, масові 503/RESET.
- План multi-cluster (загальна PKI, локальні пріоритети, DR-сценарії).
- Тест-дні (game days): падіння control plane, стоп sidecar, розрив мережі, «отруйний» апстрім.
12) Анти-патерни
Mesh «скрізь і відразу» без інвентаризації маршрутів і SLO → дорога складність.
Ретраї за замовчуванням для всіх методів → дублі ефектів і лавина трафіку.
Відключений mTLS «тимчасово» → залишається назавжди.
Egress без шлюзу → витік даних/невраховані залежності.
Одна глобальна політика для всіх сервісів → фальш-безпеку і помилкові спрацьовування.
Нульовий observability: включили mesh, але не збираємо метрики/трейси - втрачаємо сенс.
13) Швидкі рецепти
Linkerd: включити mTLS і policy по серверу
yaml apiVersion: policy. linkerd. io/v1beta1 kind: Server metadata: { name: billing, namespace: prod }
spec:
podSelector: { matchLabels: { app: billing } }
port: 8080 apiVersion: policy. linkerd. io/v1beta1 kind: ServerAuthorization metadata: { name: billing-allow-inventory, namespace: prod }
spec:
server: { name: billing }
client:
meshTLS:
identities: ["inventory. prod. serviceaccount. identity. linkerd. cluster. local"]
Consul (L7 intent + splitter)
hcl
Kind = "service-router"
Name = "orders"
Routes = [{
Match { HTTP { PathPrefix = "/v1" } }
Destination { Service = "orders" }
}]
Kind = "service-splitter"
Name = "orders"
Splits = [
{ Weight = 90, ServiceSubset = "v1" },
{ Weight = 10, ServiceSubset = "v2" }
]
14) FAQ
Чи потрібен mesh маленькій команді?
Якщо 3-5 сервісів - частіше немає. Почніть з хорошого ingress і бібліотек стійкості. Підключайте mesh, коли з'являється потреба в mTLS-за-замовчуванням, єдиних політиках і трасуванні без зміни коду.
Як контролювати вартість?
Заміряйте накладні (CPU/RAM/latency) на критичних шляхах, відключайте зайві фільтри, знижуйте обсяг логів/трейсів, використовуйте режими без sidecar там, де це безпечно.
Чи можна заважати mesh і вручну налаштовані проксі?
Так, але уникайте подвійної маршрутизації/дублюючих ретраїв. Єдине місце істинні - control plane.
Що важливіше: безпека чи продуктивність?
За замовчуванням - безпека (mTLS, AuthZ). Продуктивність досягається тюнінгом connection pools, outlier detection, цільовими маршрутами.
15) Підсумки
Service Mesh перетворює мережу між сервісами в програмований шар з єдиними політиками: шифрування та ідентичності, тонка маршрутизація і стійкість, телеметрія і квоти. Починайте з критичних шляхів, включайте STRICT mTLS і явні AuthZ, задавайте таймаути/ретраї/СВ, контролюйте egress, вимірюйте p99 і 5xx, проводьте game days. Тоді mesh стане підсилювачем надійності і швидкості релізів, а не джерелом несподіванок.