Эра сайдкаров заканчивается. Ambient-режим в Istio достиг GA ещё в конце 2024-го, а к 2026 году для новых кластеров это уже режим по умолчанию. На каждой второй конференции звучит «сайдкары — это дорого, ambient — это будущее», и складывается соблазнительно простое правило: новый кластер → берём ambient, и не думаем.

Это правило работает ровно до того момента, пока вы не выкатываете в ambient канарейку и не обнаруживаете, что весь трафик идёт мимо неё. Или пока ваша свежая AuthorizationPolicy молча не блокирует легитимные запросы. Или пока вам не понадобится зрелый мультикластер.

Выбор между sidecar и ambient — это не тумблер «старое/новое». Это инженерное решение со своими компромиссами, и неверный выбор всплывает уже посреди внедрения, неприятными сюрпризами. В этой статье разберём, чем режимы реально отличаются под капотом, в чём главная ловушка ambient, что с ресурсами, апгрейдами и мультикластером, и как выбирать осознанно.

Версии на момент написания: Istio 1.30.x, Kubernetes 1.32–1.36. Темы вроде статуса мультикластера быстро меняются — сверяйтесь со своей версией.

Сначала — как вообще устроен data plane

Любой service mesh состоит из двух плоскостей: control plane (мозг, который раздаёт конфигурацию — в Istio это istiod) и data plane (прокси, которые реально несут трафик и накладывают mTLS, ретраи, маршрутизацию, телеметрию). Разница между sidecar и ambient — целиком в устройстве data plane.

Sidecar (классика). Когда под входит в меш, рядом с приложением в тот же под внедряется второй контейнер — прокси Envoy. Правила iptables заворачивают весь трафик пода через этот Envoy, и он делает всё: L4 и L7, mTLS, ретраи, маршрутизацию, метрики. Один Envoy на каждый под.

Ambient (современный дефолт). Сайдкаров нет. Плоскость данных разбита на слои:

  • ztunnel — DaemonSet, по одному на узел. Отвечает за L4 для всех подов узла: mTLS, идентичность, базовая телеметрия. Написан на Rust, лёгкий. Работает всегда.

  • waypointопциональный прокси Envoy на namespace или service account. Добавляет L7: HTTP-маршрутизацию, ретраи, L7-авторизацию, HTTP-метрики. Разворачивается только там, где L7 реально нужен.

  • Istio CNI — DaemonSet, который настраивает перехват трафика на уровне сетевого пространства пода (перенаправляет его на ztunnel), без init-контейнера.

sidecar:
[app][istio-proxy]   [app][istio-proxy]   [app][istio-proxy]
   под 1                под 2                под 3
   ↑ Envoy в каждом поде

ambient:
[app]  [app]  [app]          [ztunnel @ узел]   (+ waypoint, если нужен L7)
 под1   под2   под3           один на узел

Вся идея ambient в одной фразе: лёгкий L4 — всем и везде, тяжёлый L7 — только где требуется.

Ключевое различие: L4 дёшево всем, L7 по требованию

Большинству воркадов от меша нужно немного: взаимное шифрование (mTLS) и идентичность, чтобы понимать, кто с кем общается. Это L4, и ztunnel даёт его всем подам узла практически бесплатно — один прокси на узел вместо N сайдкаров.

А вот умная HTTP-маршрутизация, авторизация по заголовкам, ретраи, fault injection, HTTP-метрики и трейсы — это L7, и они стоят дороже. В ambient за них отвечает waypoint, который вы разворачиваете точечно, только для тех сервисов, которым L7 реально нужен.

В sidecar такого разделения нет: каждый под несёт полный Envoy, то есть платит за L7-возможности независимо от того, использует он их или нет.

Отсюда растут и все плюсы ambient, и его главная ловушка.

Главная ловушка ambient: «L7 не бесплатный»

Это сюрприз номер один, на котором спотыкаются команды. Многие подсознательно считают «меш = полный L7 из коробки» — как было в sidecar. В ambient это не так. ztunnel — это только L4. Всё, что про HTTP, требует waypoint.

