Skip to main content
RunBook Academy

KubernetesCXXIII · NetworkPolicy TroubleshootingNetworkPolicy troubleshooting

Cross-namespace policy — the multi-tenant network

Advanced⏱ ~14 minkubectl

What you'll learn

  • Reason about cross-namespace NetworkPolicies
  • Allow traffic between namespaces using namespaceSelector
  • Diagnose cross-namespace policy failures
  • Identify the production failure modes of cross-namespace policies

Prerequisites

Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16

Not yet marked complete on this device.

A Pod in one tenant’s namespace can open a connection to a Pod in another’s, and namespaceSelector is what stops it. It matches namespace labels rather than namespace names, which is why most cross-namespace rules select on kubernetes.io/metadata.name, the label the API server sets on every namespace automatically. The trap is structural: a namespaceSelector and a podSelector inside one from element mean both must match, while the same two written as separate elements mean either will do.

The namespaceSelector

A NetworkPolicy’s spec.ingress[].from and spec.egress[].to can include a namespaceSelector to match Pods in selected namespaces.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: prod
spec:
  podSelector:
    matchLabels:
      app: billing
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: frontend
      podSelector:
        matchLabels:
          app: web
    ports:
    - protocol: TCP
      port: 8080

The policy allows ingress from Pods labeled app: web in the frontend namespace to Pods labeled app: billing in the prod namespace.

The namespace labels

The namespace labels are the source of truth. The namespaceSelector must match the namespace’s labels.

# Substitute your own values before running:
SOURCE_NS=frontend

# Check the namespace's labels
kubectl get namespace "$SOURCE_NS" --show-labels

# Output:
# NAME       STATUS   LABELS
# frontend   Active   kubernetes.io/metadata.name=frontend

The namespace label kubernetes.io/metadata.name is automatically set by Kubernetes to the namespace’s name.

The diagnostic

The canonical diagnostic:

# Substitute your own values before running:
POLICY=allow-frontend-to-backend
POLICY_NS=prod
SOURCE_NS=frontend
SOURCE_POD=web-5f9c7d8b6c-2xk9p
TARGET_IP=192.0.2.24
TARGET_PORT=8080

# 1. Check the NetworkPolicy's namespaceSelector
kubectl get networkpolicy "$POLICY" -n "$POLICY_NS" -o yaml

# 2. Check the source namespace's labels
kubectl get namespace "$SOURCE_NS" --show-labels

# 3. Check the source Pod's labels
kubectl get pods -n "$SOURCE_NS" --show-labels

# 4. Test the connection from a Pod in the source namespace
kubectl exec -it "$SOURCE_POD" -n "$SOURCE_NS" -- curl -v "$TARGET_IP:$TARGET_PORT"

The diagnostic is the policy’s selectors, the namespace’s labels, and the Pod’s labels.

Common failures

  • Namespace mismatch. The policy’s namespaceSelector requires kubernetes.io/metadata.name=frontend but the source namespace is frontend-prod.
  • Pod labels mismatch. The policy’s podSelector requires app: web but the Pods have app: webapp.
  • Policy in wrong namespace. The policy is in the target namespace but should be in the source namespace.
flowchart TD
    A[Cross-namespace failure] --> B{Namespace labels match?}
    B -->|No| C[Fix the namespace or the selector]
    B -->|Yes| D{Pod labels match?}
    D -->|No| C
    D---|Yes| E{Policy in correct namespace?}
    E -->|No| F[Move the policy]
    E -->|Yes| G[Unknown]

The remediation

The remediation depends on the cause:

# Substitute your own values before running:
SOURCE_NS=frontend-prod            # namespace whose metadata.name label is wrong
CORRECT_NAME=frontend              # value the policy's namespaceSelector expects
POLICY=allow-frontend-to-backend
POLICY_NS=frontend                 # namespace the policy currently lives in
CORRECT_POLICY_NS=prod             # namespace the policy belongs in

# Option 1: Fix the namespace label
kubectl label namespace "$SOURCE_NS" kubernetes.io/metadata.name="$CORRECT_NAME"

# Option 2: Fix the policy's selector
kubectl patch networkpolicy "$POLICY" -n "$POLICY_NS" -p '{"spec":{"ingress":[{"from":[{"namespaceSelector":{"matchLabels":{"kubernetes.io/metadata.name":"frontend"}}}]}]}]'

# Option 3: Move the policy to the correct namespace
kubectl get networkpolicy "$POLICY" -n "$POLICY_NS" -o yaml > policy.yaml
kubectl apply -f policy.yaml -n "$CORRECT_POLICY_NS"
kubectl delete networkpolicy "$POLICY" -n "$POLICY_NS"

The remediation is the cross-namespace policy.

The cluster-wide policy

A cluster-wide policy (e.g., for monitoring) can be applied using a policy in the kube-system namespace with a namespaceSelector that matches all namespaces.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-monitoring
  namespace: kube-system
spec:
  podSelector:
    matchLabels:
      app: prometheus
  egress:
  - to:
    - namespaceSelector: {}

The policy allows the Prometheus Pods in kube-system to scrape metrics from any Pod in any namespace.

Production discipline

Cross-namespace policies are the cluster’s network hypothesis. The discipline is to walk the canonical flow extended with the multi-tenant network, identify the failure mode, apply the remediation. The network is the cluster’s connectivity; the remediation is the cross-namespace policy.

  • Verify the namespace labels. The label is the source of truth.
  • Verify the pod labels. The labels are the source of truth.
  • Verify the policy’s namespace. The policy is in the target namespace.

Quiz

Knowledge check · 4 questions

  1. Q1. What is the namespace label that Kubernetes automatically sets to the namespace's name?

  2. Q2. A cross-namespace policy must have the namespaceSelector matching the source namespace's labels.

  3. Q3. An operator reports that the frontend cannot reach the backend. The cross-namespace policy has `namespaceSelector: kubernetes.io/metadata.name=frontend` but the frontend namespace is `frontend-prod`. What is the diagnostic and remediation?

    The cluster is a 1.34.x kubeadm install. The frontend namespace is `frontend-prod`. The backend namespace is `prod`. The NetworkPolicy is `allow-frontend-to-backend` in `prod`. The policy's namespaceSelector requires `kubernetes.io/metadata.name=frontend`.

  4. Q4. Name three common causes of a cross-namespace NetworkPolicy failure and the diagnostic command for each.

Passing score: 75%. Answers are checked in this browser.