Kubernetes NetworkPolicy Cheatsheet: 12 Patterns zum Copy-Pasten
NetworkPolicies sind mächtig aber verwirrend. 12 produktionsreife YAML-Patterns für Ingress, Egress, Namespace-Isolation und Monitoring. Inklusive AND-vs-OR-Falle.
TL;DR - NetworkPolicies sind Kubernetes-eigene Firewall-Regeln auf Pod-Ebene. Ohne sie ist aller Traffic erlaubt. 12 Copy-Paste-Patterns decken 90% der Production-Fälle ab: von Deny-All-Default bis Prometheus-Scraping und DNS-Egress. Die größte Falle ist die AND-vs-OR-Semantik bei Selektoren.
🔖 Nur die YAMLs? Hier ist der interaktive NetworkPolicy-Cheatsheet - mit Copy-Button pro Pattern und häufigen Fehlern. Lesezeichen empfohlen.
Wie NetworkPolicies funktionieren
Das Mentalmodell in drei Sätzen:
- Ohne Policy ist alles erlaubt. Jeder Pod kann mit jedem Pod in jedem Namespace reden. Das ist der Kubernetes-Default.
- Sobald eine Policy auf einen Pod matched, ist alles blockiert was nicht explizit erlaubt ist. Ein
podSelector: {}matched alle Pods im Namespace. - Policies sind additiv. Mehrere Policies auf demselben Pod widersprechen sich nie, sie vereinigen ihre Allows.
Wichtig: NetworkPolicies brauchen ein CNI-Plugin das sie durchsetzt. Cilium, Calico und Weave Net tun das. Standard-kubenet in manchen Managed-K8s-Setups ignoriert Policies stillschweigend. Das ist die tückischste Falle: Sie schreiben Policies, testen auf dem Cluster, alles funktioniert weiterhin, und Sie denken “Policy greift”. In Wahrheit greift nichts.
# CNI prüfen
kubectl get pods -n kube-system -l k8s-app=cilium
kubectl get pods -n kube-system -l k8s-app=calico-node
Die AND-vs-OR-Falle
Die häufigste Verwechslung bei NetworkPolicies. Zwei Selektoren im from:-Block verhalten sich unterschiedlich je nach Formatierung:
OR (zwei separate Listenelemente):
ingress:
- from:
- namespaceSelector: # Listenelement 1
matchLabels:
name: monitoring
- podSelector: # Listenelement 2
matchLabels:
app: prometheus
Bedeutet: Traffic von allen Pods aus Namespace “monitoring” ODER von allen Pods mit Label app=prometheus im eigenen Namespace. Viel offener als gewollt.
AND (ein einziges Listenelement):
ingress:
- from:
- namespaceSelector: # Teil von Listenelement 1
matchLabels:
name: monitoring
podSelector: # auch Teil von Listenelement 1
matchLabels:
app: prometheus
Bedeutet: Traffic nur von Pods mit Label app=prometheus die sich im Namespace “monitoring” befinden. Das ist meistens was man will.
Der Unterschied sind zwei Zeichen im YAML: der Bindestrich vor podSelector. Mit Bindestrich: OR. Ohne: AND.
Die 12 Patterns
Deny-Defaults (die Basis)
Jeder Zero-Trust-Ansatz beginnt mit einem Deny-All. Erst alles blockieren, dann explizit erlauben.
Pattern 1: Deny All Ingress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
namespace: <ns>
spec:
podSelector: {}
policyTypes:
- Ingress
Blockiert allen eingehenden Traffic zu allen Pods im Namespace. Kein ingress:-Block = keine Ausnahmen.
Pattern 2: Deny All Egress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-egress
namespace: <ns>
spec:
podSelector: {}
policyTypes:
- Egress
Blockiert allen ausgehenden Traffic. Vorsicht: auch DNS ist blockiert. Pods können keine Service-Namen mehr auflösen. Immer mit Pattern 10 (DNS-Egress) kombinieren.
Pattern 3: Deny All (beides)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: <ns>
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Komplette Isolation. Namespace ist stumm. Von hier aus Pattern für Pattern öffnen.
Namespace- und Pod-Zugriff
Pattern 4: Allow from Same Namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-same-namespace
namespace: <ns>
spec:
podSelector: {}
ingress:
- from:
- podSelector: {}
policyTypes:
- Ingress
Alle Pods im eigenen Namespace dürfen sich gegenseitig erreichen, aber nichts von außen. Das häufigste Pattern für interne Microservices.
Pattern 5: Allow from Specific Namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-namespace
namespace: <ns>
spec:
podSelector: {}
ingress:
- from:
- namespaceSelector:
matchLabels:
name: backend
policyTypes:
- Ingress
Erlaubt Traffic aus einem bestimmten Namespace (hier: backend). Voraussetzung: der Quell-Namespace muss ein passendes Label haben (kubectl label namespace backend name=backend).
Pattern 6: Allow Specific Port Only
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-http-only
namespace: <ns>
spec:
podSelector:
matchLabels:
app: web
ingress:
- ports:
- port: 8080
protocol: TCP
from:
- podSelector: {}
policyTypes:
- Ingress
Nur Port 8080/TCP, nur aus dem eigenen Namespace. Alles andere blockiert.
Kubernetes Debugging - systematisch statt raten
Echte Production-Incidents nachstellen, kubectl-Workflows verinnerlichen, Root-Causes in Minuten finden.
Workshop-Details ansehenInfrastruktur-Zugriff
Pattern 7: Allow from Ingress Controller
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-ingress
namespace: <ns>
spec:
podSelector:
matchLabels:
app: web
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
policyTypes:
- Ingress
Erlaubt eingehenden Traffic vom Ingress-Controller-Namespace. Ohne dieses Pattern ist Ihre App von außen nicht erreichbar, auch wenn der Ingress korrekt konfiguriert ist. Gängige Labels: ingress-nginx, traefik, istio-ingress.
Pattern 8: Allow Prometheus Scraping (AND-Variante)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-prometheus
namespace: <ns>
spec:
podSelector: {}
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoring
podSelector:
matchLabels:
app.kubernetes.io/name: prometheus
ports:
- port: 9090
protocol: TCP
policyTypes:
- Ingress
AND-Variante: nur Prometheus (Label app.kubernetes.io/name: prometheus) aus dem Monitoring-Namespace. Port auf den Metrics-Port Ihrer App anpassen.
Pattern 9: Allow from Specific Pod (Database-Zugriff)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-backend-to-db
namespace: <ns>
spec:
podSelector:
matchLabels:
app: database
ingress:
- from:
- podSelector:
matchLabels:
app: backend
ports:
- port: 5432
protocol: TCP
policyTypes:
- Ingress
Nur der Backend-Pod darf auf die Datenbank zugreifen, nur auf Port 5432.
Egress-Kontrolle
Pattern 10: Allow DNS Egress Only
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns-egress
namespace: <ns>
spec:
podSelector: {}
egress:
- ports:
- port: 53
protocol: UDP
- port: 53
protocol: TCP
policyTypes:
- Egress
Das wichtigste Egress-Pattern. Ohne DNS-Egress können Pods keine Service-Namen auflösen: curl http://api-service:8080 schlägt fehl, obwohl der Pod eigentlich erreichbar wäre. Immer mit Deny-All-Egress (Pattern 2 oder 3) kombinieren.
Pattern 11: Allow Egress to External CIDR
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-egress-to-db
namespace: <ns>
spec:
podSelector:
matchLabels:
app: backend
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- port: 5432
protocol: TCP
- ports:
- port: 53
protocol: UDP
policyTypes:
- Egress
Backend darf nur an eine externe Datenbank (Subnet 10.0.0.0/24, Port 5432) und DNS. Für RDS, Cloud SQL oder Managed-DB-Instanzen außerhalb des Clusters.
Pattern 12: Allow Egress to Internal Service
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-api
namespace: <ns>
spec:
podSelector:
matchLabels:
app: frontend
egress:
- to:
- podSelector:
matchLabels:
app: api
ports:
- port: 8080
protocol: TCP
- ports:
- port: 53
protocol: UDP
policyTypes:
- Egress
Frontend darf nur mit dem API-Service reden (Port 8080) und DNS.
Die 5 häufigsten Fehler
- DNS-Egress vergessen. Deny-All-Egress ohne DNS-Allow (Pattern 10) → alle Verbindungen schlagen fehl, obwohl Ingress-Policies korrekt sind.
- AND vs OR verwechselt. Ein Bindestrich Unterschied im YAML öffnet den Zugriff viel weiter als gewollt. Immer explizit testen.
- Namespace-Labels fehlen.
namespaceSelectormatcht auf Labels des Namespaces, nicht auf den Namen. Labels manuell setzen:kubectl label namespace <ns> name=<ns>. - CNI enforced nicht. Policies existieren im API, werden aber von kubenet ignoriert.
kubectl get pods -n kube-system | grep ciliumprüfen. - Policies nur auf Ingress, Egress vergessen. Ingress-Policies allein kontrollieren nicht den ausgehenden Traffic. Für Zero-Trust braucht es beides.
Wie es weitergeht
Im Kubernetes Debugging Workshop simulieren wir unter anderem einen Incident, bei dem eine fehlende NetworkPolicy zu unbeabsichtigtem Cross-Namespace-Traffic führt, und debuggen ihn systematisch.
Verwandt aus unserer Serie:
- kubectl Debugging Cheatsheet - 12 Befehle für jedes Pod-Problem
- Pod Pending: 23 Ursachen - wenn Pods nicht starten
- OOMKilled: 6 Ursachen - wenn Pods sterben
- NetworkPolicy-Cheatsheet (interaktiv) - alle 12 Patterns mit Copy-Button und häufigen Fehlern
Kubernetes Debugging - systematisch statt raten
Echte Production-Incidents nachstellen, kubectl-Workflows verinnerlichen, Root-Causes in Minuten finden.
Workshop-Details ansehenWeiterlesen
kubectl Debugging Cheatsheet: 12 Befehle für Production-Incidents
Strukturierter Debugging-Workflow für Kubernetes in Production: 12 kubectl-Befehle in der richtigen Reihenfolge - von Pod-Status bis ephemeral debug containers.
8 min
Pod Pending in Kubernetes: 23 Ursachen, Decision-Tree, Fix-Workflow
Pod hängt im Status Pending? Die 23 häufigsten Ursachen in 5 Kategorien, mit kubectl-Befehlen, Decision-Tree und Workflow zur Diagnose in unter 5 Minuten.
10 minBrauchen Sie eine zweite Meinung zu Ihrem Cluster?
Buchen Sie einen kostenfreien 30-Minuten Kubernetes Health-Check. Wir schauen uns Ihr Setup an und geben konkrete Hinweise, ohne Verkaufsgespräch.
Termin buchen