KubernetesMiddleTechnical

Что такое 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

Sources

Related topics