Service Mesh: Istio, Linkerd
Service Mesh: Istio, Linkerd
1) Что такое Service Mesh и когда он нужен
Service Mesh — это слой сетевой плоскости данных/управления, обеспечивающий сквозной mTLS, маршрутизацию, отказоустойчивость и наблюдаемость между сервисами без переписывания кода.
Цели:- Безопасность по умолчанию (zero-trust, идентичности сервисов, политика доступа).
- Управление трафиком (Canary/Blue-Green, A/B, shadowing).
- Надежность (ретраи, таймауты, circuit breaking).
- Наблюдаемость (метрики, логи, трейсы).
- Операционная стандартизация (политики как код, GitOps).
- Много микросервисов с полилингвальностью и требованием mTLS.
- Нужны продвинутые сценарии маршрутизации/экспериментов без изменения приложения.
- Есть требования аудита/политик на сетевом уровне.
2) Istio vs Linkerd — краткое сравнение
3) Архитектура и модели развертывания
3.1 Sidecar mesh (классика)
Каждый Pod получает прокси-сайдкар.
Плюсы: зрелость, полный L7-контроль.
Минусы: накладные расходы CPU/RAM, усложнение деплоев/отладки.
3.2 Istio Ambient Mesh
ztunnel (L4) на узле + waypoint proxies (L7) по необходимости.
Плюсы: ниже стоимость и сложность, постепенное включение L7.
Минусы: новее, не все L7-кейсы доступны без waypoint.
4) Идентичность и mTLS (zero-trust)
4.1 SPIFFE/SPIRE и сертификаты
Каждому ворклоаду присваивается SPIFFE ID: `spiffe://cluster.local/ns/NS/sa/SA`.
Аутентификация: взаимный TLS между сервисами.
Ротация ключей — автоматически (короткий TTL).
4.2 Istio (PeerAuthentication + DestinationRule)
yaml apiVersion: security. istio. io/v1 kind: PeerAuthentication metadata: { name: default, namespace: payments }
spec:
mtls: { mode: STRICT }
apiVersion: networking. istio. io/v1 kind: DestinationRule metadata: { name: payments-dr, namespace: payments }
spec:
host: payments. svc. cluster. local trafficPolicy:
tls: { mode: ISTIO_MUTUAL }
4.3 Linkerd — mTLS по умолчанию
Включается после `linkerd install` + `linkerd inject`.
Кластеры — собственный trust-anchor, ротация автоматическая.
5) Трафик-менеджмент
5.1 Istio: VirtualService (маршруты, канареек)
yaml apiVersion: networking. istio. io/v1 kind: VirtualService metadata: { name: payments }
spec:
hosts: ["payments"]
http:
- route:
- destination: { host: payments, subset: v1 } # stable weight: 90
- destination: { host: payments, subset: v2 } # canary weight: 10 retries: { attempts: 2, perTryTimeout: 300ms }
timeout: 2s
DestinationRule (LB/CB):
yaml apiVersion: networking. istio. io/v1 kind: DestinationRule metadata: { name: payments }
spec:
host: payments subsets:
- name: v1 labels: { version: v1 }
- name: v2 labels: { version: v2 }
trafficPolicy:
loadBalancer: { simple: LEAST_CONN }
outlierDetection:
consecutive5xx: 5 interval: 5s baseEjectionTime: 30s maxEjectionPercent: 50
5.2 Linkerd: ServiceProfile + TrafficSplit
yaml apiVersion: linkerd. io/v1alpha2 kind: ServiceProfile metadata:
name: payments. default. svc. cluster. local spec:
routes:
- name: POST /withdraw condition:
method: POST pathRegex: "/withdraw"
isRetryable: true timeout: 2s apiVersion: split. smi-spec. io/v1alpha2 kind: TrafficSplit metadata: { name: payments }
spec:
service: payments backends:
- service: payments-v1 weight: 90
- service: payments-v2 weight: 10
6) Ingress/Egress и API-шлюзы
Istio Gateway (ingress/egress) — управляет входящим/исходящим трафиком, TLS termination, mTLS passthrough.
Linkerd работает c существующими ingress-контроллерами (NGINX/Contour/Traefik); egress — через NetworkPolicy/egress-gateway-паттерны.
Политики egress: белые списки доменов, SNI-policy, запрет прямого интернета.
7) Авторизация и политика
7.1 Istio AuthorizationPolicy (RBAC/ABAC)
yaml apiVersion: security. istio. io/v1 kind: AuthorizationPolicy metadata: { name: allow-withdraw, namespace: payments }
spec:
selector: { matchLabels: { app: payments } }
action: ALLOW rules:
- from:
- source:
principals: ["spiffe://cluster. local/ns/api/sa/gateway"]
to:
- operation:
methods: ["POST"]
paths: ["/withdraw"]
when:
- key: request. auth. claims[role]
values: ["cashout"]
7.2 Linkerd policy (server + serverauthorization)
yaml apiVersion: policy. linkerd. io/v1beta3 kind: Server metadata: { name: payments-server, namespace: payments }
spec:
podSelector: { matchLabels: { app: payments } }
port: 8080 apiVersion: policy. linkerd. io/v1beta3 kind: ServerAuthorization metadata: { name: allow-gateway, namespace: payments }
spec:
server: { name: payments-server }
client:
meshTLS:
identities: [".ns. api. serviceaccount. identity. linkerd. cluster. local"]
8) Наблюдаемость и телеметрия
8.1 Метрики
Istio Telemetry API → Prometheus: `istio_requests_total`, `istio_request_duration_milliseconds_bucket`, `istio_tcp_received_bytes_total`.
Linkerd viz: `request_total`, latency p50/p95/p99, `success_rate`.
8.2 Трейсы и логи
Пробрасывайте W3C Trace Context.
Istio/Envoy → OTLP в OpenTelemetry Collector; Linkerd — через sidecar-логгеры/апп-SDK.
8.3 Экземпляры (Exemplars)
Добавляйте `trace_id` к гистограммам длительности для «jump-to-trace».
9) Rate limits, WAF, кастомные фильтры
Istio: EnvoyFilter/WASM для локальных rate limits, eksternal-rate-limit service (Redis), а также WAF-логика (Lua/WASM).
Linkerd: ограниченная нативная поддержка; rate limit — на ingress/шлюзовом уровне.
10) Многокластерность
Istio: east-west gateway, общая PKI или trust-bundle, сервис-дискавери через ServiceEntry, Federation.
Linkerd: `linkerd multicluster link`, gateway per cluster, service-mirror контроллер.
Use-cases: актив-актив регионы, локализация трафика, федерированный zero-trust.
11) Производительность и стоимость
Sidecar mesh: оверхед CPU/RAM на каждый Pod, увеличенная латентность (обычно +1–3 ms на hop в steady-state).
Ambient (Istio): меньшее потребление для L4, L7 включается точечно.
Linkerd: легковесный прокси, как правило, меньше overhead, но меньше экстремальных возможностей L7.
Практика: измеряйте p95/CPU до/после, держите SLO-гейты на деградацию.
12) Безопасность
mTLS везде, короткий TTL, автоматическая ротация.
Policy as Code (OPA/Gatekeeper, Kyverno) для запретов `authorizationPolicy: ALLOW all`.
Секреты — через CSI/Vault, не в манифестах.
Egress-контроль: deny-by-default, явные allow-листы.
Отдельные trust domains для окружений (prod/stage).
13) Интеграция с релизами и SLO-гейтингом
Canary/Blue-Green реализуются маршрутами mesh (см. примеры).
Анализ метрик (Prometheus/SpanMetrics) в Argo Rollouts AnalysisTemplate — автостоп/откат при burn-rate/p95/5xx.
Аннотации релизов в Grafana: сравнение `version=stable|canary`.
14) Анти-паттерны
Включить mesh «везде и сразу» → шок инфраструктуры.
Игнорировать кардинальность метрик/логов от прокси → перегрузка TSDB/логхранилища.
Оставить mTLS в PERMISSIVE/opaque режиме навечно.
Пытаться сделать сложный WAF/бизнес-логики внутри EnvoyFilter вместо gateway/приложения.
Нет политики egress — утечки в интернет/обход комплаенса.
Прокси с `:15000` debug открыты наружу.
15) Чек-лист внедрения (0–60 дней)
0–15 дней
Выбор модели: Sidecar vs Ambient (Istio) / Linkerd по профилю нагрузок.
Включить mTLS STRICT, базовые политики авторизации для 1–2 критичных сервисов.
Базовые маршруты (timeout/retries), дашборды RED/SLO.
16–30 дней
Canary/TrafficSplit, outlier detection/circuit breaking на горячих путях.
OTEL интеграция: трейсы + Exemplars; алерты burn-rate.
Egress-gateways и белые списки доменов; deny-by-default.
31–60 дней
Многокластерный линк (если нужен), federation trust.
Policy as Code на AuthorizationPolicy/ServerAuthorization.
Game-day: симуляция инцидента и отката маршрутов/политик.
16) Метрики зрелости
Покрытие mTLS (STRICT/auto-rotate) ≥ 95% сервисов.
Доля трафика через канареечные/прогрессивные релизы ≥ 80%.
Средний overhead p95 < +5% от базовой линии (после оптимизации).
0 открытых egress без разрешения, 100% сервисов с базовыми AuthZ.
RCA «из графика в трассу» ≤ 2 минуты (p50).
17) Примеры «политики как код»
Gatekeeper (запрет PERMISSIVE в проде)
yaml apiVersion: constraints. gatekeeper. sh/v1beta1 kind: K8sIstiomTLSStrict metadata: { name: deny-permissive-prod }
spec:
match:
kinds: [{ apiGroups: ["security. istio. io"], kinds: ["PeerAuthentication"] }]
namespaces: ["prod-"]
parameters:
allowedModes: ["STRICT"]
Kyverno (обязательные labels для VS/DR)
yaml apiVersion: kyverno. io/v1 kind: ClusterPolicy metadata: { name: require-mesh-labels }
spec:
rules:
- name: vs-dr-labels match:
any:
- resources:
kinds: ["VirtualService","DestinationRule"]
validate:
message: "owner and service labels required"
pattern:
metadata:
labels:
owner: "?"
service: "?"
18) Эксплуатационные советы
Версионируйте политики и маршруты (semver), промоушен через GitOps.
Наблюдаемость прокси: отдельные дашборды «proxy saturation» (CPU/heap, retries, 429/503).
Бюджет кардинальности: метки `route`, `code`, `destination` — только шаблонные.
Сетевые лимиты/квоты на уровень namespace (NetworkPolicy/LimitRange).
Документация команды: runbook «как откатить маршруты/политику/ключи mTLS».
19) Заключение
Istio и Linkerd решают одну задачу — стандартизировать безопасность, надежность и видимость межсервисных коммуникаций — но делают это с разной глубиной и стоимостью владения.
Нужны богатые L7-возможности и гибкие политики — берите Istio (рассмотрите Ambient для снижения накладных).
Нужны простота и малый overhead — берите Linkerd.
Какой бы mesh вы ни выбрали: включите mTLS по умолчанию, управляйте маршрутизацией как кодом, свяжите метрики с трейсами, закройте egress, и добавьте SLO-гейтинг в релизы. Тогда сетевой слой перестанет быть «черным ящиком» и станет предсказуемым инструментом устойчивости и скорости изменений.