How to restrict pod traffic with Kubernetes NetworkPolicies
NetworkPolicies restrict pod traffic by selecting pods and declaring allowed ingress and egress. Start default-deny, add explicit allows, remember DNS, and verify blocked versus permitted connections.
Restricting pod traffic with NetworkPolicies
By default, every pod in a Kubernetes cluster can talk to every other pod. A NetworkPolicy changes that by selecting pods and declaring which traffic is allowed. NetworkPolicies are additive and require a CNI plugin that enforces them, such as Calico or Cilium.
Prerequisites
- A CNI that supports NetworkPolicy enforcement.
- Workloads labeled consistently (for example
app: web,app: api).
Steps
1. Confirm CNI support
Not all network plugins enforce policies. Verify your cluster's CNI documents NetworkPolicy support before relying on it.
2. Label your workloads
Policies select pods by label, so apply clear labels to each Deployment, for example app: api and tier: backend.
3. Apply default-deny ingress
Deny all inbound traffic to a namespace, then open only what is needed:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: app
spec:
podSelector: {}
policyTypes: ["Ingress"]
4. Allow specific ingress
Let the web pods reach the api pods on port 8080:
spec:
podSelector:
matchLabels:
app: api
ingress:
- from:
- podSelector:
matchLabels:
app: web
ports:
- port: 8080
5. Restrict egress
Allow the api pods to reach only the database and DNS:
policyTypes: ["Egress"]
egress:
- to:
- podSelector:
matchLabels:
app: db
ports:
- port: 5432
Remember to also allow DNS (UDP/TCP 53) or name resolution breaks.
6. Test connectivity
kubectl exec deploy/web -- curl -m 3 http://api:8080
kubectl exec deploy/web -- curl -m 3 http://db:5432
The first should succeed; the second should time out.
Verification
From an allowed pod, confirm permitted connections succeed; from a non-selected pod, confirm they are blocked. Removing the allow policy should cause previously working traffic to fail, proving enforcement.
Next Steps
Move toward a zero-trust posture by combining default-deny with explicit allows everywhere, label namespaces for cross-namespace rules, and consider a service mesh for mTLS and identity-aware policy on top of network-level controls.
Prerequisites
- A CNI that enforces NetworkPolicy
- Workloads with clear labels
- kubectl access
Steps
- 1Confirm CNI support
- 2Label your workloads
- 3Apply default-deny ingress
- 4Allow specific ingress
- 5Restrict egress
- 6Test connectivity