Skip to main content

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.

Difficulty
Advanced
Duration
40 minutes
Steps
6

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

  • 1
    Confirm CNI support
  • 2
    Label your workloads
  • 3
    Apply default-deny ingress
  • 4
    Allow specific ingress
  • 5
    Restrict egress
  • 6
    Test connectivity

Category

Security