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!
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
.
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