Osvědčené postupy pro kontejnery Kubernetes: Kontroly stavu

Osvědčené postupy pro kontejnery Kubernetes: Kontroly stavu

TL, DR

  • K dosažení vysoké pozorovatelnosti kontejnerů a mikroslužeb nestačí protokoly a primární metriky.
  • Pro rychlejší obnovu a zvýšenou odolnost by aplikace měly používat princip vysoké observability (HOP).
  • Na aplikační úrovni NOP vyžaduje: správné protokolování, pečlivé sledování, kontroly zdravého rozumu a sledování výkonu/přechodu.
  • Použijte kontroly jako prvek NOR připravenostProbe и živost Sonda Kubernetes.

Co je to šablona zdravotní kontroly?

Při navrhování kritické a vysoce dostupné aplikace je velmi důležité myslet na takový aspekt, jako je odolnost proti chybám. Aplikace je považována za odolnou proti chybám, pokud se rychle zotaví ze selhání. Typická cloudová aplikace využívá architekturu mikroslužeb – kde je každá komponenta umístěna v samostatném kontejneru. A abyste se ujistili, že aplikace na k8s bude při navrhování clusteru vysoce dostupná, musíte dodržovat určité vzorce. Mezi nimi je šablona zdravotní kontroly. Definuje, jak aplikace komunikuje s k8s, že je zdravá. Nejde jen o informace o tom, zda modul běží, ale také o tom, jak přijímá požadavky a odpovídá na ně. Čím více Kubernetes ví o stavu modulu, tím chytřejší rozhodnutí činí o směrování provozu a vyrovnávání zátěže. Princip vysoké pozorovatelnosti tedy umožňuje aplikaci reagovat na požadavky včas.

Princip vysoké pozorovatelnosti (HOP)

Princip vysoké pozorovatelnosti je jedním z principy pro navrhování kontejnerových aplikací. V architektuře mikroslužeb se služby nestarají o to, jak je jejich požadavek zpracován (a je to tak správně), ale důležité je, jak přijímají odpovědi od přijímajících služeb. Například pro ověření uživatele jeden kontejner odešle požadavek HTTP druhému, přičemž očekává odpověď v určitém formátu – to je vše. PythonJS může také zpracovat požadavek a Python Flask může odpovědět. Kontejnery jsou navzájem jako černé skříňky se skrytým obsahem. Princip NOP však vyžaduje, aby každá služba odhalila více koncových bodů API, které indikují, jak je zdravá, a také její připravenost a stav odolnosti proti chybám. Kubernetes požaduje tyto indikátory, aby promyslel další kroky pro směrování a vyrovnávání zátěže.

Dobře navržená cloudová aplikace zaznamenává své hlavní události pomocí standardních I/O streamů STDERR a STDOUT. Následuje pomocná služba, například filebeat, logstash nebo fluentd, doručující protokoly do centralizovaného monitorovacího systému (např. Prometheus) a systému sběru protokolů (softwarová sada ELK). Níže uvedený diagram ukazuje, jak cloudová aplikace funguje podle vzoru zdravotního testu a principu vysoké pozorovatelnosti.

Osvědčené postupy pro kontejnery Kubernetes: Kontroly stavu

Jak použít vzor kontroly stavu v Kubernetes?

K8s ihned po vybalení monitoruje stav modulů pomocí jednoho z ovladačů (Nasazení, ReplicaSets, DaemonSets, Stavové sady atd., atd.). Po zjištění, že modul z nějakého důvodu spadl, se ovladač pokusí jej restartovat nebo přesunout do jiného uzlu. Modul však může hlásit, že je v provozu, ale sám nefunguje. Uveďme příklad: vaše aplikace používá Apache jako webový server, komponentu jste nainstalovali na několik podů clusteru. Protože knihovna byla nakonfigurována nesprávně, všechny požadavky na aplikaci reagují kódem 500 (interní chyba serveru). Při kontrole dodávky poskytuje kontrola stavu lusků úspěšný výsledek, ale zákazníci uvažují jinak. Tuto nežádoucí situaci popíšeme následovně:

