OMNI52
Cilium Cheatsheet OMNI52™ GmbH
Neu in Cilium 1.20Gateway API v1.6.1 ist Mindestvoraussetzung · Gateway API deutlich breiter · Kubernetes ClusterNetworkPolicyAlle Neuerungen →

Cilium
auf einem Blatt.

Dichte Referenz für Senior Platform Engineers und SREs zur eBPF-basierten Networking-, Observability- und Security-Lösung für Kubernetes. Identity-based Policies von L3 bis L7, kube-proxy-Replacement, Hubble, Encryption, ClusterMesh, Gateway API, Diagnose und Anti-Patterns. Keine Einsteiger-Folien.

Vorschau (2 Seiten A4 quer + Brand-Rückseite)

Cilium Cheatsheet Seite 1: Architektur & Identity, Install & kube-proxy-Replacement, CiliumNetworkPolicy, L7-Policies & toFQDNs, Hubble
Cilium Cheatsheet Seite 2: Encryption, ClusterMesh, Gateway API, Diagnose, Neu in v1.20, Anti-Patterns

PDF herunterladen

Direkter Download, keine Mail-Adresse nötig. CC BY-SA 4.0: kopieren, drucken, weiterverteilen ist ausdrücklich erlaubt, solange die Quellenangabe sichtbar bleibt.

Cilium Cheatsheet (PDF, ~100 KB)

Was drin steht

eBPF & Identity

eBPF-Datapath statt iptables, cilium-agent/-operator, clusterweite Security-Identity aus security-relevanten Pod-Labels statt IP-basierter Regeln.

Policies L3–L7

CiliumNetworkPolicy + CiliumClusterwideNetworkPolicy: fromEndpoints, toEntities, toCIDR, toFQDNs, HTTP-Rules via node-lokalem Envoy, Enforcement-Modi.

kube-proxy-Replacement

Socket-LB für ClusterIP, NodePort, LoadBalancer, externalIPs, HostPort. k8sServiceHost/-Port als Pflicht, Kombination mit Istio, Helm-Install per OCI.

Hubble

Flow-Observability direkt aus dem Datapath: Relay clusterweit, UI mit Service-Map, hubble observe, Metriken für Prometheus.

Encryption & ClusterMesh

WireGuard (cilium_wg0, UDP 51871, Strict Mode), IPsec mit Per-Tunnel-Keys, ztunnel (Beta). Multi-Cluster-Verbund per Helm, globale Services oder MCS-API, Zertifikatslaufzeit.

Gateway API & Diagnose

Eingebauter Gateway-API-Controller (GatewayClass cilium). cilium status, connectivity test, sysdump. Anti-Patterns aus der Praxis.

Cheatsheet im Volltext

Derselbe Inhalt wie im PDF, zum Mitlesen, Durchsuchen und direkten Kopieren der YAML-Snippets. Stand: Cilium v1.20.2 (Edition 2026.10).

Architektur & Identity

eBPF-Datapath

CNI mit eBPF-Datapath: Networking, Load-Balancing, Policy und Observability laufen als eBPF-Programme im Kernel, mit kube-proxy-Replacement ohne iptables-Ketten pro Service.

Komponenten: cilium-agent (DaemonSet, je Node), cilium-operator (clusterweite Aufgaben, z.B. IPAM), Hubble (Observability), cilium-CLI. CNCF-graduated.

Identity statt IP

Jeder Endpoint bekommt eine clusterweite Security-Identity, abgeleitet aus den security-relevanten Pod-Labels. Endpoints mit identischem Label-Set teilen eine Identity.

Policy-Entscheidungen laufen gegen die Identity, nicht gegen flüchtige Pod-IPs. Das skaliert unabhängig von der Endpoint-Zahl.

cilium status --wait
kubectl get ciliumendpoints -A   # Identity je Pod
kubectl get ciliumidentities

Install & kube-proxy-Replacement

Helm-Install

Ohne kube-proxy müssen k8sServiceHost / k8sServicePort gesetzt sein, sonst findet der Agent den API-Server nicht (den Service löst sonst niemand auf). Chart per OCI, cosign-signiert, Version ohne v pinnen (oder per Digest).

