Gymterview
middle

Что такое NetworkPolicy в Kubernetes?

NetworkPolicy — ресурс Kubernetes, позволяющий контролировать сетевой трафик между подами на уровне IP-адресов и портов. По умолчанию в Kubernetes все поды могут обмениваться трафиком друг с другом — NetworkPolicy ограничивает это поведение.

Аналогия: NetworkPolicy — это пропускная система на проходной. Без неё (по умолчанию) все двери открыты. Как только появляется хотя бы одна политика, начинает действовать принцип «вход только по пропускам».

NetworkPolicy работает только если в кластере установлен сетевой плагин (CNI), поддерживающий политики: Calico, Cilium, Weave Net. Стандартный Flannel политики не поддерживает.

Типы политик

  • Ingress — контроль входящего трафика к подам
  • Egress — контроль исходящего трафика от подов

Пример: изоляция пространства имён

Пример
# Запретить весь входящий трафик в namespace payment
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
  namespace: payment
spec:
  podSelector: {}       # Применяется ко всем подам в namespace
  policyTypes:
    - Ingress            # Запрещаем весь входящий трафик

Пример: разрешить трафик только от конкретного сервиса

YAML-манифест NetworkPolicy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-gateway
  namespace: payment
spec:
  podSelector:
    matchLabels:
      app: payment-service
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              name: gateway
          podSelector:
            matchLabels:
              app: api-gateway
      ports:
        - protocol: TCP
          port: 8080

Пример: ограничение исходящего трафика

Egress NetworkPolicy
# payment-service может обращаться только к PostgreSQL и Kafka
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: payment-egress
  namespace: payment
spec:
  podSelector:
    matchLabels:
      app: payment-service
  policyTypes:
    - Egress
  egress:
    - to:
        - podSelector:
            matchLabels:
              app: postgresql
      ports:
        - protocol: TCP
          port: 5432
    - to:
        - podSelector:
            matchLabels:
              app: kafka
      ports:
        - protocol: TCP
          port: 9092
    # Разрешить DNS
    - to: []
      ports:
        - protocol: UDP
          port: 53
        - protocol: TCP
          port: 53

Полная изоляция с точечными разрешениями (банковский подход)

Deny-all + allow-specific
# 1. Запретить ВСЁ
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
  namespace: payment
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress
---
# 2. Разрешить только необходимое
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-specific
  namespace: payment
spec:
  podSelector:
    matchLabels:
      app: payment-service
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              name: gateway
      ports:
        - port: 8080
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              name: data
          podSelector:
            matchLabels:
              app: postgresql
      ports:
        - port: 5432

Принцип: «deny all, allow explicit» — запрещено всё, что явно не разрешено.

На собеседовании: интервьюер хочет услышать про принцип deny-all по умолчанию, разницу между Ingress и Egress, и важность не забывать про DNS (port 53) в egress-правилах. Частая ошибка — забыть разрешить DNS и удивляться, почему сервис не может резолвить имена.