Network Policies

Network Policies control how pods communicate with each other and external services. They act as firewalls at the pod level, allowing or denying traffic based on pod selectors, namespaces, and ports.

What are Network Policies?

Network Policies define:

  • Ingress rules - What traffic can reach pods
  • Egress rules - What traffic pods can send
  • Pod selectors - Which pods the policy applies to
  • Namespace selectors - Which namespaces can communicate

Default Behavior

Without Network Policies:

  • All pods can communicate - No restrictions
  • All ingress allowed - Any pod can reach any pod
  • All egress allowed - Pods can reach any destination

With Network Policies:

  • Default deny - If a pod has a NetworkPolicy, only explicitly allowed traffic is permitted
  • Isolation - Pods without policies can still communicate (unless namespace default deny)

Basic Network Policy

Deny All Ingress

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress

This denies all incoming traffic to all pods in the namespace.

Allow Specific Ingress

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

This allows only frontend pods to reach backend pods on port 8080.

Common Patterns

Namespace Isolation

Isolate namespaces from each other:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-cross-namespace
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: production
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: production

Database Access

Restrict database access:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: database-policy
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: database
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: api
    ports:
    - protocol: TCP
      port: 5432

Allow DNS

Ensure DNS always works:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: kube-system
    ports:
    - protocol: UDP
      port: 53

Best Practices

  1. Start with deny all - Begin with restrictive policies
  2. Allow incrementally - Add rules as needed
  3. Use labels - Consistent labeling makes policies easier
  4. Test thoroughly - Verify applications work with policies
  5. Document policies - Explain why each policy exists

See Also