Kubernetes network policies: default-deny, keep DNS up
Lock down pod-to-pod traffic with a default-deny NetworkPolicy, then re-allow DNS and the flows your apps actually need.
Every pod in a default Kubernetes cluster can talk to every other pod, in every namespace. That flat network is convenient during development and exactly what an attacker wants after a single compromised workload. NetworkPolicy is the cluster firewall — but it is inert until your CNI enforces it. Calico, Cilium, and most managed CNIs do; Flannel alone does not. The production pattern is default-deny, then allow: lock the namespace, immediately restore DNS, then open only the flows your architecture actually needs.
The walkthrough below applies a deny-all policy to a shop namespace, re-allows UDP/TCP 53 to CoreDNS, and permits web → db on 5432 — nothing else. If you are still getting comfortable with Services and pod labels, the Kubernetes administration track covers the networking primitives this builds on.
Web reaches payments. Reporting and the public internet stop at the policy boundary. DNS egress to CoreDNS stays open.
Skip DNS and every pod hangs on name resolution. Skip negative testing and you only know the happy path works.
Confirm your CNI actually enforces policy
Before writing a single manifest, verify enforcement. Apply a deny-all policy to a test namespace and confirm cross-pod traffic stops. If traffic still flows, your CNI is not enforcing — adding more YAML will not help.
kubectl exec -n shop web-0 -- curl -s --max-time 3 db:5432(connected) — any pod can reach any podkubectl get networkpolicy -n shopNo resources found in shop namespace.convenient for you, and exactly what an attacker wantsStep 1: default-deny the namespace
This policy selects every pod with podSelector: {} and allows no ingress or egress. Apply it and the namespace goes dark — including DNS lookups, which is the trap almost every team hits first.
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:name: default-denynamespace: shopspec:podSelector: {}policyTypes: [Ingress, Egress]
Step 2: allow DNS back
CoreDNS lives in kube-system with the label k8s-app: kube-dns. Allow egress to that pod on both UDP and TCP port 53 — some resolvers fall back to TCP when responses are large.
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:name: allow-dnsnamespace: shopspec:podSelector: {}policyTypes: [Egress]egress:- to:- namespaceSelector: {}podSelector:matchLabels: { k8s-app: kube-dns }ports:- { protocol: UDP, port: 53 }- { protocol: TCP, port: 53 }
Step 3: allow only the flows you need
NetworkPolicy is additive: multiple policies union their allowed rules. Now open the specific path — web pods may reach db on 5432, and nothing else may ingress to db. Remember that policies filter by pod labels, not Service names — the selector must match the pod template labels on your Deployment.
For egress from web to db, you may also need an egress rule on the web pods if default-deny is in effect, because both ingress on the destination and egress on the source must permit the flow. Many teams forget the egress half and wonder why the connection still times out.
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:name: web-to-dbnamespace: shopspec:podSelector:matchLabels: { app: db }policyTypes: [Ingress]ingress:- from:- podSelector:matchLabels: { app: web }ports:- { protocol: TCP, port: 5432 }
Verify the denied path, not just the allowed one
A policy that passes the happy-path curl but never tests the negative case is a policy nobody trusts. Spin up a pod without the app: web label and confirm the connection times out.
kubectl exec -n shop web-0 -- curl -s --max-time 3 db:5432web -> db:5432 OKkubectl exec -n shop test-0 -- curl -s --max-time 3 db:5432timed out — denied, as intendedWhere this goes next
NetworkPolicy stops lateral movement inside the cluster. Pair it with RBAC so compromised service accounts cannot read every Secret, and with Pod Security so workloads cannot run as root. The Kubernetes security (CKS) path covers network policy, admission, and runtime guards together.
Go deeper in a courseKubernetes security (CKS-aligned)NetworkPolicy, RBAC, Pod Security and runtime hardening in one track.View course