Network Policies
Control pod-to-pod traffic with zero-trust networking.
Time: ~15 minutes Difficulty: Intermediate
What You Will Learn
Section titled “What You Will Learn”- Default behavior: all pods can talk to all pods
- deny-all policy: block everything, then whitelist
- Ingress policies: who can send traffic to a pod
- Egress policies: where a pod can send traffic
- Pod selectors and namespace selectors
- Why DNS egress must be explicitly allowed
Prerequisites
Section titled “Prerequisites”Minikube needs a CNI that supports NetworkPolicy. Start with Calico:
minikube start --cpus=4 --memory=8192 --cni=calicoIf your cluster is already running without Calico, you can enable it:
minikube addons enable calicoWithout a CNI that supports NetworkPolicy, the policies will be created but not enforced.
The Scenario
Section titled “The Scenario”Three microservices forming a typical web app:
Frontend ──> Backend ──> DatabaseGoal: lock down traffic so that:
- Frontend can only talk to Backend
- Backend can only talk to Database
- Database accepts traffic only from Backend
- Nothing else is allowed
Step 1: Deploy the Apps
Section titled “Step 1: Deploy the Apps”Navigate to the demo directory:
cd demos/network-policieskubectl apply -f manifests/namespace.yamlkubectl apply -f manifests/apps.yamlVerify all pods are running:
kubectl get pods -n netpol-demoStep 2: Test Default (Allow All)
Section titled “Step 2: Test Default (Allow All)”Before any policies, everything can talk to everything:
# Frontend -> Backend (works)kubectl exec deploy/frontend -n netpol-demo -- wget -qO- --timeout=3 http://backend
# Frontend -> Database (works - but shouldn't)kubectl exec deploy/frontend -n netpol-demo -- wget -qO- --timeout=3 http://database
# Database -> Frontend (works - but shouldn't)kubectl exec deploy/database -n netpol-demo -- wget -qO- --timeout=3 http://frontendStep 3: Apply deny-all
Section titled “Step 3: Apply deny-all”kubectl apply -f manifests/deny-all.yamlNow NOTHING can talk to anything:
# Frontend -> Backend (blocked)kubectl exec deploy/frontend -n netpol-demo -- wget -qO- --timeout=3 http://backend# wget: download timed outStep 4: Allow DNS
Section titled “Step 4: Allow DNS”Without DNS, pods cannot resolve service names. Allow DNS egress for all pods:
kubectl apply -f manifests/allow-dns.yamlDNS resolves now, but HTTP traffic is still blocked:
kubectl exec deploy/frontend -n netpol-demo -- nslookup backend# Works! But...kubectl exec deploy/frontend -n netpol-demo -- wget -qO- --timeout=3 http://backend# Still blocked (only DNS is allowed, not HTTP)Step 5: Allow Frontend to Backend
Section titled “Step 5: Allow Frontend to Backend”kubectl apply -f manifests/allow-frontend-to-backend.yamlkubectl apply -f manifests/allow-frontend-egress.yaml# Frontend -> Backend (works now)kubectl exec deploy/frontend -n netpol-demo -- wget -qO- --timeout=3 http://backend
# Frontend -> Database (still blocked)kubectl exec deploy/frontend -n netpol-demo -- wget -qO- --timeout=3 http://databaseStep 6: Allow Backend to Database
Section titled “Step 6: Allow Backend to Database”kubectl apply -f manifests/allow-backend-to-database.yamlkubectl apply -f manifests/allow-backend-egress.yaml# Backend -> Database (works)kubectl exec deploy/backend -n netpol-demo -- wget -qO- --timeout=3 http://database
# Frontend -> Database (still blocked, only Backend is allowed)kubectl exec deploy/frontend -n netpol-demo -- wget -qO- --timeout=3 http://databaseWhat is Happening
Section titled “What is Happening”manifests/ namespace.yaml # netpol-demo namespace apps.yaml # Frontend, Backend, Database (Deployments + Services) deny-all.yaml # Block all ingress and egress allow-dns.yaml # Allow DNS lookups (UDP/TCP 53) allow-frontend-to-backend.yaml # Backend accepts ingress from frontend allow-frontend-egress.yaml # Frontend can send to backend allow-backend-to-database.yaml # Database accepts ingress from backend allow-backend-egress.yaml # Backend can send to databasePolicy model:
- No policies = allow all (default)
- Any policy on a pod = deny all traffic of that type, except what the policy allows
- Multiple policies are additive (union of all allowed traffic)
Traffic allowed after all policies:
Frontend ──80──> Backend ──80──> Database | | | v v v DNS(53) DNS(53) DNS(53)Everything else is blocked.
Experiment
Section titled “Experiment”-
Try accessing from an unlabeled pod (blocked by deny-all):
Terminal window kubectl run test --rm -it --image=busybox:1.36 -n netpol-demo -- wget -qO- --timeout=3 http://backend -
List all policies:
Terminal window kubectl get networkpolicies -n netpol-demo -
Describe a policy to see the rules:
Terminal window kubectl describe networkpolicy allow-frontend-to-backend -n netpol-demo
Cleanup
Section titled “Cleanup”kubectl delete namespace netpol-demoFurther Reading
Section titled “Further Reading”See docs/deep-dive.md for a detailed explanation of NetworkPolicy internals, namespace selectors, CIDR blocks, named ports, egress to external services, and how different CNIs implement policies.
Next Step
Section titled “Next Step”Move on to Resource Quotas to learn namespace-level resource governance.