Цикл: «Сетевая безопасность Kubernetes: от основ до практической защиты» · материал 6 из 12
Формат: практический разбор
Для кого: ИБ-специалист, DevOps-инженер, архитектор и разработчик, которым нужно понять, где в Kubernetes реально принимается решение «разрешить или заблокировать пакет».
Кратко
NetworkPolicy — это объект Kubernetes API с описанием желаемого правила. Он сам не фильтрует ни одного пакета. Реальную работу выполняет реализация pod-сети: она подключает Pod к сети, отслеживает изменения в API и программирует datapath на worker node. Без поддержки NetworkPolicy со стороны этой реализации YAML можно успешно создать, но трафик останется открытым.
eBPF — один из способов построить такой datapath в Linux. Он не является самостоятельным firewall, не заменяет RBAC, защиту образов, аудит или реагирование. Его польза возникает только в связке: корректные правила, поддерживаемая версия ядра, контролируемая конфигурация и возможность доказать по телеметрии, почему поток был разрешён или заблокирован.
Ниже — методика: определить используемую реализацию сети, проверить enforcement на стенде из предыдущей статьи, собрать минимальный паспорт datapath и понять, что именно проверять перед выбором или изменением CNI.
Сначала разделим три разные вещи
Термины часто смешивают, из-за чего CNI превращается в «магический сетевой компонент». На практике это разные уровни.
| Уровень | Что делает | Что не доказывает |
|---|---|---|
| Kubernetes API | Хранит NetworkPolicy, Service, Pod и их labels |
Что пакет был отфильтрован |
| Реализация pod-сети / CNI | Подключает Pod к сети и может реализовать policy, маршрутизацию и Service | Что правила безопасны и полны |
| Datapath на node | Обрабатывает конкретный пакет: маршрут, трансляция, allow/drop | Кто и зачем создал широкое правило |
| Observability | Связывает поток с Pod, namespace, Service и verdict | Что блокировка не сломала бизнес-сценарий |
Официальная документация Kubernetes прямо отделяет API от реализации: pod-сеть и NetworkPolicy обычно обеспечиваются внешней реализацией сети; часть простых реализаций не поддерживает NetworkPolicy вовсе. Поэтому наличие ресурсов networkpolicy.networking.k8s.io в кластере — ещё не доказательство защиты.
Что такое CNI без маркетинга
CNI (Container Network Interface) — спецификация и набор плагинов, через которые container runtime на node настраивает сеть sandbox Pod. Kubernetes требует совместимый сетевой плагин для реализации своей модели pod-сети. Но CNI не означает фиксированный набор функций и не является названием конкретного продукта.
Одна реализация может только подключать интерфейс и выдавать IP. Другая дополнительно реализует межузловую маршрутизацию, NetworkPolicy, балансировку Service, шифрование, DNS/FQDN-политику или flow telemetry. Поэтому вопрос «у нас есть CNI?» бесполезен. Нужен другой вопрос: какая реализация pod-сети установлена, какие функции включены и где они применяются?
Не путайте эту роль с kube-proxy. Kubernetes даёт стандартную реализацию Service proxy через kube-proxy, но часть сетевых решений реализует Service handling внутри собственного datapath. Для расследования это важно: один и тот же вызов backend.default.svc.cluster.local может сначала быть виден как Service, а затем как соединение с конкретным endpoint Pod.
Как пакет связан с предыдущей статьёй
Возьмём стенд client → backend из материала о NetworkPolicy. После default deny успешное обращение по TCP/8080 возможно только когда:
- DNS разрешил имя
backend; - Service направил соединение к endpoint
backend; - datapath источника разрешил egress от
client; - datapath получателя разрешил ingress к
backend; - обратный трафик был обработан как ответ разрешённого соединения.
Схема не означает, что каждый CNI применяет правила в одинаковых точках ядра. Она показывает границы проверки. Если поток не проходит, нельзя заключать «NetworkPolicy сломана», пока не разделены DNS, Service/endpoints, policy и сама связность между node.
client Pod → DNS / Service → datapath на source node → сеть между node → datapath на destination node → backend Pod
│ │ │
имя/endpoint egress policy ingress policy
Почему одинаковый YAML может работать по-разному
Стандартный API NetworkPolicy задаёт ожидаемый результат на L3/L4: какой Pod выбран, откуда или куда разрешён TCP/UDP/SCTP. Он не предписывает конкретный внутренний механизм. Реализация может использовать Linux routing, iptables/nftables, виртуальные интерфейсы, overlay-туннель, BGP-маршрутизацию или eBPF. Эти технологии не являются взаимозаменяемыми пунктами настройки: в одном кластере может сочетаться несколько из них.
Из этого следуют два практических правила.
Первое: нельзя переносить инструкции «посмотрите правило в iptables» в другой кластер и считать их универсальной проверкой. Второе: нельзя оценивать CNI только по YAML совместимости. Нужно проверять фактический поток в конкретной версии CNI, Kubernetes и ядра Linux.
Минимальная инвентаризация без доступа к node
Начните с read-only команд. Они не раскрывают внутреннее устройство datapath полностью, но дают основу для дальнейшего запроса к платформенной команде.
kubectl get nodes -o wide
kubectl -n kube-system get daemonset
kubectl -n kube-system get pods -o wide
kubectl get networkpolicy -A
kubectl get svc -A
Зафиксируйте результат в паспорте кластера, а не в личных заметках:
| Поле | Что записать | Зачем |
|---|---|---|
| CNI и версия | точное имя реализации и release | определяет документацию и известные ограничения |
| Kubernetes и ядро node | версии control plane, worker OS/kernel | важны для совместимости и eBPF-функций |
| Pod/Service CIDR | фактические диапазоны | нужны для маршрутизации, egress и расследований |
| Межузловая схема | direct routing, overlay, BGP или иное | определяет путь трафика и возможные слепые зоны |
| Service handling | kube-proxy или замена CNI |
объясняет трансляцию Service→endpoint |
| NetworkPolicy | поддержка, режим enforcement, scope | отвечает на вопрос, действует ли default deny |
| Телеметрия | источник flows, поля, retention, экспорт | делает policy проверяемой и расследуемой |
Названия DaemonSet и Pod могут подсказать поставщика, но это не доказательство включённых функций. Версию и режим policy нужно подтвердить конфигурацией и документацией именно этого CNI.
Проверка, что policy действительно действует
Не заменяйте функциональную проверку просмотром объектов. Возьмите отдельный namespace np-lab из статьи 5 и выполните три теста в таком порядке:
# 1. До изоляции: client должен достичь backend
kubectl -n np-lab exec deploy/client -- \
curl -fsS --max-time 3 http://backend:8080
# 2. После default deny: тот же поток не должен пройти
kubectl -n np-lab exec deploy/client -- \
curl -fsS --max-time 3 http://backend:8080 || echo "blocked as expected"
# 3. После DNS и узких ingress/egress policy: поток снова проходит
kubectl -n np-lab exec deploy/client -- \
curl -fsS --max-time 3 http://backend:8080
Это не тест производительности и не полная приёмка CNI. Он отвечает на базовый вопрос: выбранная реализация изменила судьбу реального соединения после изменения NetworkPolicy или нет.
Для отрицательного теста добавьте Pod без разрешающей метки и убедитесь, что он не получает доступ к backend. Успешный allow-тест сам по себе слабое доказательство: соединение могло пройти из-за слишком широкого правила, другой политики или отсутствия enforcement.
Результат нужно фиксировать как артефакт изменения: версия CNI, namespace, применённые манифесты, время, allow/deny-результат и ссылка на flow/event, если он доступен.
eBPF: что это и чего от него не ждать
eBPF — механизм Linux kernel, позволяющий исполнять проверенные программы в разрешённых точках ядра. В сетевом datapath он может обрабатывать пакет на раннем этапе, сопоставлять его с картами состояний, применять policy или собирать metadata. Это механизм исполнения, а не отдельная политика безопасности.
Например, Cilium использует eBPF-программы, привязанные к сетевым hook. Его документация описывает проверку policy на veth/TC-пути и сопоставление пакета с identity и policy. Это описание относится к Cilium; его нельзя объявлять устройством любого CNI.
У eBPF есть реальные преимущества для динамичной среды: решение может связать flow не только с краткоживущим IP, но и с Kubernetes identity; Service lookup и policy могут использовать общую картину endpoints. Но «у нас eBPF» не отвечает ни на один из критичных вопросов: есть ли default deny, кто может менять правила, включена ли телеметрия, хватает ли ресурсов или защищены ли сами node.
Cilium и Hubble: отдельный, а не обязательный вариант
Если кластер действительно использует Cilium, проверяйте его как конкретный продукт. Cilium документирует identity-aware L3/L4 policy для Pod-to-Pod; для расширенных возможностей использует собственные CRD. Hubble строится поверх Cilium и предоставляет распределённую observability: потоки, DNS-события и verdict policy.
Это полезно для ИБ, потому что расследование перестаёт опираться только на IP. Но Hubble не компенсирует ошибочную политику и не превращает наблюдение в блокировку. Сначала нужна минимальная связность, подтверждённая allow/deny-тестами; затем — осмысленный экспорт нужных событий и срок хранения.
Ниже команды допустимы только после подтверждения, что установлен Cilium и разрешён доступ к его агенту:
kubectl -n kube-system get pods -l k8s-app=cilium
kubectl -n kube-system exec ds/cilium -- cilium status --wait
Не копируйте эти команды в кластер с другим CNI. Для него используйте штатную диагностику поставщика и проверьте: отображается ли источник, назначение, DNS-имя (если оно нужно), порт, verdict, причина/политика и время события.
Как выбрать нужную глубину контроля
Стандартная NetworkPolicy подходит, когда нужно управлять Pod/namespace/IP и портом на L3/L4. Это базовый переносимый минимум. Запросы «разрешить только конкретное DNS-имя», «только HTTP GET /health» или «видеть HTTP-код ответа» выходят за пределы стандартного API и требуют расширения конкретного CNI, egress proxy, Gateway/API gateway или service mesh.
Не начинайте с L7 только потому, что оно доступно в интерфейсе продукта. Более глубокий контроль добавляет компоненты, правила, сертификаты, нагрузку и точки отказа. Он оправдан, когда L3/L4 не выражает необходимую границу риска: например, один общий порт обслуживает и разрешённый, и опасный API-метод.
Нагрузка, отказ и обновление
Вопрос «eBPF быстрее iptables?» не является критерием проектного решения. Итог зависит от режима CNI, ядра, числа endpoints, Service, policy, включённого шифрования и объёма наблюдения. Нужны измерения на репрезентативной нагрузке, а не обещание из презентации.
Перед включением глубоких flow logs или L7-observability определите:
- какие события действительно нужны для защиты и эксплуатации;
- ожидаемый поток событий и retention;
- CPU, память и сетевой трафик на node;
- куда экспортируются события и кто имеет к ним доступ;
- поведение при недоступности collector или переполнении буфера;
- порядок обновления CNI и проверку rollback.
Особый риск — изменение CNI или его datapath одновременно с default deny. Это две переменные в одном инциденте. Сначала докажите базовую связность и policy enforcement в пилотном namespace, затем отдельно меняйте CNI/режим и повторяйте те же тесты.
Чек-лист приёмки CNI с точки зрения ИБ
Перед тем как считать CNI частью контролируемой защиты, должны быть положительные ответы на вопросы:
- Поддерживает ли текущая версия именно стандартный Kubernetes NetworkPolicy и включён ли enforcement?
- Подтверждён ли отрицательный тест
default denyна реальном Pod-трафике? - Проверены ли ingress и egress, DNS, Service и связь между разными node?
- Известны ли режим маршрутизации, Service handling и поведение egress/NAT?
- Есть ли диагностика deny и корректная связь IP с Kubernetes metadata?
- Ограничены ли права на изменение CNI-конфигурации, labels и NetworkPolicy?
- Зафиксированы ли ресурсные лимиты, обновление, rollback и ответственные?
Если на несколько пунктов ответ «не знаю», CNI нельзя считать проверенным средством сегментации. Это не основание немедленно менять продукт; это основание закрыть неизвестность тестом, документацией поставщика и измерением в своём кластере.
Итог
NetworkPolicy описывает, что разрешено. Реализация pod-сети и её datapath решают, как это будет применено. Observability позволяет увидеть, что произошло. eBPF может быть сильной технической основой для этих задач, но не является заменой архитектуры безопасности.
Следующая статья переходит к другой границе: ServiceAccount и RBAC. Даже идеальная сетевая сегментация не спасает, если скомпрометированный Pod может через Kubernetes API читать Secrets или менять политики.
Официальные источники
- Kubernetes: Network Plugins
- Kubernetes: Services, Load Balancing, and Networking
- Kubernetes: Network Policies
- Cilium: Introduction to Cilium and Hubble
- Cilium: eBPF datapath
- Cilium: Kubernetes networking
Навигация по циклу:
← NetworkPolicy с нуля: как реально изолировать приложения в Kubernetes → · Начало цикла · ServiceAccount и RBAC: почему сетевая защита Kubernetes невозможна без контроля API →