Как работают Network Policies?

Что такое NetworkPolicy

NetworkPolicy — это декларативный объект в Kubernetes, который описывает правила сетевого доступа к подам и от подов в пределах сетевого плагина (CNI). NetworkPolicy позволяет разрешать или запрещать трафик по направлениям (ingress/egress), по источнику/назначению (pod селекторы, namespace селекторы, CIDR), и по портам/протоколам. По умолчанию, если для пода не существует ни одной политики — весь трафик разрешён.

Базовая семантика и как это работает

  • NetworkPolicy является namespaced: правила управляют доступом к подам в том же namespace, где создана политика.

  • spec.podSelector определяет набор подов (при пустом селекторе {} — все поды namespace). Политика применяется только к подам, выбранным этим селектором (они — «целевые»).

  • Есть два направления правил: ingress (входящий трафик к целевым подам) и egress (исходящий трафик от целевых подов). Политика может содержать одно или оба.

  • Если для пода нет ни одной NetworkPolicy, которая его выбирает, то трафик (ingress и egress) разрешён. Если хотя бы одна NetworkPolicy выбирает под и содержит правила для ingress, то только явно разрешённый этими правилами ingress будет проходить; остальное — блокируется. Аналогично для egress.

  • Если несколько политик выбирают один и тот же под — применяются объединённые (union) разрешения: т.е. если любая политика разрешила соединение — оно разрешено.

Правила (from/to/ports/ipBlock)

  • from / to могут указывать: podSelector, namespaceSelector, ipBlock (CIDR + except).

  • ports указывают номер или имя порта и протокол (TCP|UDP|SCTP). Если порт не указан — разрешается весь портовый диапазон для того направления.

  • ipBlock полезен для внешних подсетей; при использовании ipBlock нельзя одновременно использовать namespaceSelector/podSelector в том же from/to элементе.

  • namespaceSelector позволяет разрешать трафик от/к подам в других namespace (в сочетании с podSelector можно точечно разрешать конкретные pods в других namespaces).

Примеры распространённых политик

  1. Default Deny (запрет входящих соединений ко всем подам в namespace):
kind: NetworkPolicy
spec:
podSelector: {} # все поды
policyTypes: \["Ingress"\]
\# нет ingress правил — всё блокируется
  1. Разрешить HTTP (80) только от подов с label role=frontend:
spec:
podSelector:
matchLabels: { app: backend }
ingress:
\- from:
\- podSelector:
matchLabels: { role: frontend }
ports:
\- port: 80
protocol: TCP
  1. Разрешить egress к внешнему CIDR, кроме некоторых подсетей:
spec:
podSelector: {}
policyTypes: \["Egress"\]
egress:
\- to:
\- ipBlock:
cidr: 0.0.0.0/0
except:
\- 10.0.0.0/8

Важные нюансы и ограничения

  • NetworkPolicy — механизм фильтрации сетевого трафика, а не маршрутизации или NAT. Для работы требуется CNI-плагин, который поддерживает NetworkPolicy; без поддержки — политики игнорируются.

  • Политики работают на уровне pod network interface; трафик, который не проходит через pod сетевой стек (например, трафик с узла, генерируемый процессом на хосте hostNetwork, может обходиться плагином) может не быть полностью контролируем.

  • Для обеспечения двусторонней связи нужно разрешить обе стороны: если у принимающего пода есть ingress-политика, в ней должен быть источник; если отправляющий под ограничен egress-политикой, он также должен иметь разрешение на destination.

  • policyTypes (Ingress/Egress) можно явно указывать; если не указано, Kubernetes делает вывод на основе наличия ingress/egress секций.

  • Правила применяются при планировании и в рантайме; изменения политики вступают в силу динамически (внедряются CNI), но поведение зависит от реализации плагина.

Отладка и практические советы

  • Всегда проверяйте, поддерживает ли ваш CNI NetworkPolicy.

  • Для поэтапного внедрения сначала создавайте default deny и затем добавляйте разрешающие правила по одной, тестируя.

  • Тестируйте с временными debug-pod’ами (curl/nc) внутри namespace и из других namespace, чтобы убедиться в ожидаемой блокировке/разрешении.

  • Учитывайте, что именованные порты должны существовать в контейнере (или быть согласованы с сервисами), иначе сопоставление по имени не сработает.