- Authors

- Name
- Phillip Pham
- @ddppham
Kubernetes Network Segmentation: Mikrosegmentierung praktisch umsetzen
TL;DR
- Ohne NetworkPolicies kann jeder Pod mit jedem anderen Pod im Cluster kommunizieren -- das ist ein offenes Scheunentor.
- Eine Deny-all-Baseline pro Namespace ist der wichtigste erste Schritt. Danach schrittweise Allow-Regeln hinzufuegen.
- Cilium und Calico sind die beiden relevanten CNI-Plugins. Cilium bietet Layer-7-Filtering via eBPF, Calico ist ausgereifter bei reinem L3/L4.
- NetworkPolicies sind additiv: es gibt kein explizites "Deny", nur das Fehlen eines "Allow" nach Aktivierung einer Policy.
- Testen laesst sich das Ganze mit
kubectl execund einfachencurl/wget-Aufrufen zwischen Pods.
Warum Mikrosegmentierung wichtig ist
In einem Standard-Kubernetes-Cluster ohne NetworkPolicies gilt eine Flat-Network-Architektur. Jeder Pod kann mit jedem anderen Pod kommunizieren, egal in welchem Namespace. Das ist bequem fuer die Entwicklung, aber ein Albtraum fuer die Sicherheit.
Wenn ein Angreifer einen einzelnen Pod kompromittiert (etwa ueber eine Schwachstelle in einer Dependency), kann er sich lateral durch den gesamten Cluster bewegen. Er erreicht Datenbanken, interne APIs, Secrets-Management-Systeme -- alles ohne weitere Huerde.
Mikrosegmentierung loest dieses Problem, indem der Netzwerkverkehr auf Pod-Ebene kontrolliert wird. Das Prinzip ist einfach: Verbiete alles, erlaube nur das Noetigste.
CNI-Plugin-Vergleich: Cilium vs. Calico
Nicht jedes CNI-Plugin unterstuetzt NetworkPolicies. Und selbst unter denen, die es tun, gibt es erhebliche Unterschiede.
| Feature | Cilium | Calico | Flannel |
|---|---|---|---|
| Standard NetworkPolicies | Ja | Ja | Nein |
| Layer-7-Filtering (HTTP, gRPC) | Ja (nativ via eBPF) | Nur mit Envoy-Integration | Nein |
| Verschluesselung (WireGuard) | Ja | Ja | Nein |
| eBPF-basiert | Ja | Optional (eBPF dataplane) | Nein |
| DNS-basierte Policies | Ja | Enterprise-only | Nein |
| Performance-Overhead | Gering (eBPF) | Gering (iptables/eBPF) | Minimal |
| Hubble-Observability | Ja (integriert) | Nein (externer Stack noetig) | Nein |
Fuer ernsthafte Segmentierung ist Flannel keine Option. Die Wahl steht zwischen Cilium und Calico. Cilium hat in den letzten zwei Jahren stark aufgeholt und ist mittlerweile das Default-CNI bei vielen Managed-Kubernetes-Anbietern.
Schritt 1: Deny-all-Baseline einrichten
Der erste und wichtigste Schritt ist eine Default-Deny-Policy fuer jeden Namespace. Das folgende YAML blockiert saemtlichen eingehenden und ausgehenden Traffic fuer alle Pods im Namespace:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Der leere podSelector: {} selektiert alle Pods im Namespace. Ab dem Moment, in dem diese Policy angewendet wird, ist saemtliche Kommunikation blockiert -- auch DNS-Aufloesung.
DNS muss explizit erlaubt werden, sonst funktioniert Service-Discovery nicht mehr:
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:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
Diese beiden Policies zusammen bilden eine sichere Baseline: Kein Traffic erlaubt, ausser DNS-Anfragen an kube-system.
Schritt 2: Gezielte Allow-Regeln definieren
Jetzt kommt der Teil, der tatsaechlich Arbeit macht. Fuer jede legitime Kommunikationsbeziehung braucht es eine eigene Policy. Hier ein typisches Beispiel: Ein Frontend darf mit dem Backend auf Port 8080 sprechen, das Backend darf die Datenbank auf Port 5432 erreichen.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: production
spec:
podSelector:
matchLabels:
app: backend
tier: api
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
tier: web
ports:
- protocol: TCP
port: 8080
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-backend-to-database
namespace: production
spec:
podSelector:
matchLabels:
app: postgres
tier: database
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: backend
tier: api
ports:
- protocol: TCP
port: 5432
Wichtig: Das Frontend kann die Datenbank nicht direkt erreichen. Der Backend-Pod ist der einzige erlaubte Pfad zur Datenbank. Genau das ist der Sinn von Mikrosegmentierung.
Schritt 3: Namespace-uebergreifende Regeln
In der Praxis laufen Monitoring-Stacks, Logging-Agents und Ingress-Controller in eigenen Namespaces. Diese muessen Zugriff auf Pods in anderen Namespaces erhalten. Dafuer braucht es namespaceSelector:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-monitoring-scrape
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
purpose: monitoring
podSelector:
matchLabels:
app: prometheus
ports:
- protocol: TCP
port: 9090
- protocol: TCP
port: 9091
Hinweis: namespaceSelector und podSelector im selben from-Block wirken als AND-Verknuepfung. Das bedeutet, nur Prometheus-Pods aus dem Monitoring-Namespace erhalten Zugriff. Wenn die beiden Selektoren als separate Listeneintraege stehen (jeder mit einem -), wirken sie als OR -- ein haeufiger Konfigurationsfehler.
Layer-7-Policies mit Cilium
Standard-NetworkPolicies arbeiten auf Layer 3/4 (IP-Adressen und Ports). Cilium geht einen Schritt weiter und erlaubt Regeln auf HTTP-Ebene:
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: api-http-policy
namespace: production
spec:
endpointSelector:
matchLabels:
app: backend
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: GET
path: "/api/v1/products"
- method: POST
path: "/api/v1/orders"
Diese Policy erlaubt dem Frontend nur GET-Anfragen auf /api/v1/products und POST-Anfragen auf /api/v1/orders. Alle anderen HTTP-Methoden und Pfade werden blockiert. Das ist ein erheblicher Sicherheitsgewinn gegenueber reinem Port-basiertem Filtering.
Policies testen und validieren
NetworkPolicies sind schwer zu debuggen, wenn etwas nicht funktioniert. Es gibt kein kubectl get denied-connections. Hier ein pragmatischer Testansatz:
# Temporaeren Debug-Pod starten
kubectl run debug-frontend --rm -it \
--image=nicolaka/netshoot \
--labels="app=frontend,tier=web" \
-n production -- bash
# Aus dem Pod heraus: Erlaubte Verbindung testen
curl -v http://backend-svc:8080/api/v1/products
# Sollte funktionieren
# Verbotene Verbindung testen (direkt zur DB)
curl -v telnet://postgres-svc:5432
# Sollte mit Timeout fehlschlagen
# DNS-Aufloesung pruefen
nslookup backend-svc.production.svc.cluster.local
Fuer automatisierte Tests empfiehlt sich ein Tool wie cyclonus oder netpol-verify, das systematisch alle Kommunikationspfade prueft und gegen die definierten Policies validiert.
Haeufige Fehler bei der Umsetzung
Aus der Praxis ergeben sich immer wieder dieselben Stolperfallen:
1. DNS vergessen: Nach Aktivierung von Deny-all funktioniert nichts mehr, weil DNS-Anfragen blockiert werden. Immer eine DNS-Egress-Regel mitliefern.
2. AND vs. OR verwechseln: Zwei Selektoren im selben from-Eintrag sind AND. Zwei separate from-Eintraege sind OR. Der Unterschied ist subtil, aber sicherheitsrelevant.
3. Keine Labels auf Pods: NetworkPolicies selektieren ueber Labels. Ohne konsistente Label-Strategie ist Segmentierung nicht umsetzbar. Definieren Sie Standards wie app, tier, version und setzen Sie diese in allen Deployments durch.
4. Egress vergessen: Die meisten Teams konzentrieren sich auf Ingress-Regeln. Aber Egress ist genauso wichtig. Ein kompromittierter Pod, der Daten nach aussen exfiltrieren kann, ist ein massives Problem.
5. Policy in falschem Namespace: Eine NetworkPolicy gilt nur fuer den Namespace, in dem sie definiert ist. Das klingt offensichtlich, fuehrt aber regelmaessig zu Verwirrung.
Schrittweise Einfuehrung in bestehenden Clustern
Wer Mikrosegmentierung in einem laufenden Produktionscluster einfuehren will, sollte nicht einfach Deny-all einschalten. Das fuehrt garantiert zu Ausfaellen.
Stattdessen empfiehlt sich folgendes Vorgehen:
- Traffic-Analyse: Mit Hubble (Cilium) oder Calico Flow Logs den aktuellen Netzwerkverkehr dokumentieren. Welcher Pod spricht mit welchem Pod auf welchem Port?
- Allow-Regeln schreiben: Basierend auf der Traffic-Analyse die noetigsten Policies formulieren.
- Audit-Modus: Cilium bietet einen Policy-Audit-Modus, der blockierten Traffic nur loggt statt tatsaechlich zu blockieren. Damit laesst sich pruefen, ob die Policies korrekt sind, ohne den Betrieb zu stoeren.
- Namespace fuer Namespace: Nicht den gesamten Cluster auf einmal umstellen, sondern mit einem unkritischen Namespace beginnen und sich vorarbeiten.
- Monitoring einrichten: Alerts fuer blockierten Traffic konfigurieren, damit Fehlkonfigurationen schnell auffallen.
Performance-Auswirkungen
Die Frage kommt immer: "Wie stark bremsen NetworkPolicies den Cluster?" Die Antwort haengt vom CNI-Plugin ab.
Cilium nutzt eBPF-Programme, die direkt im Linux-Kernel laufen. Der Overhead liegt typischerweise unter 1% Latenz-Zunahme. Bei Calico mit iptables-Backend kann der Overhead bei sehr vielen Regeln (mehrere hundert) merkbar werden, weil iptables-Chains linear durchlaufen werden. Calicos eBPF-Dataplane behebt dieses Problem.
Fuer die meisten Cluster mit bis zu einigen tausend Pods und einigen hundert Policies ist die Performance-Auswirkung vernachlaessigbar.
Policies als Code verwalten
NetworkPolicies gehoeren ins Git-Repository, nicht in manuelle kubectl apply-Aufrufe. Verwalten Sie sie zusammen mit Ihren Deployments in einem GitOps-Workflow.
Ein sinnvoller Verzeichnisaufbau:
k8s/
namespaces/
production/
network-policies/
00-default-deny.yaml
01-allow-dns.yaml
10-frontend-to-backend.yaml
11-backend-to-database.yaml
20-monitoring-access.yaml
deployments/
frontend.yaml
backend.yaml
database.yaml
Die Nummerierung erleichtert die Uebersicht. ArgoCD oder Flux koennen die Policies automatisch synchronisieren. Aenderungen durchlaufen Code-Review, bevor sie angewendet werden. Das reduziert das Risiko von Fehlkonfigurationen erheblich.
Fuer Compliance-relevante Umgebungen laesst sich mit OPA Gatekeeper oder Kyverno zusaetzlich erzwingen, dass jeder Namespace eine Deny-all-Policy enthalten muss.
Zusammenspiel mit anderen Sicherheitsschichten
NetworkPolicies sind ein Baustein, nicht die gesamte Loesung. Eine solide Kubernetes-Sicherheitsarchitektur umfasst weitere Ebenen:
- RBAC: Wer darf was im Cluster tun? Details dazu in unserem Artikel zu Kubernetes RBAC im Enterprise-Einsatz.
- Runtime Security: Tools wie Falco erkennen anomales Verhalten in laufenden Containern. Mehr dazu unter Kubernetes Runtime Security.
- Secrets Management: Externe Secrets-Stores wie Vault verhindern, dass sensible Daten in ConfigMaps oder Environment-Variablen landen. Siehe Secrets Management mit Vault.
- Image Scanning: Schwachstellen in Container-Images finden, bevor sie in Produktion landen. Unser Artikel zu Security Scanning Tools gibt einen Ueberblick.
Mikrosegmentierung schuetzt den East-West-Traffic. Die anderen Massnahmen schuetzen die restlichen Angriffsflaechen.
Fazit
Kubernetes-Netzwerksegmentierung ist kein Nice-to-have, sondern gehoert zur Grundausstattung eines produktionsreifen Clusters. Der Einstieg ist mit einer Deny-all-Baseline und schrittweisen Allow-Regeln machbar, auch in bestehenden Umgebungen.
Wer Unterstuetzung bei der Planung oder Umsetzung braucht -- ob fuer einen einzelnen Cluster oder eine Multi-Cluster-Landschaft -- kann sich gerne bei uns melden unter /kontakt.
Kubernetes-Beratung gesucht?
Wir helfen deutschen Unternehmen bei der Kubernetes-Implementierung, Migration und Optimierung. DSGVO-konform und praxiserprobt.
📖 Verwandte Artikel
Weitere interessante Beiträge zu ähnlichen Themen
Netzwerk-Mikrosegmentierung in Kubernetes umsetzen
Mikrosegmentierung in Kubernetes mit Default-Deny, Zonen-Architektur und Cilium ClusterWide NetworkPolicy praktisch umsetzen.
Network Policies: Kubernetes-Traffic richtig absichern
Kubernetes erlaubt standardmäßig allen Pod-Traffic. Mit Network Policies sichern Sie Ingress und Egress gezielt ab. Praxis-Guide mit YAML-Beispielen.
Zero Trust Networking für Kubernetes umsetzen
Zero Trust in Kubernetes mit mTLS via Service Mesh, Network Policies und SPIFFE-Identitäten umsetzen. Praxisanleitung mit YAML.
Zero-Trust Architektur für Kubernetes Cluster
Zero-Trust in Kubernetes umsetzen mit Network Policies, mTLS und Identity Verification. Schritt-für-Schritt Anleitung für sichere Cluster-Kommunikation.
Kubernetes Zero Trust: Architektur für Container-Umgebungen
Zero-Trust-Architektur in Kubernetes umsetzen: mTLS, Network Policies, RBAC und Service Mesh mit YAML-Praxisbeispielen konfigurieren.