Sondy živosti v Kubernetes mohou být nebezpečné

Poznámka. přel.: Vedoucí inženýr ze Zalanda, Henning Jacobs, si opakovaně všiml problémů mezi uživateli Kubernetes v pochopení účelu sond živosti (a připravenosti) a jejich správného použití. Své myšlenky proto shromáždil v této prostorné poznámce, která se nakonec stane součástí dokumentace K8s.

Sondy živosti v Kubernetes mohou být nebezpečné

Zdravotní kontroly, známé v Kubernetes jako sondy živosti (tj. doslova „testy životaschopnosti“ - přibližně překlad.), může být docela nebezpečné. Doporučuji se jim pokud možno vyhnout: výjimkou jsou pouze případy, kdy jsou skutečně nutné a jste si plně vědomi specifik a důsledků jejich použití. Tato publikace bude hovořit o kontrolách živosti a připravenosti a také vám řekne, v jakých případech je a neměli byste je používat.

Můj kolega Sandor nedávno na Twitteru sdílel nejčastější chyby, se kterými se setkává, včetně těch, které souvisí s používáním sond připravenosti/živosti:

Sondy živosti v Kubernetes mohou být nebezpečné

Nesprávně nakonfigurováno livenessProbe může zhoršit situace s vysokým zatížením (vypnutí sněhové koule + potenciálně dlouhý čas spuštění kontejneru/aplikace) a vést k dalším negativním důsledkům, jako je pokles závislosti (viz také můj nedávný článek o omezení počtu požadavků v kombinaci K3s+ACME). Ještě horší je, když je sonda živosti kombinována s kontrolou stavu, což je externí databáze: jediné selhání DB restartuje všechny vaše kontejnery!

Obecná zpráva "Nepoužívejte sondy živosti" v tomto případě to moc nepomůže, tak se podívejme, k čemu slouží kontroly připravenosti a životnosti.

Poznámka: Většina níže uvedeného testu byla původně zahrnuta do interní vývojářské dokumentace Zalanda.

Kontroly připravenosti a živosti

Kubernetes poskytuje dva důležité mechanismy tzv sondy živosti a sondy připravenosti. Pravidelně provádějí nějakou akci – jako je odeslání požadavku HTTP, otevření připojení TCP nebo provedení příkazu v kontejneru – aby potvrdili, že aplikace funguje podle očekávání.

Kubernetes používá sondy připravenostiabyste pochopili, kdy je kontejner připraven přijmout provoz. Pod je považován za připravený k použití, pokud jsou připraveny všechny jeho nádoby. Jedním z použití tohoto mechanismu je řídit, které moduly se používají jako backendy pro služby Kubernetes (a zejména Ingress).

Sondy živosti pomozte Kubernetes pochopit, kdy je čas restartovat kontejner. Taková kontrola například umožňuje zachytit uváznutí, když se aplikace zasekne na jednom místě. Restartování kontejneru v tomto stavu pomáhá spustit aplikaci navzdory chybám, ale může také vést ke kaskádovým selháním (viz níže).

Pokud se pokusíte nasadit aktualizaci aplikace, která neprojde kontrolami životnosti/připravenosti, její zavádění se zastaví, protože Kubernetes čeká na stav Ready ze všech lusků.

příklad

Zde je příklad sondy připravenosti, která kontroluje cestu /health přes HTTP s výchozím nastavením (interval: 10 sekund, timeout: 1 sekunda, práh úspěchu: 1, práh selhání: 3):

# часть общего описания deployment'а/стека
podTemplate:
  spec:
    containers:
    - name: my-container
      # ...
      readinessProbe:
        httpGet:
          path: /health
          port: 8080

Doporučení

  1. Pro mikroslužby s koncovým bodem HTTP (REST atd.) vždy definujte sondu připravenosti, který kontroluje, zda je aplikace (pod) připravena přijímat provoz.
  2. Ujistěte se, že sonda připravenosti pokrývá dostupnost skutečného portu webového serveru:
    • používání portů pro administrativní účely, nazývané „admin“ nebo „management“ (například 9090), pro readinessProbe, ujistěte se, že koncový bod vrací OK pouze v případě, že je primární HTTP port (např. 8080) připraven přijímat provoz*;

      *Jsem si vědom minimálně jednoho případu v Zalandu, kde se tak nestalo, tzn. readinessProbe Zkontroloval jsem port „management“, ale samotný server nezačal fungovat kvůli problémům s načítáním mezipaměti.

    • připojení sondy připravenosti k samostatnému portu může vést k tomu, že přetížení hlavního portu se neprojeví ve kontrole stavu (tj. fond vláken na serveru je plný, ale kontrola stavu stále ukazuje, že je vše v pořádku ).
  3. Ujistit se, že připravenostní sonda umožňuje inicializaci/migraci databáze;
    • Nejjednodušší způsob, jak toho dosáhnout, je kontaktovat server HTTP až po dokončení inicializace (například migrace databáze z Průlet a tak dále.); to znamená, že místo změny stavu kontroly stavu jednoduše nespouštějte webový server, dokud není migrace databáze dokončena*.

      * Můžete také spustit migraci databáze z init kontejnerů mimo pod. Stále jsem příznivcem samostatných aplikací, tedy těch, ve kterých aplikační kontejner ví, jak bez vnější koordinace uvést databázi do požadovaného stavu.

  4. použití httpGet pro kontroly připravenosti prostřednictvím typických koncových bodů kontroly stavu (např. /health).
  5. Pochopte výchozí parametry kontroly (interval: 10s, timeout: 1s, successThreshold: 1, failureThreshold: 3):
    • výchozí možnosti znamenají, že pod se stane není připraven asi po 30 sekundách (3 neúspěšné kontroly zdravého rozumu).
  6. Použijte samostatný port pro „admin“ nebo „správu“, pokud to technologický zásobník (např. Java/Spring) umožňuje, abyste oddělili správu zdraví a metrik od běžného provozu:
    • ale nezapomeň na bod 2.
  7. V případě potřeby lze sondu připravenosti použít k zahřátí/načtení mezipaměti a vrátit stavový kód 503, dokud se kontejner nezahřeje:
    • Doporučuji také, abyste si přečetli nový šek startupProbe, objevil se ve verzi 1.16 (psali jsme o tom v ruštině zde - Cca. překlad.).

