How to Implement Advanced NetworkPolicies
Master advanced Kubernetes NetworkPolicies for fine-grained traffic control. Learn egress rules, CIDR blocks, namespace isolation, and common security patterns.
How to Implement Advanced NetworkPolicies
NetworkPolicies provide fine-grained control over pod network traffic. Learn advanced patterns for securing microservices with ingress and egress rules.
Default Deny All Traffic
# deny-all.yaml - Start with zero trust
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {} # Applies to all pods
policyTypes:
- Ingress
- EgressAllow DNS Egress (Required After Default Deny)
# allow-dns.yaml
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
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53Multi-Tier Application Isolation
# Frontend can receive external traffic
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: frontend-policy
namespace: production
spec:
podSelector:
matchLabels:
tier: frontend
policyTypes:
- Ingress
- Egress
ingress:
# Allow from ingress controller
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ingress-nginx
ports:
- port: 8080
egress:
# Allow to backend only
- to:
- podSelector:
matchLabels:
tier: backend
ports:
- port: 8080
# Allow DNS
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- port: 53
protocol: UDP
---
# Backend can only talk to frontend and database
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-policy
namespace: production
spec:
podSelector:
matchLabels:
tier: backend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
tier: frontend
ports:
- port: 8080
egress:
- to:
- podSelector:
matchLabels:
tier: database
ports:
- port: 5432
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- port: 53
protocol: UDP
---
# Database only accepts from backend
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: database-policy
namespace: production
spec:
podSelector:
matchLabels:
tier: database
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
tier: backend
ports:
- port: 5432
egress: [] # No egress allowedAllow Traffic from Specific Namespaces
# cross-namespace-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-monitoring
namespace: production
spec:
podSelector: {} # All pods in production
policyTypes:
- Ingress
ingress:
# Allow Prometheus scraping from monitoring namespace
- from:
- namespaceSelector:
matchLabels:
name: monitoring
podSelector:
matchLabels:
app: prometheus
ports:
- port: 9090
- port: 8080CIDR-Based Rules for External Services
# external-services-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-external-apis
namespace: production
spec:
podSelector:
matchLabels:
app: api-gateway
policyTypes:
- Egress
egress:
# Allow external payment API
- to:
- ipBlock:
cidr: 203.0.113.0/24 # Payment provider IP range
ports:
- port: 443
# Allow AWS S3 (us-east-1)
- to:
- ipBlock:
cidr: 52.216.0.0/15
ports:
- port: 443
# Block private IPs except internal services
- 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:
- port: 443Namespace Isolation with Exceptions
# namespace-isolation.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: namespace-isolation
namespace: team-a
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
# Allow within same namespace
- from:
- podSelector: {}
# Allow from shared services
- from:
- namespaceSelector:
matchLabels:
shared-services: "true"
egress:
# Allow within same namespace
- to:
- podSelector: {}
# Allow to shared services
- to:
- namespaceSelector:
matchLabels:
shared-services: "true"
# Allow DNS
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- port: 53
protocol: UDPService Mesh Compatible Policy
# istio-compatible-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-istio-mtls
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
ingress:
# Allow Istio sidecar injection
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: istio-system
# Allow mTLS between sidecars
- from:
- podSelector: {}
ports:
- port: 15006 # Istio inbound
- port: 15001 # Istio outbound
- port: 15090 # Envoy stats
egress:
# Allow to Istio control plane
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: istio-system
ports:
- port: 15012 # istiod
- port: 443Audit and Test Policies
# test-pod.yaml - For testing connectivity
apiVersion: v1
kind: Pod
metadata:
name: netpol-test
namespace: production
labels:
tier: frontend
spec:
containers:
- name: test
image: nicolaka/netshoot:latest
command: ["sleep", "infinity"]# Test connectivity
kubectl exec -it netpol-test -n production -- sh
# Test DNS
nslookup kubernetes.default
# Test pod connectivity
curl -v backend-service:8080/health
# Test external connectivity
curl -v https://api.example.com
# Scan for open ports
nc -zv backend-pod 8080Complex Label Selectors
# complex-selectors.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: complex-selector
namespace: production
spec:
podSelector:
matchLabels:
app: api
matchExpressions:
- key: environment
operator: In
values: ["production", "staging"]
- key: team
operator: NotIn
values: ["deprecated"]
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchExpressions:
- key: role
operator: In
values: ["frontend", "worker"]Logging Denied Connections (CNI Dependent)
# With Calico CNI - Enable logging
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
name: log-denied
namespace: production
spec:
selector: app == 'sensitive-app'
types:
- Ingress
ingress:
- action: Log
- action: DenyVerify Policies
# List all policies
kubectl get networkpolicies -A
# Describe policy
kubectl describe networkpolicy frontend-policy -n production
# Check if CNI supports NetworkPolicy
kubectl get pods -n kube-system | grep -E "calico|cilium|weave"
# Visualize policies (requires kubectl plugin)
kubectl neat get networkpolicy -n production -o yamlSummary
Advanced NetworkPolicies enable zero-trust networking in Kubernetes. Start with default deny, then explicitly allow required traffic. Combine pod selectors, namespace selectors, and CIDR blocks for comprehensive security. Always test policies before applying to production.
📘 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.