Pozn. přek.: Hlavní inženýr společnosti Zalando, Henning Jacobs, si několikrát všiml u uživatelů Kubernetes problémy s pochopením účelu liveness (a readiness) probes a jejich správné aplikace. Proto shromáždil své myšlenky v této stručné poznámce, která se časem stane součástí dokumentace K8s.

Kontrolní mechanismy, známé v Kubernetes jako liveness probes (tj. doslova „testy životaschopnosti“ — pozn. překl.), mohou být poměrně nebezpečné. Doporučuji se jim vyhnout, pokud je to možné: výjimkou jsou pouze případy, kdy jsou skutečně nezbytné a vy plně rozumíte specifikům a důsledkům jejich použití. V tomto příspěvku se budeme zabývat liveness a readiness kontrolami a také se dozvíte, kdy je vhodné a není vhodné je používat.
Můj kolega Sandor nedávno sdílel na Twitteru nejčastější chyby, se kterými se setkává, včetně těch, které souvisejí s použitím readiness/liveness probes:
Špatně nastavená livenessProbe může zhoršit situace s vysokým zatížením (lavinové vypínání + potenciálně dlouhé spuštění kontejneru/aplikace) a vést k dalším negativním následkům, jako je pád závislostí (viz také o omezení počtu požadavků v kombinaci K3s+ACME). Ještě horší je, když se liveness probe kombinuje s kontrolou zdraví závislosti (health check), kterou představuje externí databáze: jediný výpadek DB restartuje všechny vaše kontejnery!
Obecné poselství „Nepoužívejte liveness probes“ v tomto případě moc nepomáhá, proto se podívejme, k čemu slouží readiness a liveness kontroly.
Poznámka: většina níže uvedeného testu byla původně zahrnuta do interní dokumentace pro vývojáře společnosti Zalando.
Kontroly Readiness a Liveness
Kubernetes poskytuje dva důležité mechanismy, nazývané . Ty pravidelně provádějí nějakou akci — například posílají HTTP požadavek, otevírají TCP spojení nebo vykonávají příkaz v kontejneru — aby potvrdily, že aplikace funguje správně.
Kubernetes používá readiness probes, abychom pochopili, kdy je kontejner připraven přijímat provoz. Pod se považuje za připravený k práci, pokud jsou všechny jeho kontejnery připraveny. Jedním z využití tohoto mechanismu je kontrolovat, které pody jsou používány jako backendy pro služby Kubernetes (zejména Ingress).
Zdravotní kontroly pomáhají Kubernetes pochopit, kdy je čas restartovat kontejner. Například taková kontrola umožňuje zachytit deadlock, kdy se aplikace „zasekne“ na jednom místě. Restart kontejneru v takovém stavu pomáhá posunout aplikaci z mrtvého bodu, i přes chyby, může však také vést k kaskádovým selháním (viz níže).
Pokud se pokusíte provést nasazení aktualizace aplikace, které selže v kontrolách zdraví/připravenosti, jeho nasazení se zastaví, protože Kubernetes bude čekat na status Ready od všech podů.
Příklad
Zde je příklad kontroly připravenosti, která kontroluje cestu /health přes HTTP s výchozími nastaveními (interval: 10 sekund, timeout: 1 sekunda, úspěšný práh: 1, nesprávný práh: 3):
# часть общего описания deployment'а/стека
podTemplate:
spec:
containers:
- name: my-container
# ...
readinessProbe:
httpGet:
path: /health
port: 8080Doporučení
- Pro mikroslužby s HTTP endpointem (REST atd.) vždy určete kontrolu připravenosti, která ověřuje, zda je aplikace (pod) připravena přijímat provoz.
- Zajistěte, aby kontrola připravenosti pokryla připravenost skutečného portu webového serveru:
- používající porty pro administrativní potřeby, nazývané „admin“ nebo „management“ (například 9090), pro
readinessProbe, zajistěte, aby endpoint vracel OK pouze v případě, že je hlavní HTTP port (například 8080) připraven přijímat provoz*;* Vím alespoň o jednom případě v Zalando, kdy se to nestalo, tedy
readinessProbezkontroloval port „management“, ale samotný server se vůbec nezačal načítat kvůli problémům s načítáním cache. - připevnění kontroly připravenosti na samostatný port může vést k tomu, že přetížení na hlavním portu nebude odráženo v health checku (to znamená, že pool vláken na serveru je plný, přesto health check stále ukazuje, že je vše v pořádku).
- používající porty pro administrativní potřeby, nazývané „admin“ nebo „management“ (například 9090), pro
- Ujistěte se, že kontrola připravenosti zahrnuje inicializaci/migraci databáze;
- nejjednodušší způsob, jak toho dosáhnout, je volat HTTP server až po dokončení inicializace (například migrace DB s atd.); tedy místo toho, abyste měnili status health checku, prostě nespouštějte webový server až do dokončení migrace DB*.
* Můžete také spouštět migrace databáze z init kontejnerů vně podu. Stále jsem zastáncem samostatných aplikací, což znamená, že kontejner aplikace ví, jak uvést databázi do požadovaného stavu bez vnější koordinace.
- nejjednodušší způsob, jak toho dosáhnout, je volat HTTP server až po dokončení inicializace (například migrace DB s atd.); tedy místo toho, abyste měnili status health checku, prostě nespouštějte webový server až do dokončení migrace DB*.
- Použijte
httpGetpro readiness kontroly prostřednictvím typických endpointů health checků (například,/health). - Zjistěte parametry kontrol, které jsou nastaveny jako výchozí. (
interval: 10s,timeout: 1s,successThreshold: 1,failureThreshold: 3):- výchozí parametry znamenají, že pod se stane not-ready přibližně za 30 sekund (3 neúspěšné kontroly provozuschopnosti).
- Použijte samostatný port pro „admin“ nebo „management“, pokud technologický stack (například Java/Spring) to umožňuje, abyste oddělili správu „zdraví“ a metriky od běžného provozu:
- ale nezapomeňte na bod 2.
- Pokud je to nutné, můžete readiness probe použít k vyhřátí/zátěžování cache a vracet stavový kód 503, dokud se kontejner ne „vyhřeje“:
- také doporučuji se seznámit s novou kontrolou
startupProbe, (psali jsme o ní v ruštině, — pozn. překl.).
- také doporučuji se seznámit s novou kontrolou
Upozornění
- Nespoléhejte se na vnější závislosti (například datové úložiště) při provádění testů na readiness/liveness — to může vést k kaskádovým poruchám:
- jako příklad vezměme stateful službu REST s 10 pody závislými na jedné databázi Postgres: když kontrola závisí na funkčním připojení k databázi, všech 10 podů může spadnout, pokud dojde k zpoždění v síti/na straně databáze — obvykle to končí hůře, než by mělo;
- všimněte si, že Spring Data ve výchozím nastavení kontroluje připojení k databázi*;
* Toto je chování výchozího nastavení Spring Data Redis (alespoň takové to bylo, když jsem to naposledy kontroloval), což vedlo k „katastrofickému“ selhání: když byl Redis na krátkou dobu nedostupný, všechny podu „spadly“.
- „vnější“ v tomto smyslu může také znamenat jiné pody stejné aplikace, což by ideálně znamenalo, že kontrola by neměla záviset na stavu jiných podů ve stejné skupině, aby se předešlo kaskádovým pádům:
- výsledky se mohou lišit pro aplikace s distribuovaným stavem (například in-memory caching v podech).
- Nepoužívejte liveness probe pro pody (výjimkou jsou případy, kdy jsou opravdu potřebné a vy si plně uvědomujete specifika a důsledky jejich použití):
- liveness probe může podpořit obnovení "zaseknutých" kontejnerů, ale protože máte plnou kontrolu nad svou aplikací, ideálně by se měly vyhnout takovým věcem, jako jsou "zaseknuté" procesy a deadlocky; nejlepší alternativou je záměrný pád aplikace a její návrat do předchozího stabilního stavu;
- neúspěšná liveness probe povede k restartu kontejneru, což může potenciálně zhoršit důsledky chyb spojených s načítáním: restart kontejneru způsobí prostoje (alespoň po dobu spuštění aplikace, řekněme, více než 30 sekund), což vyvolá nové chyby, zvyšuje zátěž na další kontejnery a zvyšuje pravděpodobnost jejich selhání, atd.;
- liveness kontroly v kombinaci s externími závislostmi jsou nejhorší možná kombinace, hrozící kaskádovými selháními: drobné zpoždění na straně databáze povede k restartu všech vašich kontejnerů!
- Parametry liveness a readiness kontrol by měly být odlišné:
- liveness probe lze použít se stejnou health check, ale s vyšším prahovým spínáním (
failureThreshold), například přiřadit stav not-ready po 3 pokusech a považovat, že liveness probe selhala po 10 pokusech;
- liveness probe lze použít se stejnou health check, ale s vyšším prahovým spínáním (
- Nepoužívejte exec kontroly, protože s nimi souvisejí známé problémy, které vedou k vzniku zombie procesů:
- podrobnosti: viz .
Shrnutí
- Používejte readiness probes, abyste určili, kdy je pod připraven k přijímání provozu.
- Používejte liveness probes pouze tehdy, když jsou skutečně potřebné.
- Nesprávné použití readiness/liveness probes může vést ke snížení dostupnosti a kaskádovým selháním.
Další materiály k tématu
- ;
- ;
- (vypráví také o livenessProbe).
Aktualizace č. 1 ze dne 2019-09-29
: přidána poznámka.
o PDB: jedna z bolestí liveness kontrol je nedostatek koordinace mezi pody. V Kubernetes existují k omezení počtu paralelních selhání, které může aplikace zažít, ale kontroly nezohledňují PDB. Ideálně bychom mohli nařídit K8s: "Restartuj jeden pod, pokud jeho kontrola selže, ale neopakuj je všechny, abychom to nezhoršili."
: „Použijte liveness probe, když si jste jisti, že to nejlepší, co můžete udělat, je „zabít“ aplikaci“ (opět, příliš to nepřehánějte).
Aktualizace č. 2 z 29. 9. 2019
: vytvořil jsem odpovídající žádost () na doplnění dokumentace o liveness probes.
P.S. od překladatele
Přečtěte si také náš blog:
- «»;
- «»;
- «».
Zdroj: habr.com
