By default, Kubernetes allows all pods to communicate with all other pods — Network Policies let you restrict this, implementing genuine network-level segmentation within your cluster. This guide covers setting them up.
Why Default Kubernetes Networking Is Too Permissive for Production
Without Network Policies, a compromised pod can potentially reach any other pod in the cluster — similar concern to How to Set Up Network Segmentation on a Single VPS but at the Kubernetes pod level; production clusters generally warrant deliberate network segmentation rather than relying on default open connectivity.
Prerequisite: A CNI Plugin That Supports Network Policies
Not every Kubernetes network plugin (CNI) enforces Network Policies — verify your cluster's CNI (Calico, Cilium, and several others support this; some simpler CNIs don't) actually implements policy enforcement, since defining policies with a non-enforcing CNI silently does nothing.
Basic Default-Deny Policy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
An empty podSelector matches all pods in the namespace; with no explicit ingress rules, this denies all incoming traffic by default — the recommended starting point, then adding specific allow rules as needed.
Allowing Traffic from a Specific Pod Selector
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- port: 8080
Explicitly allows only pods labeled app: frontend to reach pods labeled app: backend on port 8080 — everything else remains denied by the default-deny policy.
Allowing Traffic from a Specific Namespace
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoring
Useful for allowing cross-namespace access (a monitoring namespace scraping metrics from application namespaces, for example) while still restricting general pod-to-pod traffic within and across namespaces.
Restricting Egress Traffic Too
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- port: 5432
Beyond controlling what can reach a pod (ingress), you can also restrict what a pod itself can reach (egress) — limits the blast radius if a specific pod is compromised, preventing it from reaching arbitrary other services.
Testing Network Policies
kubectl run test-pod --image=busybox -it --rm -- wget -O- http://backend-service:8080
Verify policies actually behave as expected — confirm both that intended traffic works and unintended traffic is genuinely blocked, rather than assuming configuration correctness without testing.
Combining with Kubernetes RBAC
See How to Set Up RBAC (Role-Based Access Control) in Kubernetes — Network Policies control pod-to-pod traffic; RBAC controls who can manage cluster resources; both are complementary layers of a comprehensive Kubernetes security posture, addressing different threat vectors.
Starting Simple and Expanding
Begin with default-deny plus specific allow rules for your genuinely necessary traffic patterns, rather than attempting comprehensive policy coverage all at once — expand incrementally as you understand your application's actual required communication patterns.
Common Errors
Network Policy defined but traffic still flows unrestricted — almost always indicates your CNI plugin doesn't actually enforce Network Policies; verify your specific CNI's policy enforcement capability before assuming your policy definitions are the issue.
Continue Reading
- Kubernetes Namespaces and Resource Quotas Explained
- How to Set Up RBAC (Role-Based Access Control) in Kubernetes
- How to Troubleshoot Kubernetes Networking Issues
Browse more articles in Kubernetes & Container Orchestration.