Что такое NetworkPolicy и что произойдёт, если её не задать вообще?
NetworkPolicy задаёт L3/L4 allow-list правила для входящего и исходящего трафика Pod. Без политик весь трафик разрешён; как только Pod выбран хотя бы одной политикой — разрешён только явно перечисленный трафик. Реальную фильтрацию реализует CNI-плагин.
Что такое NetworkPolicy
NetworkPolicy — это Kubernetes-объект, описывающий правила L3/L4 фильтрации трафика для Pod. По умолчанию модель сети Kubernetes полностью открытая: любой Pod может общаться с любым другим Pod в кластере независимо от namespace. NetworkPolicy позволяет перейти к модели allow-list для выбранных Pod.
Важная оговорка: NetworkPolicy — это декларативный API. Реальную фильтрацию реализует CNI-плагин. Если CNI не поддерживает NetworkPolicy (например, Flannel без дополнений), объект сохранится в etcd, но никакой фильтрации не произойдёт. NetworkPolicy поддерживают: Calico, Cilium, Weave Net, Canal, Azure CNI.
Как работает selectiveизоляция
NetworkPolicy применяется к Pod через podSelector. Если Pod не выбран ни одной политикой — весь трафик разрешён (как было до политик). Как только хотя бы одна NetworkPolicy выбрала Pod через podSelector:
- Для Ingress: разрешён только трафик, явно перечисленный в
ingressблоках всех подходящих политик. Остальной входящий трафик отброшен. - Для Egress: аналогично — разрешён только трафик из
egressблоков. Всё остальное блокируется.
Default-deny политика
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {} # выбирает ВСЕ Pod в namespace
policyTypes:
- Ingress
- Egress
# нет правил ingress и egress — значит всё блокируется
# кроме egress DNS (добавим отдельной политикой)
Разрешить DNS и конкретный трафик
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns-egress
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-api
namespace: production
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
Изоляция между namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-monitoring
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: monitoring
ports:
- protocol: TCP
port: 9090
Разрешить доступ к внешнему IP (ipBlock)
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/8
except:
- 10.100.0.0/16 # исключить диапазон другого tenant
ports:
- protocol: TCP
port: 5432
Что произойдёт без NetworkPolicy
Без каких-либо NetworkPolicy в namespace трафик полностью открыт. Pod базы данных доступен с любого Pod в кластере. Pod одного микросервиса может открыть соединение к Redis другого микросервиса. Компрометация одного Pod даёт lateral movement по всему кластеру.
Подводные камни
- Применить NetworkPolicy с policyTypes Ingress и не добавить Egress — исходящий трафик Pod остаётся открытым, в том числе возможность эксфильтрации данных.
- Забыть DNS egress после default-deny: приложение не сможет резолвить имена сервисов, контейнеры начнут падать с ошибками типа
dial tcp: lookup postgres on 10.96.0.10:53: read udp: i/o timeout. - Использовать только podSelector без namespaceSelector: если label
app=frontendсуществует в нескольких namespace, правило разрешит трафик из всех них, а не только из нужного. - Не проверять поддержку CNI: в кластерах с Flannel без Canal NetworkPolicy молча не работает — трафик будет проходить несмотря на политики.
- Не учитывать трафик от node к Pod: некоторые health-check и node-local агенты (например, Prometheus node-exporter) ходят напрямую с IP ноды, не через Pod. Их нужно разрешать через ipBlock с CIDR нод.
- Политики не применяются к hostNetwork Pod: если Pod запущен с hostNetwork: true, он использует сеть ноды и обходит NetworkPolicy.
- Отсутствие default-deny в namespace kube-system приводит к тому, что DNS, metrics-server и другие компоненты остаются открытыми для всех Pod кластера.
Common mistakes
- Считать, что policy глобально закрывает весь namespace
- Не знать про CNI requirement
- Ломать DNS egress
What the interviewer is testing
- Понимает default allow
- Объясняет additive allow-list
- Знает ingress и egress policyTypes