Как внести исходящий трафик в белый список с помощью NetworkPolicy, которая не препятствует запуску Apache Ignite?

Как внести исходящий трафик в белый список с помощью NetworkPolicy, которая не препятствует запуску Apache Ignite?

У меня есть более или менее сложная архитектура микросервисов, где Apache Ignite используется как база данных без сохранения состояния / кэш. Ignite Pod— единственный Podв своем роде Namespace, и архитектура должна пройти аудит безопасности, который она не пройдет, если я не применю максимально NetworkPolicyвозможные ограничения для egressтрафика. Она должна ограничить весь возможный трафик, который не нужен самому Ignite.

Сначала я подумал:Отлично, Ignite не перенаправляет трафик в другие Podмодули (в них нет других модулей Namespace), так что это можно будет легко сделать, ограничив весь egressтрафик в модуле, Namespaceв котором Ignite — единственный модуль Pod!...

Ну, на самом деле это не сработало:
любое egressправило, даже если я разрешу трафик на все порты, упомянутые в документации Ignite, приведет к сбою запуска с IgniteSpiExceptionсообщением:Не удалось получить IP-адреса модулей Ignite., Caused by: java.net.ConnectException: Operation timed out (Connection timed out).

Проблема, похоже, в том,TcpDiscoveryKubernetsIpFinder, особенно метод getRegisteredAddresses(...), который, очевидно, делает некоторый исходящий трафик внутри Namespaceдля регистрации IP-адресов узлов Ignite. Порт обнаружения 47500, конечно, разрешен, но это не меняет ситуацию. Функциональность Ignite с другими Pods из других Namespaces работает без egressприменения правил, что означает (для меня), что конфигурация, касающаяся ClusterRole, ClusterRoleBinding, a Serviceв Namespaceи конфигурация xml самого Ignite и т. д., кажется правильной. Даже ingressправила, ограничивающие трафик из других пространств имен, работают так, как и ожидалось, разрешая именно желаемый трафик.

Вот какие политики я применил:

[РАБОТАЕТ, блокирует только нежелательный трафик]:

## Denies all Ingress traffic to all Pods in the Namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress-in-cache-ns
  namespace: cache-ns
spec:
  # selecting nothing here will deny all traffic between pods in the namespace
  podSelector:
    matchLabels: {}
  # traffic routes to be considered, here: incoming exclusively
  policyTypes:
    - Ingress
## Allows necessary ingress traffic
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: netpol-cache-ns
  namespace: cache-ns
# defines the pod(s) that this policy is targeting
spec:
  policyTypes:
    - Ingress
  podSelector:
    matchLabels:
      app: ignite
  # <----incoming traffic----
  ingress:
    - from:
      - namespaceSelector:
          matchLabels:
            zone: somewhere-else
        podSelector:
          matchExpressions:
            - key: app
              operator: In
              values: [some-pod, another-pod]  # dummy names, these Pods don't matter at all
      ports:
        - port: 11211   # JDBC
          protocol: TCP
        - port: 47100   # SPI communication
          protocol: TCP
        - port: 47500   # SPI discovery (CRITICAL, most likely...)
          protocol: TCP
        - port: 10800   # SQL
          protocol: TCP
# ----outgoing traffic---->
# NONE AT ALL

При применении этих двух правил все работает нормально, но аудит безопасности выдаст что-то вроде
Где ограничения для egress? Что, если этот узел будет взломан через разрешенные маршруты, потому что один из Pod, использующих эти маршруты, был взломан ранее? Тогда он может вызвать сервер C&C! Эта конфигурация не будет разрешена, укрепите свою архитектуру!

[БЛОКИРОВКА желаемого/необходимого трафика]:

Обычно запрещает весь трафик...

## Denies all traffic to all Pods in the Namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-traffic-in-cache-ns
  namespace: cache-ns
spec:
  # selecting nothing here will deny all traffic between pods in the namespace
  podSelector:
    matchLabels: {}
  # traffic routes to be considered, here: incoming exclusively
  policyTypes:
    - Ingress
    - Egress   # <------ THIS IS THE DIFFERENCE TO THE WORKING ONE ABOVE

... и впоследствии разрешить определенные маршруты

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: netpol-cache-ns-egress
  namespace: cache-ns
# defines the pod(s) that this policy is targeting
spec:
  policyTypes:
    - Egress
  podSelector:
    matchLabels:
      app: ignite
  ----outgoing traffic---->
  egress:
    # [NOT SUFFICIENT]
    # allow egress to this namespace at specific ports
    - to:
      - namespaceSelector:
          matchLabels:
            zone: cache-zone
      ports:
        - protocol: TCP
          port: 10800
        - protocol: TCP
          port: 47100   # SPI communication
        - protocol: TCP
          port: 47500
    # [NOT SUFFICIENT]
    # allow dns resolution in general (no namespace or pod restriction)
    - ports:
      - protocol: TCP
        port: 53
      - protocol: UDP
        port: 53
    # [NOT SUFFICIENT]
    # allow egress to the kube-system (label is present!)
    - to:
      - namespaceSelector:
          matchLabels:
            zone: kube-system
    # [NOT SUFFICIENT]
    # allow egress in this namespace and for the ignite pod
    - to:
      - namespaceSelector:
          matchLabels:
            zone: cache-zone
        podSelector:
          matchLabels:
            app: ignite
    # [NOT SUFFICIENT]
    # allow traffic to the IP address of the ignite pod
    - to:
      - ipBlock:
          cidr: 172.21.70.49/32  # won't work well since those addresses are dynamic
      ports:
        - port: 11211   # JDBC
          protocol: TCP
        - port: 47100   # SPI communication
          protocol: TCP
        - port: 47500   # SPI discovery (CRITICAL, most likely...)
          protocol: TCP
        - port: 49112   # JMX
          protocol: TCP
        - port: 10800   # SQL
          protocol: TCP
        - port: 8080    # REST
          protocol: TCP
        - port: 10900   # thin clients
          protocol: TCP

Используемая версия Apache Ignite — 2.10.0.

Теперь вопрос ко всем читателям:

Как я могу ограничить Egressдо абсолютного минимума внутри, Namespaceчтобы Ignite запустился и работал правильно? Будет ли достаточно просто запретить Egressза пределами кластера?

Если вам нужны еще какие-либо yamls для обоснованной догадки или подсказки, пожалуйста, не стесняйтесь запрашивать их в комментарии.
И извините за тегирование, если оно кажется неуместным, я не смог найти тег, kubernetes-networkpolicyтак как он присутствует на stackoverflow.

ОБНОВЛЯТЬ:

Выполнение nslookup -debug kubernetes.default.svc.cluster.localизнутри модуля Ignite без каких-либо политик, ограничивающих egressшоу

BusyBox v1.29.3 (2019-01-24 07:45:07 UTC) multi-call binary.

Usage: nslookup HOST [DNS_SERVER]

Query DNS about HOST

Как только NetworkPolicyприменяется (любой) параметр, ограничивающий Egressопределенные порты, модули и пространства имен, модуль Ignite отказывается запускаться, и поиск kubernetes.default.svc.cluster.localбольше не выполняется.

Egressк DNS разрешен (UDP 53 к k8s-app: kube-dns) ⇒ поиск IP по-прежнему невозможен

Связанный контент