Как разрешить доступ к kubernetes api с помощью политики исходящей сети?

Контейнер init с kubectl get pod используется для получения статуса готовности другого модуля.

После включения Egress NetworkPolicy контейнер init не может получить доступ к API Kubernetes: невозможно Unable to connect to the server: dial tcp 10.96.0.1:443: i/o timeout. CNI это Калико.

Было опробовано несколько правил, но ни одно из них не работает (IP-адреса хоста службы и главного хоста, разные маски CIDR):

...
  egress:
  - to:
    - ipBlock:
        cidr: 10.96.0.1/32
    ports:
    - protocol: TCP
      port: 443
...

или используя пространство имен (пространства имен по умолчанию и пространства имен kube-system):

...
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: default
    ports:
    - protocol: TCP
      port: 443
...

Похоже, что правила ipBlock просто не работают, а правила пространства имен не работают, потому что kubernetes api - это нестандартный модуль.

Это можно настроить? Кубернетес 1.9.5, Калико 3.1.1.

Проблема все еще существует с GKE 1.13.7-gke.8 и ситцем 3.2.7

Ответ 1

Внутренний обходной путь, который я мог придумать, заключается в следующем:

  podSelector:
    matchLabels:
      white: listed
  egress:
    - to:
        - ipBlock:
            cidr: 0.0.0.0/0

Это позволит получить доступ к серверу API - вместе со всеми другими IP-адресами в Интернете: -/

Вы можете объединить это с DENY для всего трафика, не занесенного в белый список, из правила пространства имен, чтобы запретить выход для всех других модулей.

Ответ 2

Вам нужно получить реальный IP-адрес мастера, используя "kubectl get endpoints --namespace default kubernetes" и создать выходную политику, чтобы разрешить это.

---
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1 
metadata:
  name: allow-apiserver
  namespace: test
spec:
  policyTypes:
  - Egress
  podSelector: {}
  egress:
  - ports:
    - port: 443
      protocol: TCP
    to:
    - ipBlock:
        cidr: x.x.x.x/32