DEV Community

Citadel Cloud Management
Citadel Cloud Management

Posted on • Originally published at citadelcloudmanagement.com

Writing Kubernetes NetworkPolicies That Actually Work

NetworkPolicies are the most under-used security feature in Kubernetes. Most clusters I audit have zero network segmentation -- every pod can talk to every other pod. Here is how to fix that.

Step 1: Default Deny Everything

Apply this to every namespace before writing any allow rules:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress
Enter fullscreen mode Exit fullscreen mode

This blocks ALL traffic to and from every pod in the namespace. Yes, your application will break. That is the point -- now you explicitly allowlist only the traffic that should exist.

Step 2: Allow DNS (Critical)

Without DNS egress, nothing works. Apply this immediately after the default deny:

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
      ports:
        - protocol: UDP
          port: 53
        - protocol: TCP
          port: 53
Enter fullscreen mode Exit fullscreen mode

Step 3: Allow Specific Service-to-Service Traffic

Example: allowing a frontend to talk to an API backend:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-api
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api-backend
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
      ports:
        - protocol: TCP
          port: 8080
Enter fullscreen mode Exit fullscreen mode

Common Mistakes

  1. Forgetting DNS egress. Your pods need to resolve service names. Without the DNS egress rule, every network call hangs indefinitely.

  2. Using namespaceSelector: {} (empty selector). This matches ALL namespaces, which defeats the purpose. Always use specific label selectors.

  3. Not testing with a network policy-capable CNI. The default kubenet CNI does NOT enforce NetworkPolicies. You need Calico, Cilium, or Weave Net.

  4. Applying directly to production. Test in a staging environment first.

Debugging NetworkPolicies

# List all policies in a namespace
kubectl get networkpolicy -n production

# Test connectivity between pods
kubectl exec -n production frontend-pod -- curl -m 5 api-backend:8080/health
Enter fullscreen mode Exit fullscreen mode

If curl hangs (no connection refused, just timeout), a NetworkPolicy is blocking the traffic.

Comprehensive K8s security guide: Kubernetes Security Best Practices

Top comments (0)