helm install cilium \
  oci://quay.io/cilium/charts/cilium \
  --version 1.20.2 -n kube-system \
  --set kubeProxyReplacement=true \
  --set k8sServiceHost=<api-server-ip> \
  --set k8sServicePort=6443

kube-proxy-Replacement

eBPF übernimmt ClusterIP, NodePort, LoadBalancer, externalIPs und HostPort.

Socket-LB: übersetzt Service auf Backend schon beim connect()/sendmsg(), kein Paket-Rewriting auf dem Pfad.

Mit Istio (Sidecar oder Ambient), kube-proxy-frei: socketLB.hostNamespaceOnly=true, sonst greift Socket-LB schon im Pod und stört die Umleitung zum Istio-Proxy; dazu cni.exclusive=false, damit Istios CNI-Plugin erhalten bleibt. Die Cilium-Doku empfiehlt mit Istio weiterhin kubeProxyReplacement=false.

kubectl -n kube-system exec ds/cilium -- \
  cilium-dbg status --verbose | \
  grep KubeProxyReplacement

CiliumNetworkPolicy (L3/L4)

Selektoren, Entities, CIDR

endpointSelector wählt die Ziel-Endpoints; fromEndpoints/toEndpoints selektieren per Label (Identity).

toEntities: world, cluster, host, kube-apiserver.

toCIDR/toCIDRSet: für externe Ziele, Cluster-intern per Label selektieren.

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata: {name: backend-allow, namespace: shop}
spec:
  endpointSelector:
    matchLabels: {app: backend}
  ingress:
  - fromEndpoints:
    - matchLabels: {app: frontend}
    toPorts:
    - ports:
      - {port: "8080", protocol: TCP}

Clusterwide & Enforcement-Modi

CiliumClusterwideNetworkPolicy: gleiche Syntax, nicht namespaced, für Baselines über alle Namespaces. Baseline ohne Deny-Nebenwirkung: enableDefaultDeny: {ingress: false, egress: false}, gilt nicht für L7-Regeln (L7 ohne Allow-all droppt trotzdem).

policyEnforcementMode: default (alles offen, bis eine Regel den Endpoint selektiert, dann default-deny je Richtung), always, never.

L7-Policies & toFQDNs

HTTP-Rules (L7)

L7-Regeln hängen unter toPorts.rules.http: method, path, host als POSIX-Regex. Header nie per Regex: headers prüft Präsenz, als "Name: Wert" den exakten Wert; headerMatches vergleicht exakt (Wert auch aus Secret, mismatch steuert die Reaktion). Durchsetzung via node-lokalem Envoy; Verstoß liefert HTTP 403 statt Paket-Drop.

Weiterer L7-Typ: dns. Kafka- und proxylib-Regeln (kafka, l7, l7proto) sind seit 1.20 entfernt und müssen vor dem Upgrade aus den Policies raus.

spec:
  endpointSelector:
    matchLabels: {app: api}
  ingress:
  - fromEndpoints:
    - matchLabels: {app: frontend}
    toPorts:
    - ports:
      - {port: "80", protocol: TCP}
      rules:
        http:
        - method: GET
          path: /v1/.*

toFQDNs (Egress nach Namen)

matchName exakt, matchPattern mit Wildcard.

Pflicht-Voraussetzung: eine rules.dns-Regel schaltet den DNS-Proxy ein, ohne DNS-Sichtbarkeit kann Cilium FQDNs nicht auf IPs mappen und die Policy läuft leer.

egress:
- toEndpoints:
  - matchLabels: {k8s-app: kube-dns}
  toPorts:
  - ports: [{port: "53", protocol: ANY}]
    rules:
      dns: [{matchPattern: "*"}]
- toFQDNs:
  - matchName: api.example.com
  - matchPattern: "*.storage.example.com"
  toPorts:
  - ports: [{port: "443", protocol: TCP}]

Hubble (Observability)

Flows, Relay, UI

Hubble liest Flows direkt aus dem eBPF-Datapath, ohne Sidecars oder Paket-Mirroring. L7-Flows (HTTP, DNS) gibt es nur für Traffic, den eine L7-Regel über den Proxy leitet, und diese Regel filtert dann auch.

