Back openDesk Edu for a sovereign, open-source education — every vote counts.
Vote nowSave products you love by clicking the heart icon.
Datengestützte Untersuchung von Open-Source-Kubernetes-Security-Tools basierend auf einem Korpus von 2.080 Repositories – Scanning, Secrets, Policy, Runtime und Supply-Chain-Integrität.
Kubernetes NetworkPolicy ist die Standard-API zur Steuerung des Traffics zwischen Pods – aber die API-Spezifikation ist lediglich ein Vertrag. Wie dieser Vertrag durchgesetzt wird, hängt vollständig vom gewählten CNI-Plugin ab, und der Performance-Unterschied zwischen den Implementierungen ist bei großen Skalierungen dramatisch.
Dieser Artikel befasst sich mit den zwei dominierenden Durchsetzungsansätzen: eBPF-basiert (Cilium) und iptables-basiert (Calico). Wir untersuchen die interne Funktionsweise, reale Performance-Benchmarks bei 100 bis 10.000 Policies, die Realität von L7-Policies und praktische Debugging-Muster.
Cilium hängt eBPF-Programme an mehreren Hook-Punkten im Linux-Kernel an. Jede Policy-Entscheidung erfolgt im Kernel-Space – ohne Userspace-Proxy, ohne iptables-Traversierung und ohne Context-Switches.
Hook-Punkte (in der Reihenfolge der Paketverarbeitung):
| Hook-Punkt | Ort | Funktion |
|---|---|---|
| XDP | NIC-Treiber-Level | Frühestmögliche Interzeption. Verwirft abgelehnte Pakete, bevor sie den Kernel-Netzwerkstack betreten. Erfordert einen nativ XDP-fähigen NIC-Treiber (Mellanox ConnectX, Intel XL710, Bare Metal). |
| TC ingress | veth-Interface | L3/L4-Policy-Durchsetzung für Pod-zu-Pod-Traffic. BPF-Maps speichern Policies als Identity + Bitmap-Lookups – O(1) unabhängig von der Anzahl der Regeln. |
| TC egress | veth-Interface | Egress-Policy-Durchsetzung, FQDN-basierte Regeln, Rate Limiting. |
| Socket-Level | connect() Syscall | L7-Policy-Durchsetzung via Redirect an einen pro-Node Envoy-Proxy zur Inspektion von HTTP/gRPC/Kafka/DNS. |
Die vom Cilium-Agent kompilierten eBPF-Programme nutzen BPF-Maps für das Zustandsmanagement. Policy-Updates pushen neuen BPF-Bytecode in den Kernel – es gibt keine regelbasierte Programmierung von iptables-Chains.
Packet flow with Cilium eBPF:
NIC → [XDP: drop/allow] → TC ingress → [BPF map lookup: identity+port] → Pod
Pod → [BPF map lookup] → TC egress → [FQDN resolve] → NIC
Zentrale Design-Eigenschaft: Der Policy-Lookup erfolgt via BPF-Maps in O(1). Das Hinzufügen des 10.000sten Services oder der 1.000sten Policy ändert nichts an den Lookup-Kosten. Dies ist der fundamentale Performance-Vorteil.
Der Felix-Agent von Calico läuft auf jedem Node und übersetzt NetworkPolicy-Objekte in iptables-Chains. Jede Policy-Regel wird zu einer oder mehreren iptables-Regeln in einer strukturierten Chain-Hierarchie.
Funktionsweise:
cali-fi-veth-abc123).PREROUTING → FORWARD → INPUT/OUTPUT → POSTROUTING.Packet flow with Calico iptables:
NIC → netfilter PREROUTING → FORWARD chain
→ cali-forward chain → cali-fi-veth-* chain
→ [Rule 1: match? no → Rule 2: match? no → ... → Rule N]
→ ACCEPT/DROP → Pod
Calico verfügt ebenfalls über eine eBPF-Dataplane (verfügbar seit v3.13). Wenn diese aktiviert ist, wird iptables umgangen und eBPF für die Paketverarbeitung genutzt – eine ähnliche Architektur wie bei Cilium. Dies ist jedoch ein Opt-in, und Calicos eBPF-Implementierung ist weniger ausgereift als das eBPF-native Design von Cilium.
| Dimension | Cilium eBPF | Calico iptables | Calico eBPF |
|---|---|---|---|
| Policy-Lookup | O(1) BPF-Map | O(n) sequenzielle Chain | O(1) BPF-Map |
| Kernel-Bypass | Ja (kein iptables) | Nein (Netfilter-Traversierung) | Ja (kein iptables) |
| Context-Switches | Null für L3/L4 | Pro-Paket Netfilter | Null für L3/L4 |
| Standard in 2026 | GKE, AKS (Option), EKS (Option) | AKS (Option), k3s (RKE2) | Opt-in |
| L7-Durchsetzung | Nativ (In-Kernel Redirect) | Envoy-Sidecar erforderlich | Envoy-Sidecar erforderlich |
Die wichtigste Erkenntnis aus mehreren unabhängigen Benchmarks: eBPF-basierte L3/L4-Policy-Durchsetzung verursacht keinen messbaren Overhead.
Cilium eBPF L3/L4 Overhead (aus Tencent TKE Benchmark, 2026):
| Metrik | Keine Policy | L3/L4 Policy angewendet | Overhead |
|---|---|---|---|
| Durchsatz (native) | 104.787 req/s | 104.083 req/s | -0,7% |
| Durchsatz (overlay) | 100.242 req/s | 100.599 req/s | +0,4% |
Dies liegt im Bereich des Messrauschens. Der Grund: BPF-Map-Lookup + Identity-Check ist ein Hash-Tabellen-Lookup im Kernel-Space. Er fügt nur Nanosekunden pro Paket hinzu.
Calico iptables mit skalierenden Policies (aus einer akademischen Studie von Kim et al. 2025):
| Policy-Anzahl | Durchsatz | Latenz | CPU |
|---|---|---|---|
| 100 Regeln | 8,8 Kbps | 43 ms | 3,24% |
| 500 Regeln | 8,5 Kbps | 46 ms | 3,45% |
| 1.000 Regeln | 8,2 Kbps | 51 ms | 3,89% |
Calico zeigt eine graduelle Verschlechterung. Die iptables-Chain wächst linear mit der Anzahl der Regeln – jedes Paket muss mehr Regeln durchlaufen.
Die eigentliche Divergenz tritt bei der Service-Skalierung auf, nicht bei der Anzahl der Policies. kube-proxy im iptables-Modus programmiert eine Regel pro Service pro Endpoint. Bei 10.000 Services mit jeweils 10 Endpoints sind das 420.000 iptables-Regeln.
Degradierung bei Service-Skalierung (aus Tencent TKE Benchmark, Kernel 6.6):
| Skalierung | iptables Degradierung | Cilium eBPF Degradierung |
|---|---|---|
| 5.000 Services × 10 Endpoints (209K Regeln) | -28,5% short-conn RPS | -13,2% |
| 10.000 Services × 10 Endpoints (420K Regeln) | -42,3% short-conn RPS | -11,5% |
Cilium verwendet BPF-Maps, in denen Endpoints Map-Werte und keine eigenständigen Regeln sind. Das Hinzufügen von Endpoints verlängert den Lookup nicht – es fügt lediglich Werte zum selben Map-Eintrag hinzu.
Latenz bei Skalierung (gleicher Benchmark):
| Dimension | iptables | Cilium eBPF |
|---|---|---|
| TCP_RR p99 | 111 μs | 96 μs |
| TCP_CRR p99 | 499 μs | 558 μs |
| HTTP p99 @ 1000 QPS | 0,99 ms | 0,99 ms |
Interessanterweise ist die TCP_RR-Latenz von Cilium auf modernen Kerneln (6.6+) tatsächlich niedriger als bei iptables, da eBPF den iptables-Overhead komplett umgeht. TCP_CRR (Verbindungsaufbau) ist jedoch aufgrund des conntrack-Overheads leicht höher.
Die L7-Policy-Durchsetzung (Filterung von HTTP-Pfaden/Methoden, gRPC-Service-Filterung) unterscheidet sich grundlegend von L3/L4. Sowohl Cilium als auch Calico leiten L7-Traffic an einen Userspace-Proxy (Envoy) für die Deep Packet Inspection weiter. Der Overhead ist massiv.
Cilium L7 Overhead:
| Metrik | Keine Policy | L7 CNP angewendet | Overhead |
|---|---|---|---|
| Durchsatz (native) | 104.787 req/s | 13.591 req/s | -87,0% |
| Durchsatz (overlay) | 100.242 req/s | 11.984 req/s | -88,0% |
| Dies ist kein Fehler von Cilium – es ist der inhärente Preis für L7-Sichtbarkeit. Jede L7-Anfrage erfordert: |
Der Envoy-Proxy pro Node teilt sich einen einzigen CPU-Kern mit allen Pods auf diesem Node. Auf ARM64-Nodes mit 1 vCPU führt dies zu 8,3-mal mehr Kernel-Scheduling-Aufwand pro Anfrage im Vergleich zur Baseline.
Service-Mesh-Vergleich (aus idmcarvalho service-mesh-benchmark):
| Szenario | QPS vs. Baseline (50c) | p50 Latenz | CS/Anfrage |
|---|---|---|---|
| Baseline (kein Mesh) | — | 42 ms | 202 |
| Cilium eBPF L3/L4 | -1,3% | 43 ms | 188 (-7%) |
| Istio ambient (ztunnel) | -28,5% | 54 ms | 283 (+40%) |
| Istio sidecar | -57,0% | 88 ms | 482 (+139%) |
| Cilium L7 | -84,5% | 249 ms | 1.667 (+726%) |
Cilium L7 ist tatsächlich schlechter als der Istio-Sidecar, da der gemeinsam genutzte Envoy-Proxy pro Node direkt mit den Application-Workloads um die CPU konkurriert.
Aus dem HMoradiRad-Vergleich (kind-Cluster, Bare-Metal-Schätzungen):
| Szenario | Cilium | Calico (iptables) | Gewinner |
|---|---|---|---|
| Same-node Durchsatz | 32,9 Gbps | 23,8 Gbps | Cilium (+38%) |
| Cross-node Durchsatz | 13,6 Gbps | 11,7 Gbps | Cilium (+16%) |
| Same-node Latenz | 0,83 ms | 0,91 ms | Cilium |
| Cross-node Latenz | 0,240 ms | 0,205 ms | Calico (leicht) |
Cilium gewinnt beim Durchsatz in beiden Szenarien dank des direkten veth-to-veth Forwardings von eBPF (keine Bridge, kein Netfilter). Calico gewinnt leicht bei der Cross-Node-Latenz – was auf den einfacheren Host-IP-Stack-Pfad im nativen Routing-Modus zurückzuführen ist.
Aus einer NSF-geförderten akademischen Studie (perf-basierte CPP-Messung):
| CNI | Gesamt-CPP | eBPF | Netfilter | Bridge | IP-Forwarding |
|---|---|---|---|---|---|
| Cilium | ~1.280 | ~1.200 | 0 | 0 | 0 |
| Calico (ohne Policy) | ~480 | 0 | 0 | 0 | ~240 |
| Calico (mit Policy) | ~2.700 | 0 | ~2.200 | 0 | ~240 |
| Flannel | ~330 | 0 | 0 | ~250 | 0 |
| Kube-router | ~250 | 0 | 0 | ~250 | ~250 |
Der eBPF-Overhead von Cilium (~1.200 CPP) ist höher als bei Bridge-basierten Ansätzen in Fällen ohne Policies, aber Calico mit Policies kostet ~2.700 CPP – mehr als das Doppelte der Gesamtkosten von Cilium. Das Durchlaufen des Netfilters ist hier der entscheidende Flaschenhals.
| Feature | Kubernetes NetworkPolicy | Calico (iptables) | Calico eBPF | Cilium |
|---|---|---|---|---|
| L3/L4 (IP, Port, Protokoll) | ✅ | ✅ | ✅ | ✅ |
| L7 HTTP (Pfad, Methode, Header) | ❌ | ❌ (nur Enterprise) | ❌ (nur Enterprise) | ✅ Nativ |
| L7 gRPC (Service, Methode) | ❌ | ❌ | ❌ | ✅ Nativ |
| L7 Kafka (Topic, Client ID) | ❌ | ❌ | ❌ | ✅ Nativ |
| DNS-basierte (FQDN) Policy | ❌ | ❌ (nur Enterprise) | ❌ | ✅ via DNS-Proxy |
| CIDR-Bereiche | ✅ | ✅ | ✅ | ✅ |
| Identitätsbasiert | ❌ (IP-basiert) | Teilweise (Label-basiert) | Teilweise | ✅ (Labels, Service Accounts) |
| Clusterweite Policies | ❌ (Namespace-scoped) | ✅ GlobalNetworkPolicy | ✅ | ✅ ClusterwideNP |
| Policy-Reihenfolge | ❌ (implizit) | ✅ (explizite Order) | ✅ | ❌ |
| Host-Firewall | ❌ | ✅ HostEndpoint | ✅ | ✅ |
| Egress-Gateway | ❌ | ❌ (nur Enterprise) | ❌ | ✅ |
| Policy-Tiers | ❌ | ✅ (Enterprise) | ✅ | ❌ |
| Feature | Cilium | Calico |
|---|---|---|
| Flow-Sichtbarkeit | ✅ Hubble (integriert, L7-aware) | ❌ (nur Enterprise / externe Tools) |
| Policy-Urteile | ✅ ALLOWED/DENIED pro Flow | ❌ |
| Echtzeit-Netzwerkkarte | ✅ Hubble UI | ❌ |
| CLI | hubble observe --namespace X --type drop | calicoctl flowlogs (eingeschränkt) |
| Prometheus-Metriken | ✅ hubble_flows_processed_total | ✅ (Setup erforderlich) |
| Runtime-Security | ✅ Tetragon (eBPF-basiert) | ❌ |
Hubble ist das Killer-Feature von Cilium für den Betrieb. Man kann jedes verworfene Paket sehen, welche Policy es verworfen hat und die L7-Details (HTTP-Methode, Pfad, Statuscode) – alles direkt aus dem eBPF im Kernel, ohne Sidecars.
| Feature | Cilium | Calico |
|---|---|---|
| kube-proxy Ersatz | ✅ (ausgereift, empfohlen) | ✅ (nur eBPF-Modus) |
| Service Mesh | ✅ (sidecarless, eBPF-basiert) | ❌ |
| BGP-Routing | Nur Control-Plane | ✅ (BIRD-Daemon, First-Class) |
| Multi-Cluster | ClusterMesh (bis zu 255) | Federation via BGP/Overlay |
| Verschlüsselung | WireGuard, IPsec | WireGuard, IPsec |
| Bandbreitenmanagement | ✅ EDT-basiertes Rate Limiting | Via Annotationen |
| Load Balancing | Maglev, DSR, XDP | IPVS oder iptables |
| Windows-Nodes | ❌ | ✅ (Windows HNS) |
| CNCF-Status | Graduated (Okt 2023) | Nicht CNCF (Tigera-Besitz) |
Wählen Sie Cilium, wenn:
Wählen Sie Calico, wenn:
Bei Clustern mit weniger als 500 Services und ohne L7-Policy-Bedarf ist der Performance-Unterschied vernachlässigbar. Der iptables-Modus von Calico verbraucht weniger Ressourcen (~278 MB/Node vs. ~153 MB/Node bei Cilium) und ist einfacher zu betreiben.
Die Entscheidung sollte auf sekundären Faktoren basieren: BGP-Bedarf (Calico) vs. Observability-Bedarf (Cilium).
Phase 1: Dual-Run-Validierung
Cilium kann während der Migration parallel zu Calico betrieben werden. Installieren Sie Cilium mit einem reservierten CIDR-Bereich, der sich nicht mit dem von Calico überschneidet:
ipam:
operator:
clusterPoolIPv4PodCIDRList: "10.200.0.0/16" # Separate from Calico's range
routingMode: "native"
kubeProxyReplacement: "probe" # Don't replace yet
Deployen Sie Cilium ohne kube-proxy-Replacement. Validieren Sie die Konnektivität und verschieben Sie anschließend die Workloads Namespace für Namespace.
Phase 2: Policy-Migration
Standard-Kubernetes NetworkPolicy-Objekte funktionieren auf beiden CNIs ohne Modifikationen. Die Migrationsfläche beschränkt sich auf die erweiterten Policy-CRDs:
| Calico CRD | Cilium-Äquivalent | Notizen |
|---|---|---|
NetworkPolicy (projectcalico.org) | CiliumNetworkPolicy | L7-Features lassen sich direkt zuordnen |
GlobalNetworkPolicy | CiliumClusterwideNetworkPolicy | Clusterweiter Scope |
NetworkSet | N/A (CIDR oder DNS nutzen) | IP-Gruppendefinitionen |
HostEndpoint | CiliumHostPolicy | Firewall auf Host-Ebene |
Nutzen Sie den Calico Network Policy Converter, um Calico-spezifische CRDs in entsprechende CiliumNetworkPolicy-Objekte zu übersetzen.
Phase 3: Entfernung von kube-proxy
Sobald alle Workloads über den Cilium-Datapath laufen, aktivieren Sie das vollständige kube-proxy-Replacement:
kubeProxyReplacement: "strict" # Fully replace
loadBalancer:
mode: "dsr" # Direct Server Return for Service LB
Schreiben Sie, wann immer möglich, Standard-Kubernetes NetworkPolicy. Greifen Sie nur dann auf CiliumNetworkPolicy oder Calico GlobalNetworkPolicy zurück, wenn Sie tatsächlich erweiterte Funktionen benötigen. So bleibt der Großteil Ihrer Policies CNI-agnostisch.
Das gleiche Muster aus dem k3s NetworkPolicy-Artikel gilt auch hier. Verlassen Sie sich niemals darauf, dass ein Policy-Objekt existiert – verifizieren Sie, dass es erzwungen wird:
# Deploy a test client and server
kubectl run test-client --image=busybox --command -- sleep 3600
kubectl run test-server --image=nginx --port=80
# Create a deny-all policy
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
EOF
# Test: should fail
kubectl exec test-client -- wget -q --timeout=3 http://test-server.default && echo "FAIL: policy not enforced" || echo "PASS: policy enforced"
Mit Cilium + Hubble können Sie genau sehen, welche Policy welchen Flow steuert:
# Watch all dropped packets in the payments namespace
hubble observe --namespace payments --type drop
# Output:
# Oct 11 10:23:45.123: default/test-client:42321 > default/test-server:80 (HTTP) FlowID:12345
# Verdict: DENIED (L7 Policy: allow-only-get)
# HTTP Method: POST, Path: /api/v1/admin/delete
Bei Calico erfordert das Debugging die direkte Inspektion der iptables-Chains:
# Show Calico's iptables chains
iptables -L cali-fi-veth-$(kubectl get pod test-server -o jsonpath='{.status.podIP}' | tr '.' '-') -n -v --line-numbers
# Count total iptables rules (the scaling concern)
iptables-save | grep -c "^-A"
Bei großen Installationen wird diese Ausgabe unübersichtlich. Aus diesem Grund werden für das Policy-Debugging in großem Maßstab Calico Enterprise oder externe Observability-Tools empfohlen.
| Ihre Situation | Empfehlung | Warum |
|---|---|---|
| Neuer Cluster, moderner Kernel (≥5.8) | Cilium | eBPF-native, beste Performance bei Skalierung, Hubble Observability |
| Bestehendes Calico, funktioniert gut | Bei Calico bleiben | Kein zwingender Grund für eine Migration, außer L7 oder Hubble werden benötigt |
| 10.000+ Services | Cilium | iptables bricht bei Skalierung ein (-42%), Cilium bleibt stabil |
| BGP-Peering mit physischen Routern | Calico | BIRD-Daemon, erstklassige BGP-Integration |
| L7 HTTP/gRPC Policy benötigt | Cilium | Natives L7 im Kernel ohne Sidecars |
| Windows-Nodes erforderlich | Calico | Einziges CNI mit Windows HNS Dataplane |
| Kleiner Cluster (<500 Services) | Beide | Performance-Unterschied ist vernachlässigbar |
| Managed K8s (GKE/AKS) | Cilium | Bereits integriert (GKE Dataplane V2, Azure CNI Powered by Cilium) |
| Edge / k3s / ressourcenbeschränkt | Calico (iptables) | Geringerer Memory-Footprint (~100 MB vs ~200 MB) |
L3/L4 NetworkPolicy hat mit eBPF keinen Overhead — Die BPF-Map-Lookups von Cilium kosten nur Nanosekunden pro Paket. Wenden Sie L3/L4-Policies bedenkenlos breit über alle Workloads an.
L7 NetworkPolicy ist überall kostspielig — Ein Overhead von 87 % ist der immanente Preis für die Inspektion durch Userspace-Proxies. Wenden Sie L7 selektiv nur auf Pods an, die tatsächlich eine Steuerung auf Anwendungsebene benötigen (Ingress-Gateways, sensible API-Endpunkte).
iptables bricht bei Service-Skalierung zusammen — 10.000 Services mit 420.000 Regeln führen zu einer Durchsatzminderung von 42 %. Dies ist der Hauptgrund, warum man sich für eBPF in mittelgroßen bis großen Clustern entscheiden sollte.
Hubble ist das herausragende Operational-Feature von Cilium — Echtzeit-Flow-Visibility mit Policy-Urteilen, L7-Details und Prometheus-Metriken. Kein iptables-basiertes CNI kann dies ohne Sidecars erreichen.
Standard NetworkPolicy ist portabel — Beide CNIs implementieren die Standard-API. Nur erweiterte CRDs (CiliumNetworkPolicy, GlobalNetworkPolicy) führen zu einem Vendor-Lock-in. Schreiben Sie nach Möglichkeit portable Policies.
Calico ist nicht falsch — Für BGP-Umgebungen, Windows-Nodes oder Cluster, bei denen die iptables-Skalierung kein Problem darstellt, bleibt Calico eine ausgereifte und praxiserprobte Wahl. Die Lücke zwischen den beiden Ökosystemen wird zwar größer, aber das Kernversprechen von Calico (BGP + Flexibilität) bleibt gültig.