Что такое сетевые политики (Network Policies) в Kubernetes и для чего они нужны?

Ответ

Network Policies в Kubernetes — это ресурсы, которые определяют правила входящего (ingress) и исходящего (egress) сетевого трафика для групп подов. Их основная цель — реализация микросервисной сетевой безопасности по принципу "запрещено всё, что не разрешено явно" (zero-trust network model) внутри кластера.

Ключевые моменты:

  • Не являются сетевым плагином. Это декларативная спецификация правил. Для их реализации требуется CNI-плагин, поддерживающий Network Policies (например, Calico, Cilium, Weave Net). Без такого плагина политики создаются, но не применяются.
  • Работают на уровне L3/L4. Можно задавать правила на основе IP-адресов (CIDR), портов (TCP/UDP/SCTP) и селекторов подов/неймспейсов. Для фильтрации на уровне L7 (HTTP, gRPC) нужны дополнительные инструменты, например, сервисная сеть (Istio, Linkerd) или расширенные политики Cilium.
  • Изолируют по умолчанию. Если для пода не задана ни одна Network Policy, он принимает и отправляет любой трафик (поведение по умолчанию зависит от плагина). Как только пода назначается политика, все не разрешенные ею соединения блокируются.

Пример сценария и политики: Допустим, у нас есть frontend (метка app: frontend) и backend (метка app: backend) с базой данных (метка app: db).

  1. Политика для backend: Разрешает входящий трафик только от frontend на порт 8080 и исходящий трафик только к db на порт 5432.
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
    name: backend-allow-frontend
    spec:
    podSelector:
    matchLabels:
      app: backend
    policyTypes:
    - Ingress
    - Egress
    ingress:
    - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080
    egress:
    - to:
    - podSelector:
        matchLabels:
          app: db
    ports:
    - protocol: TCP
      port: 5432
  2. Политика для db: Разрешает входящий трафик только от backend на порт 5432 и запрещает любой другой входящий/исходящий трафик (явный deny-all не требуется, так как политика уже ограничивает доступ).

В своей работе я использовал Calico для реализации таких политик. Это критически важно для compliance (например, PCI DSS) и для минимизации ущерба в случае компрометации одного из компонентов приложения.

Ответ 18+ 🔞

Давай разжую тебе про эти Network Policies, а то у некоторых от одного названия глаза на лоб лезут, как будто это какая-то ядрёна вошь.

Представь себе, что твой Kubernetes-кластер — это общага. И поначалу там полный бардак: все друг к другу в комнаты ходят, кто хочет, когда хочет, чужое пиво хавают. Network Policy — это строгий вахтёр, которого ты нанимаешь и говоришь ему: «Слушай, дружище, вот этим ребятам из 305-й (это наши frontend-поды) разреши ходить только в 404-ю (backend) и только за тем, чтобы стукнуть в дверь 8080. И всё. Больше нихуя».

Важнейший момент, который все просраливают: сам по себе этот вахтёр — просто бумажка с инструкцией. Это НЕ сетевой плагин. Если у тебя в общаге не стоит совместимый замок на дверях (читай: CNI-плагин вроде Calico или Cilium), то твои красивые правила — просто хуй в пальто, они нихера не будут работать. Создашь, а трафик как ходил, так и ходит.

Работают эти политики на базовом уровне: по айпишникам, портам и по наклейкам (лейблам) на подах. Хочешь фильтровать по тому, какие именно HTTP-запросы летят (уровень L7)? Тогда это уже ёперный театр с сервисными сетками (Istio) или продвинутые фичи Cilium. Стандартные политики так низко не опускаются.

Главная их фишка — изоляция по умолчанию. Пока к поду не привязана ни одна политика, он — распиздяй, общается со всеми. Но стоит только назначить ему хотя бы одну — всё, приехали. Всё, что в этой политике не разрешено явно, блокируется нахуй. Всё. Доверия ебать ноль, принцип zero-trust.

Пример из жизни, чтобы не было, как у дурака, махорки: Есть у нас фронтенд (app: frontend), бэкенд (app: backend) и база (app: db).

  1. Политика для бэкенда. Пишем вахтёру: «Пусть к бэкенду заходят только с фронтенда, и только стучать в порт 8080. А сам бэкенд пусть ходит только к базе, стучать в порт 5432. Больше никуда».
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
    name: backend-allow-frontend
    spec:
    podSelector:
    matchLabels:
      app: backend
    policyTypes:
    - Ingress
    - Egress
    ingress:
    - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080
    egress:
    - to:
    - podSelector:
        matchLabels:
          app: db
    ports:
    - protocol: TCP
      port: 5432
  2. Политика для базы. Вторая бумажка: «К базе пусть заходит только бэкенд на порт 5432. И всё. Больше нихуя, даже не дыши в её сторону».

Я, например, для таких дел калиску (Calico) использовал. Штука архиважная, особенно если тебе надо соответствовать всяким строгим стандартам вроде PCI DSS. Это как если в общаге прорвёт трубу в одной комнате — вода только там и останется, а не весь этаж затопит. Минимизация ущерба, ёпта. Без этого — пиши пропало, одна компрометация, и весь кластер пошёл по пизде.