Relay aggregiert clusterweit (auch über ClusterMesh), UI zeigt die Service-Dependency-Map, die CLI (hubble) filtert Flows live.

Redaction: Hubble schwärzt L7-Daten (Query-Parameter, Header) standardmäßig nicht. hubble.redact.enabled=true plus hubble.redact.http.urlQuery=true, Header per hubble.redact.http.headers.allow oder .deny (nur eine der beiden Listen).

cilium hubble enable --ui
cilium hubble port-forward &
hubble status
hubble observe --namespace shop \
  --verdict DROPPED
hubble observe --protocol http --last 20

Metriken

Hubble-Metriken für Prometheus per Helm: hubble.metrics.enabled="{dns,drop,tcp,flow,icmp,httpV2}".

Agent: prometheus.enabled=true,
Operator: operator.prometheus.enabled=true.

Encryption

WireGuard

Transparente Verschlüsselung des Pod-Traffics zwischen Nodes (Device cilium_wg0, UDP 51871, Firewall freischalten!). Key-Paar erzeugt jeder Node selbst, Public-Key-Austausch via CiliumNode-Annotation.

Node-zu-Node zusätzlich: encryption.nodeEncryption=true. Nodes mit Label node-role.kubernetes.io/control-plane nimmt Cilium davon automatisch aus. Same-Node-Traffic bleibt unverschlüsselt.

Strict Mode: encryption.strictMode.egress.enabled=true plus .egress.cidr (Pod-CIDR, nur IPv4) verhindert unverschlüsselte Erstpakete. encryption.strictMode.ingress.enabled=true (nur WireGuard) droppt unverschlüsselten Pod-Traffic. Die alten Schlüssel encryption.strictMode.enabled/.cidrs sind seit 1.20 entfernt.

# Konfig-Änderung: --version = installierte Chart-Version
helm upgrade cilium \
  oci://quay.io/cilium/charts/cilium \
  --version 1.20.2 -n kube-system \
  --reuse-values \
  --set encryption.enabled=true \
  --set encryption.type=wireguard
kubectl -n kube-system exec ds/cilium -- \
  cilium-dbg status | grep Encryption

IPsec

encryption.type=ipsec; Key liegt im Secret cilium-ipsec-keys (Cilium-Namespace), z.B. "3+ rfc4106(gcm(aes)) <key> 128". Das + erzwingt Per-Tunnel-Keys, globale Keys gelten als unsicher (GHSA-pwqm-x5x6-5586).

Key-Rotation ist manuell (KEYID 1–15 inkrementieren), nie während eines Upgrades rotieren.

ztunnel (Beta)

encryption.type=ztunnel: L4-mTLS je Node über Istios ztunnel, Enrollment je Namespace (Label io.cilium/mtls-enabled=true), CA internal (Default) oder spire. Nicht mit ClusterMesh kombinierbar. Empfohlene Alternative zur seit 1.20 deprecateten Mutual Authentication.

ClusterMesh

Multi-Cluster-Verbund

Pod-Konnektivität über Cluster-Grenzen, globale Services mit Cross-Cluster-Load-Balancing. Policies selektieren seit 1.19 nur den lokalen Cluster, Remote-Endpoints explizit per Label io.cilium.k8s.policy.cluster.

Voraussetzungen: PodCIDRs aller Cluster disjunkt, eindeutiger cluster.name + cluster.id (1–255, mit clustermesh.maxConnectedClusters=511 bis 511, nur bei der Installation setzbar, in allen Clustern gleich), gegenseitiges TLS-Vertrauen (gemeinsame CA, z.B. cilium-ca kopieren, oder tls.caBundle), IP-Konnektivität zwischen allen Nodes, clustermesh-apiserver gegenseitig erreichbar.

# CLI-Weg (Lab, Demo)
cilium clustermesh enable --context c1
cilium clustermesh connect --context c1 \
  --destination-context c2
cilium clustermesh status --wait

Helm-Setup & Zertifikate

Setup laut Doku Helm-first: clustermesh.useAPIServer=true, clustermesh.config.enabled=true, Remote-Cluster unter clustermesh.config.clusters. Die CLI ist ein Helm-Wrapper für schnelle Setups (Lab, Demo).

