Прямой ответ
По умолчанию в Kubernetes сетевой изоляции нет: любой под может достучаться до любого пода в любом namespace (сети-основы — flat-сеть — «скомпрометировали фронтенд-под — БД-под в соседнем namespace открыт» — lateral movement — OWASP-контекст); NetworkPolicy — ресурс, объявляющий «кто с кем может говорить» (firewall-правила на уровне подов по лейблам — не IP — лейбл-селекторы — декларативно и переносимо при пересоздании подов); важнейшая механика, которую не понимают: политика — whitelist-модель — как только под попал под действие хоть одной политики (podSelector сматчил), весь неразрешённый ею трафик указанного направления запрещается; «пустая» политика (podSelector: {} без правил) — запрещает всё для выбранных подов — отсюда паттерн default-deny (две политики на namespace: ingress-deny-all + egress-deny-all — «всё запрещено, дальше разрешаем явно» — как файрвол на сервере — только декларативно и в git — IaC-дисциплина); рабочий набор (на приложение из 3 компонентов — app/db/redis): (1) default-deny ingress+egress в namespace; (2) app: ingress — от ingress-контроллера (namespaceSelector по лейблу kubernetes.io/metadata.name=ingress-nginx) на порт 8000, egress — к db/redis (podSelector) по портам + DNS (egress UDP/TCP 53 в kube-system — первая поломка внедрения: «запретили egress — DNS умер — резолв сервисов лёг — всё легло» — DNS-разрешение — обязательное правило — классика); (3) db: ingress только от app на 5432 (egress — deny или минимум — БД наружу не ходит); (4) проверки: политики применяются CNI-плагином (Calico/Cilium — без поддерживающего CNI — NetworkPolicy — декорация, молча игнорируется — «написали политики, а они не работают» — проверка плагина — первый шаг; Cilium — расширенные возможности — L7-политики (по HTTP-методам/путям — «разрешить только GET /health» — FQDN-правила (egress по доменам — не IP — внешние API — http-клиенты)); egress во внешний мир: по IP-блокам (ipBlock CIDR — облачные диапазоны — хрупко), по FQDN (Cilium/Istio — «api.stripe.com:443» — читаемо и стабильно — вебхук-контекст), либо egress-шлюз (прокси-под с аудитом исходящего — «что реально шлёт приложение» — supply chain/утечки — SBOM-культура); отладка: kubectl exec из test-пода (curl-проверки «должно ходить/не должно» — диагностика — ephemeral-контейнеры при distroless — distroless-практика), логирование дропов (Calico flow logs/Cilium monitor — «кто стучится и отбивается» — материал для правил — observability-до-enforce — флаги-постепенность).
Практика: внедрение default-deny без остановки кластера
Поэтапно (боевой кластер, 40 сервисов): (1) аудит трафика (2 недели — Cilium Hubble/Calico flow logs — матрица «кто→куда» фактических соединений — «мы думали, app ходит в db и redis — оказалось ещё в legacy-сервис и наружу на 12 IP» — реальность против архитектурной картинки — микросервисы-ревизия); (2) report-режим (Cilium-политики в audit/DryRun или default-allow + логирование «что запретили бы» — Kyverno-аналог — список будущих поломок — без инцидентов); (3) default-deny по одному namespace (начиная с изолированного сервиса — проверка: DNS-egress, ingress-контроллер, health-пробы (probes-механика — kubelet-пробы — «запретили ingress — readiness лёг — под выпал» — пробы идут от kubelet — политика их учитывает по-своему в разных CNI — проверка обязательна), мониторинг-скрейпы (Prometheus — egress/ingress с prometheus-пода в namespace — «метрики пропали — алертинг ослеп» — вторая классика после DNS); (4) шаблонизация (Helm-темплинг политик — параметры: ingress-источники/порты — helm-практика — «40 namespace руками» — ошибка — шаблон+значения — конфигурация); (5) проверка политик как тесты (network-policy-тесты в CI: тестовый pod пытается достучаться — assert «разрешено/запрещено» — тест-культура — регрессия правил — красный CI — github-actions — политики — код, тесты — как у кода); (6) enforce на весь кластер + политика-запрет создания namespace без default-deny (Kyverno — «новый сервис стартует изолированным» — по умолчанию, не по памяти); (7) инциденты внедрения (реальные): cron-джоба ходила в БД по IP (не через Service — лейбл-селектор не сматчил — сервисы-механика — фикс: через Service), sidecar-логгер (Loki-агент — egress на loki:3100 — правило добавили), backup-агент (PITR-выгрузка — egress на S3-эндпоинт — FQDN-правило — MinIO/S3); итог месяца: lateral movement закрыт (pen-test — «из фронтенд-пода БД не видна» — харднинг-результат), производительность — в шуме (Cilium eBPF — микросекунды — ёмкость); главный вывод: NetworkPolicy внедряется как продукт (аудит → report → gradual enforce → тесты → политика-по-умолчанию), а не «накидали yaml за день».
FAQ
Что происходит с DNS при default-deny egress и как правильно разрешить?
Механика: резолв имён сервисов — kube-dns/CoreDNS в kube-system — egress-deny без явного DNS-правила блокирует UDP/TCP 53 → все обращения по именам падают (включая Service-имена — «БД по IP работает, по имени — нет» — диагностический маркер); правильное правило: egress UDP+TCP 53 на podSelector kube-dns (или namespaceSelector kube-system — по лейблу) — в каждой политике с egress-ограничением — boilerplate-блок (шаблонизация — Helm — сценарий выше); нюанс ndots:5 (k8s-resolv.conf — поиск доменов — сети — лишние DNS-запросы — FQDN с точкой — оптимизация — диагностика); проверка: nslookup kubernetes.default из test-пода после применения — 2 секунды — спасает часы («всё легло после политики» — incident-практика).
NetworkPolicy без Calico/Cilium работает?
Нет — API-ресурс принимается кластером (kubectl apply — success), но enforcement делает CNI-плагин (flannel в чистом виде — игнорирует — «политики есть, изоляции нет» — тихая ложь — проверка: kubectl get pods -n kube-system на calico/cilium-агенты, тест-доступом — тест-дисциплина); managed-кластеры: GKE (Calico-включение), EKS (VPC CNI + policies-аддон), AKS (Azure NPM — Calico-опция — облачный-контекст); выбор плагина по нуждам: L3/L4 (Calico — достаточно большинству), L7/FQDN (Cilium — HTTP-правила/домены — egress-политики читаемее — API-безопасность — «разрешить POST /pay» — уровень выше IP), service mesh альтернатива (Istio mTLS + AuthorizationPolicy — «политики с шифрованием» — heavier — микросервисы); правило: NetworkPolicy — минимум для любого прод-кластера (CNI выбирается до, не после — «мигрируем CNI ради политик» — операция серьёзная — миграция-контекст по аккуратности).
Как тестировать и отлаживать NetworkPolicy?
Тесты-проверки: test-под с curl в каждый защищаемый сценарий («app→db:5432 — разрешено, frontend→db — запрещено» — тест-структура — CI-джоба в кластере — github-actions — k8s-манифесты тестов рядом с политиками в git — IaC); отладка дропов: Calico — calicoctl get networkpolicy/flow logs, Cilium — cilium monitor --type drop (кто/куда/почему — label-объяснение — «dropped: policy denied» — логи-культура); частые ошибки: podSelector без namespaceSelector в мульти-namespace (правило «только свой namespace» — кросс-ns трафик требует обоих селекторов — «app из другого ns не достучался» — классика), пустой ingress-массив против отсутствия ключа (ingress: [] — запретить всё, ключ отсутствует — не трогать — семантика whitelist — перечитывать спецификацию), порядок не важен (политики аддитивны — union разрешений — «перекрывающиеся правила» — не конфликтуют, складываются — файрвол-логика наоборот); визуализация: Hubble UI/Cilium maps — граф фактических потоков против политик — «видеть, а не гадать» — observability.
Нужны ли NetworkPolicy, если есть service mesh (Istio)? Разные слои: mesh — L7 (mTLS-идентичность сервисов, AuthorizationPolicy по principals/путям — «сервис А с сертификатом может GET /api» — прикладной уровень — mTLS-контекст), NetworkPolicy — L3/L4 (IP/порт/лейблы — CNI-уровень — работает без mesh-сайдкара — «под без инжекции» — mesh-политики его не видят); защита в глубину — оба (mesh-баг/обход сайдкара — L3-изоляция держит — харднинг-принцип — «mesh даёт изоляцию» — частично: без NetworkPolicy mesh-трафик вне политик ходит свободно по портам); без mesh — NetworkPolicy — единственный сетевой контроль (40 сервисов без mesh — сценарий выше — достаточно для изоляции); практика 2026: default-deny NetworkPolicy — база для всех, mesh — поверх для тех, кому нужны L7/mTLS (микросервисы-зрелость — mesh — не замена базовой сетевой гигиены).
Источники: документация Kubernetes Network Policies, Cilium policy docs — ссылки в шапке.