← Debugging Guides

阅读中文版本

Kubernetes NetworkPolicy Blocks Pod Traffic — Connection Timeout

Fix connection timeouts between pods by auditing NetworkPolicies, allowing the intended ingress and egress, and verifying with DNS and port tests.

intermediatedebuggingkubernetesnetworkpolicynetworking

Symptoms

  • One pod cannot reach another although both are Running and Ready
  • Connections time out rather than getting refused
  • Traffic works before a NetworkPolicy is applied

Possible causes

  • A NetworkPolicy selects the pod and allows only specific ingress/egress
  • Egress is default-deny and the pod cannot reach DNS or the target
  • The policy selects pods by labels that changed

Diagnosis steps

List policies affecting the namespace

kubectl get networkpolicy -n <ns> -o yaml

Interpretation

The selectors and allowed rules show which traffic is permitted and which is blocked.

Test DNS and a specific port from inside the pod

kubectl exec <pod> -- sh -c "nslookup db && nc -zv db 5432"

Interpretation

DNS failure suggests egress to DNS is blocked; a port timeout suggests the target policy blocks it.

Root cause

Once a pod is selected by a NetworkPolicy, traffic not explicitly allowed is denied. With default-deny ingress and egress, connections time out because packets are dropped rather than refused, which looks different from a closed port.

Fix

Add policies that allow the specific ingress and egress the workload needs, explicitly permit DNS egress to kube-dns, and keep selectors aligned with stable pod labels.

Risk note

A broad allow-all policy defeats the purpose of segmentation; grant only the required ports and peers.

Verify the fix

Re-test connectivity from the pod and confirm DNS and the target port succeed; verify the intended and blocked peers behave as expected.

Symptoms

This debugging guide addresses “Kubernetes NetworkPolicy Blocks Pod Traffic — Connection Timeout”. Start from the symptoms, follow the ordered diagnostics, and confirm each hypothesis before moving on; the fix and verification steps then close the loop.

Observed symptoms include:

  • One pod cannot reach another although both are Running and Ready
  • Connections time out rather than getting refused
  • Traffic works before a NetworkPolicy is applied

Reproduce and Diagnose

Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.

Step 1: List policies affecting the namespace

kubectl get networkpolicy -n <ns> -o yaml

The selectors and allowed rules show which traffic is permitted and which is blocked.

Step 2: Test DNS and a specific port from inside the pod

kubectl exec <pod> -- sh -c "nslookup db && nc -zv db 5432"

DNS failure suggests egress to DNS is blocked; a port timeout suggests the target policy blocks it.

Likely contributors, in order of frequency:

  • A NetworkPolicy selects the pod and allows only specific ingress/egress
  • Egress is default-deny and the pod cannot reach DNS or the target
  • The policy selects pods by labels that changed

Root Cause

Once a pod is selected by a NetworkPolicy, traffic not explicitly allowed is denied. With default-deny ingress and egress, connections time out because packets are dropped rather than refused, which looks different from a closed port.

The Fix

Add policies that allow the specific ingress and egress the workload needs, explicitly permit DNS egress to kube-dns, and keep selectors aligned with stable pod labels.

Watch out: A broad allow-all policy defeats the purpose of segmentation; grant only the required ports and peers.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-app-to-db
spec:
  podSelector:
    matchLabels: { app: db }        # target
  policyTypes: ["Ingress"]
  ingress:
    - from:
        - podSelector:
            matchLabels: { app: web }  # allowed source
      ports:
        - protocol: TCP
          port: 5432
---
# do not forget DNS egress when using default-deny egress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns
spec:
  podSelector: {}
  policyTypes: ["Egress"]
  egress:
    - to:
        - namespaceSelector: {}
      ports:
        - protocol: UDP
          port: 53
        - protocol: TCP
          port: 53

Verify and Prevent

Re-test connectivity from the pod and confirm DNS and the target port succeed; verify the intended and blocked peers behave as expected.

Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.

This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.