Zertifikate: seit 1.20 gelten auto-generierte Cluster-Mesh-Zertifikate ein Jahr. Methode helm (Default) erneuert nur beim Re-Render, also beim Upgrade. Produktiv cronJob oder certmanager, oder clustermesh.apiserver.tls.auto.certValidityDuration setzen.

Globale Services

Annotation service.cilium.io/global: "true" auf dem gleichnamigen Service in beiden Clustern, Cilium load-balanct auf die Backends beider Cluster.

service.cilium.io/shared: "false": Remote-Backends nutzen, eigene nicht teilen.

Alternative zu globalen Services: MCS-API (clustermesh.mcsapi.enabled=true, seit 1.20 stabil, CRDs v1beta1, braucht CoreDNS ab 1.12.2 für clusterset.local).

Gateway API

Eingebauter Controller

Cilium implementiert die Gateway API (CRDs v1.6.1 vorab installieren): GatewayClass, Gateway, HTTPRoute, GRPCRoute, ReferenceGrant, TLSRoute sowie TCPRoute/UDPRoute (seit Gateway API 1.6 GA, v1; CRDs optional, Traffic läuft am Envoy vorbei direkt auf den Gateway-Service; im Host-Network-Modus nicht nutzbar). Gateway-Service per Default vom Typ LoadBalancer.

Voraussetzungen: kubeProxyReplacement=true, l7Proxy=true (Default), gatewayAPI.enabled=true. Ohne bpf.tproxy=true (beta) läuft der Redirect zu Envoy über iptables-TPROXY: fehlen die Netfilter-Module, laufen Verbindungen in Timeouts. GatewayClass heißt cilium.

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata: {name: web-gw, namespace: shop}
spec:
  gatewayClassName: cilium
  listeners:
  - {name: http, port: 80, protocol: HTTP}
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata: {name: web, namespace: shop}
spec:
  parentRefs: [{name: web-gw}]
  rules:
  - matches:
    - path: {type: PathPrefix, value: /}
    backendRefs: [{name: web, port: 80}]

Diagnose (cilium-CLI)

Werkzeuge

cilium status --wait: Health aller Komponenten.
cilium connectivity test: E2E-Testsuite im Cluster.
cilium sysdump: Support-Archiv für Bug-Reports.

Im Agent-Pod: cilium-dbg (endpoint list, policy get, monitor).

cilium connectivity test
cilium sysdump --output-filename dump
kubectl -n kube-system exec ds/cilium -- \
  cilium-dbg endpoint list
kubectl -n kube-system exec ds/cilium -- \
  cilium-dbg monitor --type drop

Neu in v1.20

Highlights (29.07.2026)

ClusterNetworkPolicy (network-policy-api, v1alpha2): opt-in per k8sClusterNetworkPolicy.enabled=true, CRD separat installieren. Tier Admin schlägt auch CNP/CCNP, Baseline greift erst nach ihnen. Volle API-Konformität verlangt --policy-cidr-match-mode=pods,nodes (Helm policyCIDRMatchMode={pods,nodes}, Beta), weil die API CIDR-Regeln auch auf Pod- und Node-IPs anwendet; pods kostet je getroffenem Pod eine zusätzliche Identity.

Gateway API v1.6.1: TCPRoute/UDPRoute GA, delegierte Listener (ListenerSets), ExternalAuth-Filter, Backend-TLS.

netkit automatisch (Beta): bpf.datapathMode=auto nimmt netkit, wenn der Kernel es kann (ab 6.8, eBPF-Host-Routing nötig), sonst veth; Default bleibt veth. Kein In-place-Wechsel: erkennt auto netkit auf einem Node mit bestehenden veth-Pods, startet Cilium mit Fehler. Mit bpf.tproxy=true fällt auto immer auf veth zurück, explizites netkit plus tproxy startet nicht.

Traffic Distribution: PreferSameZone / PreferSameNode werden ausgewertet; Maglev beachtet service.cilium.io/weight auf EndpointSlices (Gewicht 0 = draining, Bestandsverbindungen laufen weiter).

MCS-API stabil für portable Service-Discovery über ClusterMesh.

