Skip to content
Back to Blog
DevOps

Kubernetes Network Policies: Micro-segmentation in K8s

Implement Kubernetes NetworkPolicy resources for pod-to-pod traffic control, namespace isolation, and egress filtering.

Jul 2025
15 min read

Kubernetes Network Policies: Pod-Level Micro-Segmentation

By default, all pods can reach all other pods in Kubernetes. NetworkPolicy resources change this to explicit allow.

Default Deny All

Apply this to every namespace you care about:

YAML
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}  # Selects ALL pods
  policyTypes:
    - Ingress
    - Egress

Allow Frontend to Backend

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

Allow DNS (Critical!)

Without this, pods can't resolve DNS — add it with default-deny:

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
      ports:
        - port: 53
          protocol: UDP
        - port: 53
          protocol: TCP

Namespace Isolation

YAML
# Only allow traffic within the same namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-cross-namespace
  namespace: production
spec:
  podSelector: {}
  ingress:
    - from:
        - podSelector: {}  # Same namespace only

Database Access Control

YAML
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: postgres-access
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: postgres
  ingress:
    - from:
        - podSelector:
            matchLabels:
              role: db-client
      ports:
        - protocol: TCP
          port: 5432

Testing Network Policies

BASH
# Deploy test pod
kubectl run test --image=busybox -it --rm -- /bin/sh

# Inside test pod
wget -qO- http://backend:8080/health  # Should work
wget -qO- http://database:5432        # Should fail

Always use a CNI plugin that enforces NetworkPolicy: Calico, Cilium, or Antrea.