исходящая сетевая политика k8s не работает для dns

#kubernetes

#kubernetes

Вопрос:

Я добавил эту сетевую политику, чтобы блокировать все выходы, но разрешать DNS.

 apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all-egress
  namespace: {{ $namespace }}
spec:
  podSelector: {}
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          networking/namespace: kube-system
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: TCP
      port: 53
    - protocol: UDP
      port: 53
  policyTypes:
  - Egress
 

Однако я получаю эту ошибку со службой, к которой применяется это правило: Could not lookup srv records on _origintunneld._tcp.argotunnel.com: lookup _origintunneld._tcp.argotunnel.com on 10.2.0.10:53: read udp 10.32.1.179:40784->10.2.0.10:53: i/o timeout

Этот IP-адрес (10.2.0.10) принадлежит службе kube-dns, которая имеет модуль с k8s-app=kube-dns меткой и находится в пространстве имен kube-system с меткой networking/namespace=kube-system .

Если я удалю селектор pod и селектор пространства имен, то политика выхода сработает, и я не получу сообщение об ошибке

Это работает, но небезопасно, поскольку оно не ограничено модулем kube-dns:

 apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all-egress
  namespace: {{ $namespace }}
spec:
  podSelector: {}
  egress:
  - to:
    ports:
    - protocol: TCP
      port: 53
    - protocol: UDP
      port: 53
  policyTypes:
  - Egress
 

kube-системное пространство имен yaml: kubectl get namespace kube-system -o yaml

 apiVersion: v1
kind: Namespace
metadata:
  creationTimestamp: "2020-07-30T22:08:25Z"
  labels:
    networking/namespace: kube-system
  name: kube-system
  resourceVersion: "4084751"
  selfLink: /api/v1/namespaces/kube-system
  uid: b93e68b0-7899-4f39-a3b8-e0e12e4008ee
spec:
  finalizers:
  - kubernetes
status:
  phase: Active
 

Комментарии:

1. Какой cni вы используете?

2. У меня включена сетевая политика в моем кластере gke, поэтому я считаю, что он использует calico

3. Какую версию k8s вы используете? Я попытаюсь ее воспроизвести

4. 1.17.14-gke.400

5. Вы проверили, что kube-system в пространстве имен есть эта метка? kubectl get namespace kube-system -o yaml

Ответ №1:

Я столкнулся с той же проблемой. Для меня это было связано с тем, что в моем кластере был включен NodeLocal DNSCache.

Комментарии:

1. вы удаляете NodeLocal DNSCache или находите другой способ?

Ответ №2:

Текущая политика явно не разрешает трафик для DNS Kubernetes. В результате DNS-запросы из входящих модулей {{ $namespace }} будут отброшены, если это не разрешено другими правилами.

Создание правила разрешения выхода для DNS k8s должно решить вашу проблему.

 apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all-egress
  namespace: {{ $namespace }}
spec:
  podSelector: {}
  policyTypes:
    - Egress
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              networking/namespace: kube-system
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - port: 53
          protocol: TCP
        - port: 53
          protocol: UDP
    - to:
        - namespaceSelector: {}
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - port: 53
          protocol: UDP
 

Комментарии:

1. Это позволило бы только модулям kube-dns выходить на dns. Мне нужно разрешить всем модулям в данном пространстве имен переходить к модулям kube-dns.