Перейти к содержимому
Hogin Hogin
Назад

Service mesh без sidecar: Cilium Service Mesh рядом с Istio Ambient

8 мин чтения

Istio Ambient в 2024–2025-м считался финальным ответом на «налог сайдкара» — убрали прокси-контейнер из каждого пода, заменили его двумя новыми типами компонентов, ztunnel и waypoint. Это уже не сайдкар, но это всё ещё отдельный слой прокси поверх кластера. Cilium, если он у вас и так стоит ради CNI и Hubble, решает ту же задачу без единого дополнительного прокси-процесса — mTLS и L7-политики живут на том же eBPF-датаплейне, что и обычная сетевая политика. Разбираемся, где проходит настоящая архитектурная граница между «без сайдкара» и «без прокси вообще», и что из этого следует на практике.

Содержание

Открыть содержание

От сайдкара к Ambient — и куда дальше

Классический service mesh (Istio в sidecar-режиме, Linkerd до недавних версий) ставит Envoy-прокси в каждый под. Прокси перехватывает весь входящий и исходящий трафик через iptables-редирект и на этом строит mTLS, retry, circuit breaking и L7-маршрутизацию. Цена — лишний контейнер на каждый под: свои CPU и память, отдельный процесс жизненного цикла, задержка на каждый лишний хоп через прокси.

Istio Ambient убирает именно этот sidecar, но не убирает прокси как класс. Вместо одного прокси на под появляются два новых компонента:

Это честный шаг вперёд: sidecar’а в поде больше нет, память и CPU-налог на под исчезает. Но control plane меша по-прежнему состоит из выделенных прокси-компонентов, которые нужно ставить, обновлять и эксплуатировать отдельно от остального кластера — и trafic, которому нужна L7-логика, всё равно делает лишний прыжок через waypoint.

Архитектурная разница: eBPF datapath против ztunnel/waypoint

Cilium заходит с другой стороны. У него уже есть eBPF-датаплейн, через который проходит весь трафик подов — на нём построены обычная сетевая политика, kube-proxy replacement и Hubble. Service Mesh-режим не добавляет параллельную инфраструктуру, а расширяет тот же датаплейн: mTLS-хендшейк и identity-проверка происходят прямо в eBPF-программах на ноде, L7-парсинг (HTTP-методы, пути, gRPC) — через Envoy, который у Cilium тоже встроен, но работает как общий процесс на ноду, а не как выделенный под на namespace, через который нужно прокладывать маршрут.

Istio Ambient: ztunnel и waypoint как отдельные компоненты против Cilium: mTLS и L7 на общем eBPF-датаплейне

Разница на уровне числа движущихся частей: у Ambient их три — CNI, ztunnel, waypoint, каждый со своим жизненным циклом и апгрейдом. У Cilium — один компонент, который вы и так эксплуатируете. Это не означает, что Cilium mesh «лучше» в любом сценарии — просто он решает более узкую задачу меньшим числом сущностей, а Ambient целится в полноценную traffic-management историю уровня Istio.

Что Cilium закрывает нативно, а что нет

Из классического набора «service mesh functionality» Cilium нативно и без дополнительных компонентов закрывает:

Путь запроса с mTLS: два хопа через sidecar/waypoint против одного прохода через eBPF-датаплейн ноды

Чего Cilium не закрывает и закрывать не пытается — сложный traffic management: canary-раскатки по процентам трафика, header-based routing между версиями сервиса, retry/circuit-breaking политики на уровне мешa. Это осознанно оставлено Istio (в любом режиме) и Gateway API-реализациям поверх него — Cilium не конкурирует с полноценным traffic shaping, а закрывает identity и L7-видимость там, где они и так нужны для observability.

Важный нюанс: Cilium умеет быть Gateway API-контроллером (Ingress/Gateway API), и на этом уровне появляется часть traffic-management примитивов — weighted routing между версиями сервиса, header-based match для входящего трафика с edge. Но это работает на границе кластера, а не как политика между произвольными сервисами внутри mesh — путать «Cilium как Gateway API-контроллер» с «Cilium как полноценный traffic-management mesh» не стоит, это разные периметры применения одной и той же технологии.

Сравнение в одной таблице

Sidecar IstioIstio AmbientCilium Service Mesh
Прокси в подеEnvoy sidecarнетнет
Отдельные мешевые компонентыEnvoy-сайдкарыztunnel + waypointнет — тот же eBPF-датаплейн
mTLSчерез sidecarчерез ztunnelчерез eBPF + SPIFFE-identity
L7-политикичерез sidecarчерез waypoint (доп. хоп)через per-node Envoy
Traffic shaping (canary, header routing)полноценныйполноценныйнет
Что эксплуатировать сверх CNIcontrol plane Istiocontrol plane Istio + ztunnel/waypointничего, если Cilium уже стоит

Честные ограничения

Два места, где Cilium Service Mesh обещает меньше, чем кажется на первый взгляд, и об этом стоит знать до того, как закладывать его в архитектуру.

