How Do You Create a Default-Deny Network Policy?
A default-deny Network Policy selects all Pods in a namespace (podSelector: {}) and specifies Ingress and/or Egress policy types with no allow rules. This blocks all traffic by default, forcing you to create explicit allow policies for legitimate communication.
Detailed Answer
A default-deny Network Policy is the foundation of secure Kubernetes networking. It blocks all traffic to and from Pods in a namespace, requiring explicit allow rules for every communication path.
Deny All Ingress
Block all incoming traffic to Pods in a namespace:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
namespace: production
spec:
podSelector: {} # Applies to ALL Pods in this namespace
policyTypes:
- Ingress # No ingress rules = deny all incoming traffic
Deny All Egress
Block all outgoing traffic from Pods in a namespace:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-egress
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress # No egress rules = deny all outgoing traffic
Deny All Ingress and Egress
The most restrictive starting point — block everything:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
After Default-Deny: Allow DNS
Egress deny breaks DNS resolution, which breaks almost everything. Always allow DNS:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
After Default-Deny: Allow Specific Traffic
With default-deny in place, add explicit allow rules for each communication path:
# Allow frontend to reach the API
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-api
namespace: production
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
---
# Allow API to reach the database
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-api-to-db
namespace: production
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432
Complete Default-Deny Setup
A typical production namespace setup:
# 1. Deny all traffic
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
# 2. Allow DNS for all Pods
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
---
# 3. Allow ingress from the Ingress controller
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-controller
namespace: production
spec:
podSelector:
matchLabels:
exposed: "true"
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ingress-nginx
ports:
- protocol: TCP
port: 8080
Testing Default-Deny
# Deploy a test Pod
kubectl run test-pod --image=busybox --rm -it -n production -- sh
# Test DNS (should work after DNS allow policy)
nslookup api-service
# Test connectivity to a Service (should fail without allow policy)
wget -qO- --timeout=5 http://api-service:8080
# wget: download timed out
# After adding allow policy, test again (should succeed)
wget -qO- --timeout=5 http://api-service:8080
# {"status": "ok"}
Common Mistake: Forgetting DNS
The most common issue after applying default-deny egress is that DNS stops working. Symptoms include:
- Pods cannot resolve Service names
- Applications fail with "name resolution failed" errors
- Direct IP connections work but DNS-based connections fail
Always create the DNS allow policy immediately after the default-deny policy.
Why Interviewers Ask This
Interviewers ask this because default-deny is the foundation of zero-trust networking in Kubernetes. It is a CKA/CKAD exam topic and a production security requirement.
Common Follow-Up Questions
Key Takeaways
- Default-deny is the starting point for Kubernetes network security — apply it to every namespace.
- After applying default-deny, you must explicitly allow DNS, inter-service communication, and external access.
- An empty podSelector ({}) targets all Pods in the namespace.