Getestet gegen Kubernetes 1.33 bis 1.36 (ältere ohne Support, 1.37 erst im Entwicklungszweig für 1.21 gelistet), Envoy 1.37.x. Das cilium-cni-Binary schrumpft von rund 77 auf 16 MB.

Upgrade-Reihenfolge

Gateway-API-CRDs vor dem Cilium-Upgrade auf v1.6.1 heben und TLSRoute-Ressourcen vorher sichern. Kafka-/l7-/l7proto-Regeln vorher aus den Policies entfernen, CiliumNodeConfig auf cilium.io/v2 umstellen. Ziel mindestens 1.20.2: frühere 1.20-Patches scheitern auf Clustern, die mit 1.15 oder älter angelegt wurden, und ein HTTPRoute-ExternalAuth mit ungültiger Backend-Referenz schlägt erst ab 1.20.2 geschlossen fehl.

Mit kube-proxy-Replacement ohne Socket-LB oder mit socketLB.hostNamespaceOnly=true balanciert 1.20 Pod-Verbindungen auf NodePort-Services schon beim Verlassen des Client-Pods. Die Egress-Policy des Clients muss die Backends erlauben, die Ingress-Policy der Backends den Client.

Support-Fenster: drei Minor-Linien parallel (1.20.2, 1.19.8, 1.18.14 vom 15.09.2026). Die aktuelle Linie bekommt alle Bugfixes, die beiden Vorgänger nur Security- und schwere Korrektheits-Fixes.

Anti-Patterns

Was du nicht tun solltest

toFQDNs ohne DNS-Rule: ohne rules.dns-Sichtbarkeit kein FQDN-zu-IP-Mapping, Policy blockt oder läuft leer.

kube-proxy-frei ohne k8sServiceHost/Port: Agent erreicht den API-Server nicht, Cluster-Bootstrap hängt.

CIDR-Regeln für Cluster-Traffic: toCIDR ist für externe Ziele gedacht; Pod-IPs sind flüchtig, Labels/Identities selektieren.

Default-Modus falsch verstanden: ohne selektierende Regel ist alles offen; die erste Regel schaltet den Endpoint auf default-deny (je Richtung), sofern sie nicht enableDefaultDeny abschaltet.

WireGuard ohne UDP 51871: Nodes müssen sich auf dem Port erreichen, sonst kein Tunnel.

--reuse-values beim Minor-Upgrade: neue Chart-Werte fehlen, das Template rendert falsch. Werte per helm get values sichern, auf umbenannte Keys prüfen, mit -f übergeben.

IPsec-Keys während des Upgrades rotieren: erst alle Nodes auf gleiche Cilium-Version, dann rotieren.

ClusterMesh mit überlappenden PodCIDRs oder doppelter cluster.id: Verbund kommt nicht sauber hoch, vorab planen.

Verwandte Cheatsheets

Ebenfalls von OMNI52:
service-mesh-cheatsheet.de, Service Mesh im Vergleich
istio-cheatsheet.de, Istio in der Tiefe
kubernetes-cheatsheet.de, Kubernetes Core
rke2-cheatsheet.de, RKE2 (CNI-Wahl)

Lizenz & Weiterverteilung

CC BY-SA 4.0. Du darfst dieses Cheatsheet kopieren, weiterverteilen, ausdrucken und in eigenen Materialien zitieren. Bedingung: Quellenangabe „Cilium Cheatsheet, OMNI52 GmbH, cilium-cheatsheet.de“ bleibt sichtbar, und abgeleitete Werke stehen unter der gleichen Lizenz (Share-Alike).

Nicht erlaubt: Logo, Marken oder den Eindruck zu vermitteln, dass der Inhalt von dir/euch stammt oder dass OMNI52 GmbH die Weiterverwendung sponsort.

Volltext der Lizenz: creativecommons.org/licenses/by-sa/4.0/deed.de.

Cilium is a trademark of The Linux Foundation, registered in the United States and/or other countries. Kubernetes is a registered trademark of The Linux Foundation. OMNI52™ is a trademark of OMNI52 GmbH (filed, not yet registered). This website is operated by OMNI52 GmbH and is not affiliated with, endorsed by, or sponsored by The Linux Foundation, the CNCF, or the Cilium project. “Cilium” is used in a nominative / descriptive sense to indicate the technology this cheatsheet documents.