Kubernetes NetworkPolicies Blocking DNS
Asked Answered
T

2

5

I have an AKS cluster (Azure CNI) which I'm trying to implement NetworkPolicies on. I've created the network policy which is

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: myserver
spec:
  podSelector:
    matchLabels:
      service: my-server
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          service: myotherserver
    - podSelector:
        matchLabels:
          service: gateway
    - podSelector:
        matchLabels:
          service: yetanotherserver
    ports:
     - port: 8080
       protocol: TCP
  egress:
    - to:
      ports:
       - port: 53
         protocol: UDP
       - port: 53
         protocol: TCP
       - port: 5432
         protocol: TCP
       - port: 8080
         protocol: TCP

but when I apply the policy I'm seeing recurring messages that the host name cannot be resolved. I've installed dnsutils on the myserver pod; and can see the DNS requests are timing out; and I've also tried installing tcpdump on the same pod; and I can see requests going from myserver to kube-dns. I'm not seeing any responses coming back.

If I delete the networkpolicy DNS comes straight back; so I'm certain there's an issue with my networkpolicy but can't find a way to allow the DNS traffic. If anyone can shed any light on where I'm going wrong it would be greatly appreciated!

Thirion answered 23/12, 2020 at 12:50 Comment(0)
B
10

Solution which does not require a name label to the target namespace. It's necessary to define a namespaceSelector as well as a podSelector. The default namespaceSelector will target the pod's own namespace.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns-access
  namespace: <your-namespacename>
spec:
  podSelector:
    matchLabels: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: UDP
      port: 53

EDIT: Changed namespaceSelector to only target kube-system namespace based on the kubernetes.io/metadata.name label. This assumes you have automatic labeling enabled. https://kubernetes.io/docs/concepts/overview/_print/#automatic-labelling

If you don't have this feature enabled, the next best thing is to define an allow-all namespaceSelector along with the podSelector.

Botany answered 15/2, 2022 at 13:56 Comment(2)
making such open access for egress is not suitable it would be great if we limit egress traffic to kube-system namespace only that actually improve your solutionHazelwood
I changed my answer @MansurUlHasanBotany
T
6

To avoid duplication create a separate network policy for opening up DNS traffic. First we label the kube-system namespace. Then allow DNS traffic from all pod to kube-system namespace.

kubectl label namespace kube-system name=kube-system

kubectl create -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns-access
  namespace: <your-namespacename>
spec:
  podSelector:
    matchLabels: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: kube-system
    ports:
    - protocol: UDP
      port: 53

EOF
Trantham answered 23/12, 2020 at 13:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.