Osvědčené postupy pro kontejnery Kubernetes: Kontroly stavu

V našem příkladu k8s ano kontrola funkčnosti. Při tomto typu ověřování kubelet průběžně kontroluje stav procesu v nádobě. Jakmile pochopí, že se proces zastavil, znovu jej spustí. Pokud lze chybu vyřešit jednoduchým restartováním aplikace a program je navržen tak, aby se při jakékoli chybě vypnul, pak je kontrola stavu procesu vše, co potřebujete podle NOP a vzoru testu stavu. Jediná škoda je, že ne všechny chyby se restartem odstraní. V tomto případě k8s nabízí 2 hlubší způsoby, jak identifikovat problémy s pod: živost Sonda и připravenostProbe.

LivenessProbe

Během živost Sonda kubelet provádí 3 typy kontrol: nejen zjišťuje, zda je modul spuštěný, ale také zda je připraven přijímat a adekvátně reagovat na požadavky:

  • Nastavte požadavek HTTP na modul. Odpověď musí obsahovat kód odezvy HTTP v rozsahu od 200 do 399. Kódy 5xx a 4xx tedy signalizují, že modul má problémy, i když proces běží.
  • Chcete-li testovat moduly se službami, které nejsou HTTP (například poštovní server Postfix), musíte vytvořit připojení TCP.
  • Spusťte libovolný příkaz pro modul (interně). Kontrola je považována za úspěšnou, pokud je kód dokončení příkazu 0.

Příklad, jak to funguje. Další definice podu obsahuje aplikaci NodeJS, která u požadavků HTTP vyvolá chybu 500. Abychom se ujistili, že se kontejner při přijetí takové chyby restartuje, použijeme parametr livenessProbe:

apiVersion: v1
kind: Pod
metadata:
 name: node500
spec:
 containers:
   - image: magalix/node500
     name: node500
     ports:
       - containerPort: 3000
         protocol: TCP
     livenessProbe:
       httpGet:
         path: /
         port: 3000
       initialDelaySeconds: 5

To se neliší od jakékoli jiné definice podu, ale přidáváme objekt .spec.containers.livenessProbe. Parametr httpGet přijímá cestu, na kterou je odeslán požadavek HTTP GET (v našem příkladu to je /, ale v bojových scénářích může být něco jako /api/v1/status). Další livenessProbe přijímá parametr initialDelaySeconds, který nařídí ověřovací operaci, aby počkala zadaný počet sekund. Zpoždění je nutné, protože kontejner potřebuje čas ke spuštění a po restartu bude nějakou dobu nedostupný.

Chcete-li toto nastavení použít na cluster, použijte:

kubectl apply -f pod.yaml

Po několika sekundách můžete zkontrolovat obsah podu pomocí následujícího příkazu:

kubectl describe pods node500

Na konci výstupu najděte to je co.

Jak můžete vidět, livenessProbe inicioval požadavek HTTP GET, kontejner vygeneroval chybu 500 (k čemuž byl naprogramován) a kubelet jej restartoval.

Pokud vás zajímá, jak byla naprogramována aplikace NideJS, zde jsou použité soubory app.js a Dockerfile:

app.js

var http = require('http');

var server = http.createServer(function(req, res) {
    res.writeHead(500, { "Content-type": "text/plain" });
    res.end("We have run into an errorn");
});

server.listen(3000, function() {
    console.log('Server is running at 3000')
})

dockerfile

FROM node
COPY app.js /
EXPOSE 3000
ENTRYPOINT [ "node","/app.js" ]

Je důležité si uvědomit toto: livenessProbe restartuje kontejner pouze v případě, že selže. Pokud restartování neopraví chybu, která brání spuštění kontejneru, kubelet nebude schopen provést akci k nápravě problému.

připravenostProbe

