Привет, Хабр! Под эгидой AOT мы проводим конференции для сообщества вокруг Kubernetes. На Kuber Conf от АОТ в 2025 году у нас выступал Михаил Петров, Kubernetes-эксперт в Stackland (Yandex Cloud). Для тех, кто любит смотреть видео — держите ссылку.
А ниже — текстовая версия доклада в изложении Михаила.

В целом кубером я занимаюсь вот уже почти 10 лет и за это время построил десятки продакшн-кластеров в VK и не только. В Yandex Cloud мы сейчас разрабатываем onprem-решение для запуска ИИ- и дата-нагрузок на базе Kubernetes и Talos OS.
В этой статье расскажу вам, как внедрить в ваши Kubernetes-кластера CNI Chaining — обсудим, когда это вообще полезно и применимо, какие плюсы несёт и с какими сложностями можно столкнуться в процессе.
Как вы знаете, в Яндексе широко используется ipv6. На ноду выдаются префиксы (/96 или /64), а потом уже из них выдаются ipv6-адреса для серверов, запущенных на этой ноде. В один прекрасный момент я подумал — а чем вообще поды, запущенные на нодах, не сервисы? И решил реализовать такой паттерн в своей домашней лаборатории. Перед этим почитал многое по теме — SIG Networks и документацию — и понял, что именно мой кейс нигде не описан и в крупных плагинах не используется, его поддержки нет ни в Calico, ни в Cilium. Только в AWS поддержка Prefix Delegation отчасти есть, но она всё равно реализована на базе собственного плагина, а не опенсорсного.
Что такое CNI Chaining
Де-факто CNI (Container Network Interface) — контракт между рантаймом (например, containerd) и сетевым плагином. Это бинарник, который умеет:
читать параметры сети из stdin;
читать параметры из окружения;
возвращать результат в stdout.
Это открытый стандарт, так что любой желающий может написать свой CNI-плагин.
К организации сетевого стека в этом случае существует два подхода. Первый — монолит, глубокая интеграция компонентов, оптимизированный datapath и единая точка поддержки. Весомый минус — если вам захочется поменять какую-то часть, то менять придётся весь монолит целиком. Второй — CNI Chaining, здесь стек состоит из маленьких плагинов, у каждого из которых всего лишь одна конкретная роль (что очень unix way). Собственно, отсюда и минусы — разные плагины пишут разные логи, по-разному ломаются, и приходится тратить больше времени, чтобы следить за их работоспособностью.
В чём главные отличия между монолитом и Chaining? Монолит в случае чего сложно изменить, а Chaining — нет. В монолите всё живёт внутри одного-единственного плагина, в Chaining-е же мы можем всё комбинировать, как душе угодно. С монолита сложно съехать, например, миграция с Calico на Cilium вполне может занять у вас несколько месяцев.
Какие есть типы CNI-плагинов
Прежде всего, main-плагины — именно они и создают интерфейсы. Например, bridge, который может создать вам мост и veth-пару, point to point, просто создающий две veth-пары, и macvlan/ipvlan для прямого доступа к хосту.
IPAM-плагины выдают поду IP-адрес — host-local, DHCP или какой-нибудь внешний плагин, скажем, Whereabouts, который позволяет координировать выдачу IP-адресов на уровне всего кластера.
Meta-плагины умеют модифицировать поведение на сетевом интерфейсе. Они дают возможность зашейпить трафик, выделить нужный порт в IPtables для проброски трафика в под, или вообще изолировать под от внешней сети.
Операции CNI
Все операции CNI — это контракт, хорошо описанный в спецификации, так что при внимательном изучении спеки с описанием плагина проблем у вас не возникнет. Основных операций две — добавить что-то на сетевой интерфейс или же что-то с него удалить.

Кстати, отмечу тут важно, не не самое очевидное. CNI-плагины не знают про кубер, вообще. Их роль — настроить сетевой стек, который вы будете использовать.