Multi-cluster mesh. У Cilium есть Cluster Mesh — механизм, который соединяет несколько кластеров в общее сетевое пространство: поды одного кластера видят сервисы другого через тот же eBPF-датаплейн, без дополнительного gateway. Но это решает связность и балансировку, а не полноценный multi-cluster traffic management в духе Istio — например, единую политику failover между кластерами по latency или health check самого сервиса, а не только по доступности сети, Cluster Mesh из коробки не даёт. Если у вас active-active или active-passive стратегия на уровне сервисов, а не только сетей, это придётся строить поверх — либо Istio-уровнем, либо своим слоем.

Zero-trust identity целиком. mTLS на базе SPIFFE-identity внутри одного кластера Cilium закрывает честно, но полноценный zero-trust — это ещё и федерация identity между кластерами и внешними системами, ротация trust bundle, доверие между несколькими SPIRE-серверами. Cilium разворачивает SPIRE как часть своей установки, но это не отменяет того, что SPIRE — отдельная система с собственной операционной сложностью: federation между кластерами настраивается вручную, а не «из коробки» флагом Helm. Если zero-trust identity нужен именно как отдельная платформенная задача, а не только «под капотом у mesh», разворачивать и эксплуатировать SPIRE стоит осознанно, а не как побочный эффект одного флага.

Миграция с sidecar-based Istio без простоя

Если в кластере уже работает sidecar-based Istio, а Cilium стоит рядом только как CNI, миграция делается инкрементально, namespace за namespace, без общего окна простоя:

  1. Включите Cilium Service Mesh (authentication.mutual.spire) в кластере, оставив существующие Istio-сайдкары как есть — это два независимых mTLS-слоя, они не конфликтуют, просто на время миграции трафик шифруется дважды.
  2. Возьмите один некритичный namespace, уберите инъекцию sidecar (istio-injection: disabled на namespace, рестарт подов без sidecar) и включите на нём CiliumNetworkPolicy с authentication.mode: required — трафик из этого namespace теперь идёт через eBPF mTLS, а не через Envoy sidecar.
  3. Проверьте через Hubble, что хендшейк проходит и трафик не роняется политикой (см. раздел ниже), прежде чем повторять шаг на следующем namespace.
  4. Если где-то в мешe реально используется L7 traffic shaping (canary по заголовку, weighted routing) — эти namespace оставьте на Istio; переносить их на Cilium mesh не нужно, эту функциональность он не покрывает.

Такой namespace-by-namespace переход не требует downtime именно потому, что оба mTLS-слоя могут работать параллельно — вы не выключаете один механизм до включения другого.

Что нужно, чтобы включить mTLS на Cilium

Понадобится кластер с уже установленным Cilium (см. разбор Hubble и eBPF-наблюдаемости, если CNI ещё не стоит) и Helm. Cilium Mutual Authentication разворачивает SPIRE server и agent как часть чарта:

helm upgrade cilium cilium/cilium --namespace kube-system --reuse-values \
  --set authentication.mutual.spire.enabled=true \
  --set authentication.mutual.spire.install.enabled=true \
  --set hubble.enabled=true

cilium status --wait

Теперь потребуем взаимную аутентификацию для конкретного сервиса — остальной трафик в кластере продолжает работать как раньше:

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: require-mtls-backend
  namespace: default
spec:
  endpointSelector:
    matchLabels:
      app: backend
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: frontend
      authentication:
        mode: "required"
      toPorts:
        - ports:
            - port: "8080"
              protocol: TCP

С этого момента под с лейблом app: frontend может достучаться до backend:8080, только предъявив валидный SPIFFE-SVID на хендшейке — без единого sidecar-контейнера в обоих подах.

Как проверить, что всё работает

Убедитесь, что SPIRE-компоненты подняты и Cilium видит их:

kubectl get pods -n cilium-spire
cilium status | grep -i "mutual auth"
# Mutual authentication: Ready

Теперь смотрим живые потоки между frontend и backend и ищем факт аутентификации в flow:

hubble observe --namespace default --protocol http -f
# frontend -> backend:8080  FORWARDED  http-request  auth=SPIRE

Если снять лейбл app: frontend с клиентского пода (или временно завести под без валидной identity) и повторить запрос, в Hubble появится вердикт DROPPED с причиной, указывающей на несостоявшуюся аутентификацию — ровно то же наглядное «трассировка без сайдкаров», которым Cilium славится в обычных сетевых политиках, только теперь применительно к mTLS-хендшейку.

Итог

Istio Ambient честно решает проблему sidecar-налога, но взамен ставит два новых типа мешевых компонентов, которые нужно эксплуатировать отдельно, — это правильный выбор, если вам действительно нужен полноценный traffic management: canary по процентам, header-based routing, retry-политики. Cilium Service Mesh решает более узкую задачу — mTLS и L7-видимость — но делает это флагом конфигурации на датаплейне, который в кластере почти наверняка уже работает ради CNI и Hubble. Если весь ваш список требований — «шифровать трафик между сервисами и видеть, что происходит на L7», отдельный service mesh может быть просто лишним компонентом; если нужен полноценный traffic shaping — Cilium mesh его не закроет, и здесь без Istio Ambient (или его аналогов) не обойтись.


Поделиться:

Следующая статья
Flux 2.8: health-check-и на CEL и что это меняет в проверке релизов