NetworkPolicy: Default Deny All Traffic
Implement a zero-trust network security model in Kubernetes by creating a default deny-all NetworkPolicy. Learn how to block all ingress and egress traffic and selectively allow what you need.
💡 Quick Answer: Create a zero-trust baseline with
podSelector: {}(selects all pods) and bothpolicyTypes: [Ingress, Egress]with no rules—this blocks all traffic. Then add specific allow policies. Always include a DNS egress allow policy after default-deny.Key config: Empty
podSelector+ empty rules = deny all for that direction.Gotcha: After default-deny, pods can’t resolve DNS—immediately add:
egress: [{to: [{namespaceSelector: {matchLabels: {kubernetes.io/metadata.name: kube-system}}}], ports: [{port: 53, protocol: UDP}]}].
The Problem
By default, Kubernetes allows all pods to communicate with each other without restrictions. This violates the principle of least privilege and can be a security risk.
The Solution
Create a default deny-all NetworkPolicy in each namespace, then explicitly allow only the traffic you need.
Step 1: Verify NetworkPolicy Support
First, check if your cluster’s CNI supports NetworkPolicies:
# Check the CNI being used
kubectl get pods -n kube-system | grep -E "calico|cilium|weave"Note: Some CNIs like Flannel do NOT support NetworkPolicies. Consider using Calico or Cilium.
Step 2: Create Default Deny-All Policy
This policy denies all ingress AND egress traffic for pods in the namespace:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: my-namespace
spec:
podSelector: {} # Applies to all pods in namespace
policyTypes:
- Ingress
- EgressApply it:
kubectl apply -f default-deny-all.yamlStep 3: Allow Specific Traffic
Now create policies to allow only necessary traffic.
Allow DNS (Required)
Pods need to reach CoreDNS for name resolution:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: my-namespace
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53Allow Traffic Between Specific Pods
Allow frontend pods to reach backend pods:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: my-namespace
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080Allow External Egress
Allow pods to reach external services:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-external-egress
namespace: my-namespace
spec:
podSelector:
matchLabels:
app: api-gateway
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
ports:
- protocol: TCP
port: 443Testing NetworkPolicies
Deploy Test Pods
# Create a test namespace
kubectl create namespace netpol-test
# Deploy test pods
kubectl run client --image=busybox -n netpol-test -- sleep 3600
kubectl run server --image=nginx -n netpol-test
kubectl expose pod server --port=80 -n netpol-testTest Connectivity Before Policy
kubectl exec -n netpol-test client -- wget -qO- --timeout=2 http://server
# Should return nginx welcome pageApply Deny-All and Test Again
# Apply default deny
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: netpol-test
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
EOF
# Test again - should timeout
kubectl exec -n netpol-test client -- wget -qO- --timeout=2 http://server
# wget: download timed outCommon Issues
Pods can’t resolve DNS
You forgot to allow DNS egress. Apply the “allow-dns” policy.
Policy not being enforced
Check if your CNI supports NetworkPolicies:
# Create a test policy and verify
kubectl describe networkpolicy default-deny-all -n my-namespaceNeed to allow traffic from Ingress Controller
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-controller
namespace: my-namespace
spec:
podSelector:
matchLabels:
app: my-web-app
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ingress-nginxComplete Example
Here’s a complete setup for a typical 3-tier application:
---
# 1. Default deny all
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: my-app
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
# 2. Allow DNS for all pods
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: my-app
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
---
# 3. Allow ingress to frontend from ingress controller
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-to-frontend
namespace: my-app
spec:
podSelector:
matchLabels:
tier: frontend
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ingress-nginx
---
# 4. Allow frontend to backend
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: my-app
spec:
podSelector:
matchLabels:
tier: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
tier: frontend
ports:
- protocol: TCP
port: 8080
---
# 5. Allow backend to database
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-backend-to-database
namespace: my-app
spec:
podSelector:
matchLabels:
tier: database
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
tier: backend
ports:
- protocol: TCP
port: 5432Summary
You’ve learned how to:
- Create a default deny-all NetworkPolicy
- Allow DNS resolution for pods
- Allow specific pod-to-pod communication
- Test NetworkPolicy enforcement
Always start with deny-all and add allow rules incrementally.
References
📘 Go Further with Kubernetes Recipes
Love this recipe? There’s so much more! This is just one of 100+ hands-on recipes in our comprehensive Kubernetes Recipes book.
Inside the book, you’ll master:
- ✅ Production-ready deployment strategies
- ✅ Advanced networking and security patterns
- ✅ Observability, monitoring, and troubleshooting
- ✅ Real-world best practices from industry experts
“The practical, recipe-based approach made complex Kubernetes concepts finally click for me.”
👉 Get Your Copy Now — Start building production-grade Kubernetes skills today!
📘 Get All 100+ Recipes in One Book
Stop searching — get every production-ready pattern with detailed explanations, best practices, and copy-paste YAML.
Want More Kubernetes Recipes?
This recipe is from Kubernetes Recipes, our 750-page practical guide with hundreds of production-ready patterns.