Всегда ли стандартные CNI подходят для работы?
Нет, не всегда. Иногда встречаются требования, которые по тем или иным причинам не укладываются в ваш roadmap. Вот пример, мой случай — я хотел по DHCPv6 получать префикс на ноду, а потом из этого префикса и раздавать IP-адреса подам. Или у вас может быть какая-то специфичная L2/L3-топология, либо вам надо зеркалировать трафик, приходящий на определённый поды. Так вот, все эти действия стандартные CNI-плагины не разрешат.
Где используется CNI Chaining
Я хотел найти какие-то практические примеры для статьи, так что посмотрел, как CNI Chaining используется в крупных облачных провайдерах. Выяснилось, что он довольно популярен в AWS, а ещё на нём архитектурно построен GKE Dataplane v2. В энтерпрайзе Chaining тоже часто используется.
Существуют и сетевые проекты, использующие Chaining для обеспечения своей работы — например, Kube-OVN предоставляет свой бинарник, на который потом сверху навешивают Cilium. К слову, подход популярный и используется не только тут.
Вот ещё несколько примеров.
Вы точно знаете, что такое nodeport. До того, как появился Cilium, nodeport реализовывался так — был некий порт хоста, который надо было пробросить в под, причём автоматически. Именно это и позволял сделать плагин CNI — Portmap.
Другой пример — случаи, в которых у вас есть особые требования к high-perfomance-тюнингу, и для определённых интерфейсов нужно настраивать конкретные sysctl-ы. Тут тоже CNI Chaining в помощь.
Классика жанра тут — когда у вас есть нужда в создании service mesh, причём так, чтобы не сильно переделывать работу ваших имеющихся подов и приложений. Как всё работает: навешиваете на любой CNI-плагин Istio CNI и получаете прозрачные mTLS / L7-политики без каких-то повышений привилегий в подах.
Используемые паттерны
Продакшен-паттернов CNI Chaining два. Первый — есть простая цепочка, когда каждый шаг этой цепочки отвечает за одно действие. А есть составная. На примере Flannel — у него используются оба паттерна.

Сначала запускается бинарник Flannel-а, который внутри себя вызывает CNI-плагин bridge и сам обрабатывает результаты его работы, а потом передает управление дальше по цепочке.
Вот он вызвал плагин, а потом передал управление в portmap и затем в ограничитель трафика.

Мы видим, что CNI-цепочка довольно-таки интересная вещь и может использоваться разными способами.
Повторюсь про Istio — в нём применяется подобный подход, когда мы результаты работы одного плагина передаем в другой.

Ключ к чейнингу — это prevResult, когда каждый последующий бинарник читает вывод предыдущего бинарника и выдает на выход свой вывод.

Зачем вам вообще Chaining. Цена гибкости
Прежде всего — это потрясающая гибкость. Вы можете реализовать абсолютно любую конфигурацию без необходимости патчинга больших монолитов. То есть любой кейс можно реализовать достаточно быстро и под задачи конкретной вашей инфраструктуры.
Если вы взяли и сделали свой CNI-плагин, то важно понимать, что старт пода у нас зависит от старта сети. И если ваш CNI-плагин где-то тормозит на каких-то операциях, то это увеличит время старта пода, это можно отслеживать по метрике PLEG, которая есть в кубере.
Итак, как понять — стоит ли вам реализовывать CNI Chaining? Критерий тут один: есть у вас опытные инженеры, разбирающиеся в сетевом стеке Linux, или нет. Если есть — можно пробовать. Если нет — ну, вы поняли. Вот вам картинка в помощь.

Итого
К чему мы пришли. Теперь вы знаете и можете добавлять новые фичи без форков CNI-плагинов, строить свои сетевые сценарии, комбинировать сетевые плагины как детальки «Лего» и избегать вендорлока.
Учитывайте одну важную вещь — написав собственный CNI-плагин, вы сами становитесь его вендором, как следствие — любые возникающие с ним проблемы ложатся на ваши плечи. В целом это оправдано, если вы и вправду крупный вендор, или же ваши edge-кейсы не подходят под стандартные решения, принятые в индустрии, либо миграция будет слишком дорогой.
Полезные ссылки
cni.dev — документация
Новая конференция Kuber Conf от АОТ пройдет совсем скоро — 22 октября. В центре внимания — инженерные задачи без привязки к конкретным облакам: практика эксплуатации Kubernetes, разбор инцидентов и обмен опытом. Участники обсудят построение инфраструктуры вокруг K8s и способы удержания падающего SLO.
Михаил Петров выступит там c докладом «От бизнес-требования к ядру Linux»
Ночью наша нода занята наполовину, а платим мы за все ядра. Расскажу, как запускать batch-нагрузки, не нарушая SLO low-latency-сервиса, и добиться более плотной утилизации нод.
Разберём:
Почему стоит убрать cpu.limits.
Какие механизмы cgroups v2 позволяют селить batch- и low-latency-нагрузку рядом.
Посмотреть другие материалы и зарегистрироваться на конференцию можно на сайте. Также мы планируем рассказывать новости в телеграм-канале АОТ.

