Späť na blog

ingress-nginx reload búrky: prečo 502 špičky sedia s Ingress churnom

Symptómy sú nepríjemne periodické:

  • 502/504 vyskočia na pár sekúnd… každých pár minút.
  • gRPC a keep-alive heavy klienti reconnectujú a “healnú sa retry”.
  • Backend je zdravý (readiness zelený).
  • ingress-nginx pody necrashujú.

Keď vidím spiky 502 a backend je OK, položím si najprv jednu otázku:

Nereloadujeme NGINX príliš často?

ingress-nginx generuje NGINX config a reloaduje pri zmenách Kubernetes objektov. Pri churn-e (Ingress updaty, cert renewaly, ExternalDNS, canary flipy) sa reload prestane správať ako “konfigurácia” a začne byť “generátor mikro‑výpadkov”.

Testované na: Kubernetes 1.29–1.31, ingress-nginx 1.10–1.11, NGINX 1.25+, HTTP/1.1 + HTTP/2, cloud aj on‑prem LB pred ingressom.

Incident (anonymizovaný)

Mali sme 502 špičky, ktoré vždy zmizli po retry. Backend bol stabilný a p99 na aplikácii to nevysvetľovalo.

Clue bola synchronizácia: viacero nesúvisiacich služieb malo špičky v rovnakých timestampoch. To zvyčajne znamená spoločný edge komponent, nie individuálny backend.

Root cause:

  • GitOps neustále reconciloval Ingress objekty.
  • Reconciler robil “no-op” updaty (poradie anotácií, prepísané defaulty).
  • ingress-nginx to bral ako zmenu configu a reloadoval pri každom update.
  • Reload čas rástol, lebo rástol aj generovaný config.

Constraint: nemohli sme prestať deployovať. Potrebovali sme budget: najprv znížiť reload frekvenciu, potom spraviť reload menej disruptive.

Timeline

  • T-0: 502 špičky, hlavne na keep-alive spojeniach a gRPC.
  • T+10m: v logoch ingress-nginx vidím reload eventy presne v čase špičiek.
  • T+20m: zmeriam reload rate (počas deploy okien viaceré reloady za minútu).
  • T+30m: mitigácia: pauznúť non-essential churn a zvýšiť graceful shutdown budget.
  • T+60m: 502 špičky výrazne klesnú.
  • T+1d: fixy: stop no-op updateov, konsolidácia Ingressov, alert na reload rate.

Mechanizmus: prečo reload spraví 502 aj keď backend je zdravý

NGINX reload nie je no-op:

  • master zvaliduje nový config
  • naštartujú sa nové workery
  • staré workery drainujú a potom skončia

Aj pri graceful reloade sa niektoré spojenia zavrú:

  • idle keep-alive sa môžu dropnúť
  • dlhé HTTP/2 streamy sa môžu resetnúť podľa timing-u
  • retry to maskuje, kým nevyletí p99

Zhorší sa to, keď:

  • príde ďalší reload skôr, než staré workery stihnú drain
  • config je veľký (parsing/validácia)
  • controller je CPU-throttlovaný a reload okno sa natiahne

Runbook: dokáž, že reload je príčina

1) Korelácia špičiek s reload logmi

Začni logmi. Rôzne verzie logujú trochu iné frázy, ale intent je vždy viditeľný.

kubectl -n ingress-nginx logs deploy/ingress-nginx-controller --since=60m | \
  rg -n "Reloading|reloaded|Configuration changes detected|backend reload" | tail -n 50

Ak timestampy sedia so špičkami, máš silný signál.

2) Zmeraj reload rate (nehádaj)

Ak scrapuješ ingress-nginx metriky, najprv si nájdi reálne metriky v /metrics (nenašteluj sa na názvy naslepo):

kubectl -n ingress-nginx port-forward deploy/ingress-nginx-controller 10254:10254
curl -s http://127.0.0.1:10254/metrics | rg -n "reload|nginx.*reload" | head -n 50

Cieľ je budget: reloady za minútu v steady state majú byť takmer nulové.

3) Nájsť zdroj churnu

Typickí vinníci:

  • GitOps patch loop
  • cert-manager (TLS secret updaty)
  • ExternalDNS (anotácie/DNS zmeny)
  • canary tooling (časté anotácie)

V čase incidentu sa pozri, kto “touchoval” Ingress:

kubectl get events -A --sort-by=.lastTimestamp | tail -n 50
kubectl get ingress -A -o custom-columns=NS:.metadata.namespace,NAME:.metadata.name,GEN:.metadata.generation --sort-by=.metadata.generation | tail -n 20

Ak generácie rastú bez reálnej zmeny routingu, často ide o no-op churn bug.

4) Over, že backend je healthy (aby si nefixoval zlé miesto)

kubectl -n <app-ns> get pods -o wide
kubectl -n <app-ns> get endpoints <svc> -o wide

Ak backend drží a špičkuje iba edge, riešiš ingress správanie, nie appku.

Bezpečné mitigácie (v incidente)

1) Prestaň sa dotýkať configu

Pauzni to, čo robí churn:

  • pauznúť GitOps sync pre Ingress resources
  • neflipovať canary anotácie
  • cert/DNS zmeny mimo peak trafficu

2) Viac drain budgetu pre reload

ingress-nginx exponuje NGINX knobs cez ConfigMap (over si presné kľúče pre tvoju verziu). Intent:

  • dať workerom viac času na drain
  • znížiť drop keep-alive počas tesných reload okien

Reprezentatívny príklad:

apiVersion: v1
kind: ConfigMap
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
data:
  worker-shutdown-timeout: "30s"
  keep-alive: "75"
  keep-alive-requests: "10000"

A uisti sa, že controller pod má termination grace period, ktorá pokryje drain:

spec:
  template:
    spec:
      terminationGracePeriodSeconds: 60

3) Odstráň CPU throttling z controlleru

CPU throttling predĺži reload a zväčší disruption okno. Daj controlleru CPU headroom a zváž horizontálne škálovanie.

Čo sme zmenili (konkrétne)

1) Stop no-op updatov pri zdroji

GitOps prepisoval anotácie aj keď sa reálny výsledok nezmenil. Fix znížil reloady o rád.

2) Konsolidácia a de-churn Ingressov

Stovky malých Ingress objektov spravia veľký generovaný config a veľa update eventov. Konsolidácia znížila:

  • veľkosť configu
  • reload time
  • frekvenciu zmien

3) Reload budget a observabilita

Pridali sme:

  • dashboard panel: reloady za minútu
  • alert: reload rate nad budget
  • alert: “reload start bez success” dlhšie než N sekúnd (log-based, ak treba)

Ako verifikovať

  • 502 špičky už nesedia s reload logmi.
  • Reload rate je nízky v steady state.
  • Long-lived klienti (gRPC streamy, keep-alive heavy) prestanú periodicky reconnectovať.

Prevencia / guardrails

  • Ingress updaty sú produkčná zmena; no-op updaty sú outage v prestrojení.
  • Budget na reload rate (steady state má byť zriedkavý a vysvetliteľný).
  • Ingress controller drž mimo CPU throttling.
  • Cert/DNS churn koordinuj tak, aby nevznikali reload búrky počas peak trafficu.

Súvisiace čítanie

Súvisiace články

Citujte tento článok

Ak na článok odkazujete, pridajte pôvodnú URL a uveďte autora.

Michal Drozd. "ingress-nginx reload búrky: prečo 502 špičky sedia s Ingress churnom". https://www.michal-drozd.com/sk/blog/ingress-nginx-reload-burky/ (Publikované 28. decembra 2025).