Upozornění

  1. Nespoléhejte na externí závislosti (jako jsou datové sklady) při spouštění testů připravenosti/životnosti – to může vést ke kaskádovým selháním:
    • Jako příklad si vezměme stavovou službu REST s 10 moduly v závislosti na jedné databázi Postgres: když kontrola závisí na funkčním připojení k DB, všech 10 modulů může selhat, pokud dojde ke zpoždění na straně sítě/DB – obvykle to všechno končí hůř, než by mohlo;
    • Vezměte prosím na vědomí, že Spring Data standardně kontroluje připojení k databázi*;

      * Toto je výchozí chování Spring Data Redis (alespoň to bylo naposledy, co jsem to kontroloval), což vedlo ke „katastrofickému“ selhání: když byl Redis na krátkou dobu nedostupný, všechny moduly „spadly“.

    • „externí“ v tomto smyslu může také znamenat jiné moduly stejné aplikace, to znamená, že v ideálním případě by kontrola neměla záviset na stavu jiných modulů stejného clusteru, aby se zabránilo kaskádovým haváriím:
      • výsledky se mohou u aplikací s distribuovaným stavem lišit (například ukládání do mezipaměti v podech).
  2. Nepoužívejte sondu živosti pro lusky (výjimkou jsou případy, kdy jsou skutečně nezbytné a jste si plně vědomi specifik a důsledků jejich použití):
    • Sonda životnosti může pomoci obnovit zavěšené kontejnery, ale protože máte plnou kontrolu nad svou aplikací, nemělo by v ideálním případě dojít k věcem, jako jsou zavěšené procesy a uváznutí: nejlepší alternativou je záměrně zhroucení aplikace a její uvedení zpět do předchozího ustáleného stavu;
    • selhání sondy životnosti způsobí restart kontejneru, čímž potenciálně zhorší následky chyb souvisejících s načítáním: restartování kontejneru bude mít za následek prostoj (alespoň po dobu spouštění aplikace, řekněme 30-lichých sekund), což způsobí nové chyby , zvýšení zatížení jiných kontejnerů a zvýšení pravděpodobnosti jejich selhání atd.;
    • kontroly životnosti v kombinaci s externí závislostí jsou nejhorší možnou kombinací, která hrozí kaskádovými selháními: malé zpoždění na straně databáze povede k restartu všech vašich kontejnerů!
  3. Parametry kontrol živosti a připravenosti musí být jiný:
    • můžete použít sondu živosti se stejnou kontrolou stavu, ale s vyšším prahem odezvy (failureThreshold), například přiřadit stav není připraven po 3 pokusech a uvažujte, že sonda živosti selhala po 10 pokusech;
  4. Nepoužívejte kontroly exec, protože jsou spojeny se známými problémy, které vedou ke vzniku zombie procesů:

Shrnutí

  • Pomocí sond připravenosti určete, kdy je modul připraven přijímat provoz.
  • Používejte sondy živosti pouze tehdy, když jsou skutečně potřeba.
  • Nesprávné použití sond připravenosti/životnosti může vést ke snížení dostupnosti a kaskádovým poruchám.

Sondy živosti v Kubernetes mohou být nebezpečné

Další materiály k tématu

Aktualizace č. 1 z 2019

O kontejnerech init pro migraci databáze: Přidána poznámka pod čarou.

EJ mi připomněl o PNR: jedním z problémů s kontrolami životnosti je nedostatečná koordinace mezi lusky. Kubernetes má Rozpočty narušení podu (PNR) omezit počet souběžných selhání, ke kterým může aplikace dojít, kontroly však neberou v úvahu PNR. V ideálním případě bychom mohli K8 říct: "Restartujte jeden modul, pokud jeho test selže, ale nerestartujte je všechny, aby se situace nezhoršila."

Bryan to vystihl dokonale: „Používejte sondování živosti, když přesně víte co nejlepší věc, kterou můžete udělat, je zabít aplikaci“ (opět se nenechte unést).

Sondy živosti v Kubernetes mohou být nebezpečné

Aktualizace č. 2 z 2019

Pokud jde o přečtení dokumentace před použitím: Vytvořil jsem odpovídající požadavek (budoucí žádost) přidat dokumentaci o sondách živosti.

PS od překladatele

Přečtěte si také na našem blogu:

Zdroj: www.habr.com

Přidat komentář