Cilium BPF conntrack map full: náhodné resetovania aj keď conntrack vyzerá OK
Intermitentne dostávate connection reset by peer, gRPC UNAVAILABLE alebo náhodné timeouty… ale iba na niektorých nodoch. Skontrolujete netfilter conntrack:
conntrack -Svyzerá normálnenf_conntrack_countnie je pri limite- kube-proxy ani nebeží (kube-proxy replacement)
A napriek tomu spojenia padajú.
Pri Cilium existuje paralelný svet: eBPF conntrack (CT) mapy. Keď sa tieto mapy zaplnia (alebo GC nestíha), viete strácať nové flowy alebo destabilizovať existujúce, pričom klasické conntrack metriky ostanú zelené.
Testované na: Kubernetes 1.29–1.31, Cilium 1.15–1.16, Linux 6.1–6.6, kube-proxy replacement zapnutý.
Incident (anonymizovaný)
Multi-tenant cluster migroval z kube-proxy na Cilium kube-proxy replacement. Krátko nato jedna služba (HTTP/2 + gRPC) začala mať:
- periodické connection resety
- vyššiu tail latenciu
- chyby koncentrované na podmnožine nodov
Blast radius: ~10–15% requestov (klienti trafili “postihnuté” nody) malo chyby.
Constraints:
- nemohli sme okamžite rollbacknúť kube-proxy replacement
- chceli sme mitigovať bez masívneho dropu spojení
Timeline
- T-0: nárast chýb; žiadna saturácia netfilter conntracku.
- T+10m: pattern je node-specific (len pár nodov).
- T+20m:
cilium monitor --type dropukáže dropy súvisiace s conntrackom. - T+30m:
cilium bpf metrics listukáže rast CT insert fail counterov. - T+45m: potvrdené: CT mapy sú blízko max entries; GC nestíha churn.
- T+60m: bezpečná mitigácia: zvýšiť CT mapy + znížiť churn.
- T+2h: chyby zmiznú; CT utilization sa stabilizuje.
Mechanizmus: čo sa naozaj stalo
Cilium používa BPF mapy na connection tracking
Keď Cilium robí service LB/NAT v eBPF, trackuje flowy cez BPF mapy. Tie majú:
- pevný max size (ak nemáte dynamické sizing nastavenia)
- GC mechanizmus, ktorý musí stíhať churn
- failure mode, ktorý sa ukáže ako Cilium drop, nie netfilter drop
Prečo je to node-scoped
BPF mapy sú per node. Preto:
- padá len časť nodov (hot nodes, vyšší churn, noisy neighbors)
- restart podov nepomôže, ak traffic stále skončí na rovnakom node
Prečo churn zabíja
Short-lived spojenia (alebo agresívne klientské správanie) vytvárajú veľa záznamov. Ak GC nestíha uvoľňovať, inserty zlyhajú. Vidíte:
- nové spojenia failujú
- existujúce sa resetujú kvôli chýbajúcemu stavu
Runbook: potvrdenie CT map exhaustion
Čo skontrolovať ako prvé
-
Je problém node-local?
Ak chyby korelujú s pár nodmi, podozrievajte per-node stav (BPF mapy, routovanie, kernel). -
Pozrite Cilium drops
Na postihnutom node (alebo cez privileged debug pod):
cilium monitor --type drop
Zachyťte 30–60s okno počas incidentu.
- Pozrite BPF CT metriky
cilium bpf metrics list | head -n 50
Hľadajte rast counterov, ktoré indikujú CT insert failure / map pressure.
Presné názvy metrik sa môžu líšiť podľa verzie, ale pattern “ct map full / insert fail” je konzistentný.
Ako potvrdiť hypotézu
A. Utilizácia CT mapy
cilium bpf ct list global | head
Rýchly odhad veľkosti:
cilium bpf ct list global | wc -l
Ak ste blízko configured max alebo trendujete stále hore, je to silný signál.
B. Konfigurácia limitov
cilium config view | grep -E 'bpf-ct|map'
Typické kľúče:
bpf-ct-global-tcp-maxbpf-ct-global-any-max- dynamické sizing ratio (ak ho používate)
C. Overte, že netfilter conntrack nie je bottleneck
conntrack -S | head
sysctl net.netfilter.nf_conntrack_max
Ak je toto zdravé a Cilium CT nie, root cause je BPF vrstva.
Bezpečné mitigácie
-
Zvýšiť CT map capacity
Nastaviť vyššiebpf-ct-global-tcp-max/bpf-ct-global-any-maxa rolloutnúť Cilium node-by-node. -
Znížiť churn (často najlepšia oprava)
- keepalive
- connection pooling
- odstrániť dial-per-request správanie pri retries
-
Scale hot nodov
Rozloží churn a CT tlak. -
Sane timeouts
Ak spojenia žijú zbytočne dlho, CT entries žijú dlho → vyšší tlak.
Rizikové mitigácie
- Flush CT map / tvrdý restart Cilium
- vie dropnúť aktívne spojenia na node (kontrolovaný výpadok)
- Slepo znižovať timeouts
- môže rozbiť legit long-lived spojenia
Čo sme zmenili (konkrétne)
1) Zvýšili sme CT mapy cez Cilium config
Upravili sme cilium-config (alebo Helm, ktorý ho generuje).
Diff (ilustratívny):
# kube-system/cilium-config
-bpf-ct-global-tcp-max: "262144"
-bpf-ct-global-any-max: "131072"
+bpf-ct-global-tcp-max: "524288"
+bpf-ct-global-any-max: "262144"
Rollout sme robili postupne (po nodoch), aby sme nespôsobili masívne prerušenie spojení.
2) Znížili sme churn v aplikácii
Našli sme klienta, ktorý otváral nové spojenie pre každý request počas retries. Prešli sme na reuse spojení.
Koncept:
- predtým: nový TCP connect pre každý pokus
- potom: keepalive + pooled transport + cap na retries
Ako verifikovať (merateľné)
- Drop countery prestanú rásť pri normálnom loade:
cilium monitor --type dropbez CT spike
- CT map size sa stabilizuje
- entries fluktuujú, ale nemajú monotónny rast
- utilization drží pod budgetom (napr. ≤ 70%)
- Chybovosť padne
- resety / gRPC
UNAVAILABLEspäť na baseline - tail latencia sa zlepší
Prevencia / guardrails
Budgety / invariants
- CT utilization budget per node (alert, keď sa blížite k max)
- Connection churn budget
- cap na creations/sec per klient
- dial rate ako first-class metriku
Alerty
- CT insert failure countery (per node) > 0 sustained
- drop spike na node (skôr než sa objavia app chyby)
- per-node error rate odchýlka od baseline
Súvisiace čítanie
- Kubernetes conntrack Vyčerpanie: Tichý Zabijak Paketov
- Traffic Ide na Mŕtve Pody: Conntrack Zastaralé NAT Mapovanie
- Ghost Pod: Prečo váš Service stále posiela traffic na mŕtve endpointy
- kube-proxy Mikro-Výpadky: Problém xtables Lock Contencie
- VXLAN Náhodné Straty Paketov: Pasca Checksum Offload
- Vyčerpanie Ephemeral Portov: Node Ktorý ‘Pokazí’
- Pakety prichadzaju ale aplikacia timeoutuje: rp_filter pasca v Kubernetes
Súvisiace články
HTTP Keep-Alive Connection Reset: Prečo Vaše Requesty Zlyhávajú s 'Connection Reset by Peer'
Sporadické 'connection reset by peer' chyby v produkcii. Ukážem ako nesúlad keep-alive timeoutov medzi klientom a serverom toto spôsobuje a ako to opraviť.
Kubernetes DNS: Latency Daň ndots:5
Každý DNS query v K8s robí 5 neúspešných lookupov pred úspechom. ndots:5 default spôsobuje 100ms+ latenciu. Tu je ako to opraviť.
Ephemeral-storage evictions v Kubernetes: logová búrka, ktorá vyhodila zdravé pody
Pody sú evicted kvôli ephemeral-storage aj keď disk vyzerá voľný. Runbook: nodefs/imagefs, logy, kubelet GC a nastavenie budgetov + log rotácia.
Pakety prichadzaju ale aplikacia timeoutuje: rp_filter pasca v Kubernetes
tcpdump ukazuje pakety ktore prichadzaju, ale aplikacia nic nevidi. Vinik: Linux reverse path filtering ticho zahadzuje pakety predtym nez dosiahnu iptables, sposobene asymetrickym routovanim.
Citujte tento článok
Ak na článok odkazujete, pridajte pôvodnú URL a uveďte autora.