readinessProbe funguje podobně jako livenessProbes (požadavky GET, komunikace TCP a provádění příkazů), s výjimkou akcí pro odstraňování problémů. Kontejner, ve kterém je zjištěna chyba, není restartován, ale je izolován od příchozího provozu. Představte si, že jeden z kontejnerů provádí mnoho výpočtů nebo je pod velkým zatížením, což způsobuje prodloužení doby odezvy. V případě livenessProbe se spustí kontrola dostupnosti odpovědi (pomocí parametru kontroly timeoutSeconds), po které kubelet restartuje kontejner. Po spuštění kontejner začne provádět úlohy náročné na zdroje a znovu se restartuje. To může být kritické pro aplikace, které vyžadují rychlost odezvy. Například auto na silnici čeká na odpověď ze serveru, odpověď je zpožděná – a auto se stane nehodou.

Pojďme napsat definici redinessProbe, která nastaví dobu odezvy požadavku GET na maximálně dvě sekundy a aplikace na požadavek GET odpoví po 5 sekundách. Soubor pod.yaml by měl vypadat takto:

apiVersion: v1
kind: Pod
metadata:
 name: nodedelayed
spec:
 containers:
   - image: afakharany/node_delayed
     name: nodedelayed
     ports:
       - containerPort: 3000
         protocol: TCP
     readinessProbe:
       httpGet:
         path: /
         port: 3000
       timeoutSeconds: 2

Nasadíme pod s kubectl:

kubectl apply -f pod.yaml

Počkejme pár sekund a pak uvidíme, jak ReadinessProbe fungoval:

kubectl describe pods nodedelayed

Na konci výstupu můžete vidět, že některé události jsou podobné tento.

Jak můžete vidět, kubectl nerestartoval modul, když doba kontroly přesáhla 2 sekundy. Místo toho žádost zrušil. Příchozí komunikace jsou přesměrovány na jiné, fungující moduly.

Všimněte si, že nyní, když je modul vyložen, kubectl na něj znovu směruje požadavky: odpovědi na požadavky GET již nejsou zdržovány.

Pro srovnání níže je upravený soubor app.js:

var http = require('http');

var server = http.createServer(function(req, res) {
   const sleep = (milliseconds) => {
       return new Promise(resolve => setTimeout(resolve, milliseconds))
   }
   sleep(5000).then(() => {
       res.writeHead(200, { "Content-type": "text/plain" });
       res.end("Hellon");
   })
});

server.listen(3000, function() {
   console.log('Server is running at 3000')
})

TL, DR
Před příchodem cloudových aplikací byly protokoly primárním prostředkem sledování a kontroly stavu aplikací. Neexistovaly však žádné prostředky k provedení nápravných opatření. Protokoly jsou užitečné i dnes, je třeba je shromažďovat a odesílat do systému sběru protokolů pro analýzu nouzových situací a rozhodování. [To vše šlo udělat bez cloudových aplikací třeba pomocí monitu, ale s k8s to bylo mnohem jednodušší :) – pozn. ]

Dnes se musí korekce provádět téměř v reálném čase, takže aplikace už nemusí být černé skříňky. Ne, měly by ukazovat koncové body, které umožňují monitorovacím systémům dotazovat se a shromažďovat cenná data o stavu procesů, aby mohly v případě potřeby okamžitě reagovat. Toto se nazývá návrhový vzor testu výkonnosti, který se řídí principem vysoké pozorovatelnosti (HOP).

Kubernetes ve výchozím nastavení nabízí 2 typy zdravotních kontrol: readinessProbe a livenessProbe. Oba používají stejné typy kontrol (požadavky HTTP GET, komunikace TCP a provádění příkazů). Liší se v tom, jaká rozhodnutí dělají v reakci na problémy v luscích. livenessProbe restartuje kontejner v naději, že se chyba nebude opakovat, a readinessProbe izoluje modul od příchozího provozu, dokud se nevyřeší příčina problému.

Správný návrh aplikace by měl zahrnovat oba typy kontroly a zajistit, aby shromažďovaly dostatek dat, zvláště když je vyvolána výjimka. Měl by také ukazovat potřebné koncové body API, které poskytují monitorovacímu systému (Prometheus) důležité zdravotní metriky.

Zdroj: www.habr.com

Přidat komentář