Конкретно, в ambient без waypoint у вас:

  • не работает HTTP-маршрутизация и разбивка трафика по весам (канарейки уровня L7);

  • не применяется авторизация по HTTP-методу/пути/заголовкам;

  • не валидируется JWT;

  • нет HTTP-метрик уровня запроса (istio_requests_total), нет пер-запросных access-логов, нет трейсов;

  • не работают fault injection, rate limiting, ретраи и таймауты уровня L7.

При этом mTLS, L4-идентичность и L4-авторизация — работают, потому что это ztunnel.

Самое коварное — как именно это «не работает». Возьмём канарейку через Gateway API в ambient:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata: { name: search-canary, namespace: shop }
spec:
  parentRefs:
  - kind: Service
    name: search
  rules:
  - backendRefs:
    - { name: search-stable, port: 8080, weight: 90 }
    - { name: search-canary, port: 8080, weight: 10 }

Применяем — и статус маршрута зелёный:

$ kubectl get httproute search-canary -n shop -o jsonpath='{.status.parents[0].conditions}'
[{"type":"Accepted","status":"True"}, {"type":"ResolvedRefs","status":"True"}]

«Маршрут принят, всё ок» — думаете вы. А весь трафик при этом идёт на стабильную версию, в канарейку — ноль. Потому что разбивку по весам (L7) применять негде:

$ istioctl ztunnel-config services | grep search
shop   search   10.96.0.21   None   ...
                              ^^^^ WAYPOINT = None

Лечится разворачиванием waypoint:

istioctl waypoint apply -n shop --enroll-namespace

Ещё опаснее история с авторизацией. Если повесить AuthorizationPolicy с L7-атрибутами (метод, путь, заголовки) на воркад без waypoint, ztunnel не может её вычислить и срабатывает в безопасную сторону, то есть строже задуманного: ALLOW-политика с L7-условием становится «не совпадает ни с чем» и фактически блокирует весь трафик. Классическое «добавил безобидное правило — и прод лёг».

Вывод не «ambient плохой», а «планируйте размещение waypoint'ов заранее». Если вы знаете, что сервису нужен L7 — waypoint должен появиться вместе с правилами, а не после того, как вы час дебажите зелёный-но-неработающий HTTPRoute.

Ресурсы и производительность

Это та область, где у ambient есть реальный операционный выигрыш — и одновременно неочевидный подводный камень.

Проще: в sidecar обновление data plane означает перекатить все поды приложения — новый Envoy инъектируется только при создании пода. Это большая, заметная операция. В ambient перевод подов на обновлённый ztunnel не требует перезапуска подов приложения. Для прикладных команд это серьёзное облегчение.

Тоньше: ztunnel — это DaemonSet, по одному на узел, и обновляется «на узел целиком». Апгрейд ztunnel на месте кратко прерывает трафик меша на узле, а долгоживущие TCP-соединения после grace-периода рвутся (TCP RST). Поэтому в проде апгрейд ztunnel сопровождают cordoning'ом узлов или blue/green-пулами, чтобы ограничить blast radius. А istio-cni не поддерживает canary-апгрейд даже с ревизиями — его обновляют вместе с жизненным циклом узла.

То есть ambient убирает «налог на перезапуск всех подов», но взамен вводит понодовую специфику ztunnel. Не лучше и не хуже — просто другой набор соображений. Правила совместимости при этом общие для обоих режимов: control plane обновляется раньше data plane, и не больше одной минорной версии за раз.

Где sidecar пока объективно выигрывает

Ambient — дефолт для нового, но это не значит «всегда». Sidecar зрелее, и сегодня он предпочтительнее, когда:

  • Серьёзный мультикластер на масштабе. Sidecar-мультикластер — stable, прод-готовый, обкатанный. Ambient-мультикластер быстро дозревает: мульти-сетевой вариант достиг Beta (1.29, начало 2026), но одно-сетевой пока alpha, конфигурацию waypoint между кластерами нужно синхронизировать вручную, нет cross-cluster L7-failover, нет прямой адресации подов/headless-сервисов. Для тяжёлого cross-cluster сегодня sidecar безопаснее. Тренд, впрочем, однозначный — разрыв закрывается релиз за релизом, так что совет «для мультикластера бери sidecar» имеет срок годности.

  • Нужны EnvoyFilter или Wasm-плагины. Кастомные Envoy-фильтры на ztunnel не работают (он Rust и L4). В ambient их можно повесить на waypoint, но если кастомизация нужна повсеместно и пер-подово — sidecar естественнее.

  • Нужна пер-подовая гранулярность. Ambient наводится на уровне namespace/service account, а не отдельного пода.

  • Нужен полный L7 и подробная телеметрия везде по умолчанию, без планирования waypoint'ов.

Это спектр, а не тумблер

Самое важное для практики: выбор не «всё или ничего». Оба режима спокойно живут в одном кластере, выбираются по неймспейсам и взаимодействуют между собой (общий istiod, совместимый mTLS и идентичность SPIFFE).

kubectl label ns team-a istio.io/dataplane-mode=ambient
kubectl label ns team-b istio-injection=enabled

Нормальный, частый конечный пункт — гибрид: ambient для тех 80% сервисов, которым нужен только L4; sidecar для немногих, кому нужны EnvoyFilter или пер-подовые особенности; waypoint'ы на те ambient-неймспейсы, где требуется L7.

И миграция малорискованна, потому что это «дверь в обе стороны»: namespace можно перевести в ambient (без перезапуска подов) и при необходимости вернуть обратно. Начинать разумно с некритичного namespace, которому нужен только L4 — самый лёгкий шаг, waypoint не требуется. Единственное жёсткое ограничение — нельзя применить оба режима к одному и тому же поду.

Главная засада миграции — тот же паритет L7: VirtualService с маршрутизацией по заголовку или L7-авторизация, которые «просто работали» в sidecar, после перевода в ambient молча перестанут действовать, пока вы не развернёте waypoint и не перенесёте на него L7-конфиг. Поэтому перед миграцией каждого namespace — аудит использования L7.

Как выбирать: короткая шпаргалка

Фактор

Скорее ambient

Скорее sidecar

Большинству сервисов нужен только mTLS + базовая телеметрия

Память/ресурсы критичны на масштабе

Хочется апгрейдить data plane без рестарта подов

Нужны EnvoyFilter / повсеместный Wasm

Зрелый мультикластер на масштабе сегодня

Нужна пер-подовая гранулярность

Нужен полный L7 везде по умолчанию

L7 нужен точечно (часть сервисов)

✅ (ambient + waypoint)

Драйверы решения, если свести к сути: нужен ли вам L7 везде или точечно, насколько серьёзен мультикластер, требуются ли EnvoyFilter/пер-подовый тюнинг, и насколько важна экономия ресурсов. Для типового нового кластера ответ всё чаще «ambient», но именно как осознанный выбор, а не по инерции.

Вывод

Ambient — это не «sidecar, только лучше». Это другая архитектура data plane с другим распределением затрат: дешёвый L4 всем, дорогой L7 по требованию. Отсюда его сильные стороны (ресурсы, апгрейды без рестарта, чистые поды) и его главная ловушка («L7 требует waypoint, и без него всё молча не работает или ломается строже задуманного»).

Практический итог:

  • Для нового кластера, где большинству сервисов хватает mTLS и базовой телеметрии — ambient, по умолчанию, но с заранее спланированными waypoint'ами там, где нужен L7.

  • Для серьёзного мультикластера, повсеместных EnvoyFilter или пер-подовой гранулярности — пока sidecar.

  • В большинстве реальных кластеров — гибрид, и это нормально.

И, как обычно в инфраструктуре: меньше веры в красивые проценты из чужих бенчмарков, больше измерений на своём ворклоаде.

Это переработанный фрагмент моего курса по Istio (ambient-first, под версии 2026 года): от устройства меша и управления трафиком до безопасности, наблюдаемости и методичной диагностики инцидентов. Замечания и спорные места — welcome в комментарии, особенно по мультикластеру: эта часть меняется быстрее всего.

Комментарии (0)