Osvedčené postupy pre kontajnery Kubernetes: kontroly stavu

Osvedčené postupy pre kontajnery Kubernetes: kontroly stavu

TL; DR

  • Na dosiahnutie vysokej pozorovateľnosti kontajnerov a mikroslužieb nestačia protokoly a primárne metriky.
  • Pre rýchlejšie zotavenie a zvýšenú odolnosť by aplikácie mali uplatňovať princíp vysokej pozorovateľnosti (HOP).
  • Na aplikačnej úrovni NOP vyžaduje: správne protokolovanie, dôkladné monitorovanie, kontroly zdravého rozumu a sledovanie výkonu/prechodu.
  • Použite šeky ako prvok NOR pripravenosť Sonda и živosť Sonda Kubernetes.

Čo je to šablóna zdravotnej kontroly?

Pri navrhovaní kritickej a vysoko dostupnej aplikácie je veľmi dôležité myslieť na taký aspekt, ako je odolnosť voči chybám. Aplikácia sa považuje za odolnú voči chybám, ak sa rýchlo zotaví zo zlyhania. Typická cloudová aplikácia využíva architektúru mikroslužieb – kde je každý komponent umiestnený v samostatnom kontajneri. A aby ste sa uistili, že aplikácia na k8s je pri navrhovaní klastra vysoko dostupná, musíte postupovať podľa určitých vzorov. Medzi nimi je šablóna zdravotnej kontroly. Definuje, ako aplikácia komunikuje s k8, že je zdravá. Nejde len o informácie o tom, či modul beží, ale aj o tom, ako prijíma požiadavky a ako na ne reaguje. Čím viac Kubernetes vie o stave modulu, tým inteligentnejšie rozhodnutia robí o smerovaní prevádzky a vyrovnávaní zaťaženia. Princíp vysokej pozorovateľnosti teda umožňuje aplikácii reagovať na požiadavky včas.

Princíp vysokej pozorovateľnosti (HOP)

Princíp vysokej pozorovateľnosti je jedným z princípy navrhovania kontajnerových aplikácií. V architektúre mikroslužieb sa služby nestarajú o to, ako sa ich požiadavka spracuje (a je to tak správne), ale dôležité je, ako dostanú odpovede od prijímajúcich služieb. Napríklad na overenie používateľa jeden kontajner odošle požiadavku HTTP druhému, pričom očakáva odpoveď v určitom formáte – to je všetko. PythonJS môže tiež spracovať požiadavku a Python Flask môže odpovedať. Kontajnery sú navzájom ako čierne skrinky so skrytým obsahom. Princíp NOP však vyžaduje, aby každá služba odhalila viacero koncových bodov API, ktoré indikujú, ako je zdravá, ako aj jej pripravenosť a stav odolnosti voči chybám. Kubernetes požaduje tieto indikátory, aby si premyslel ďalšie kroky smerovania a vyrovnávania záťaže.

Dobre navrhnutá cloudová aplikácia zaznamenáva svoje hlavné udalosti pomocou štandardných I/O streamov STDERR a STDOUT. Ďalej prichádza pomocná služba, napríklad filebeat, logstash alebo fluentd, doručovanie protokolov do centralizovaného monitorovacieho systému (napríklad Prometheus) a systému zberu protokolov (softvérový balík ELK). Nižšie uvedený diagram ukazuje, ako cloudová aplikácia funguje podľa vzoru zdravotného testu a princípu vysokej pozorovateľnosti.

Osvedčené postupy pre kontajnery Kubernetes: kontroly stavu

Ako použiť vzor kontroly stavu v Kubernetes?

Po vybalení monitor k8s monitoruje stav modulov pomocou jedného z ovládačov (rozmiestnenie, ReplicaSets, DaemonSets, Stavové sady atď., atď.). Po zistení, že modul z nejakého dôvodu spadol, sa ho ovládač pokúsi reštartovať alebo presunúť do iného uzla. Modul však môže hlásiť, že je v prevádzke, ale sám nefunguje. Uveďme príklad: vaša aplikácia používa Apache ako webový server, komponent ste nainštalovali na niekoľko modulov klastra. Keďže knižnica bola nakonfigurovaná nesprávne, všetky požiadavky na aplikáciu odpovedajú kódom 500 (interná chyba servera). Pri kontrole dodávky poskytuje kontrola stavu strukov úspešný výsledok, ale zákazníci si myslia inak. Túto nežiaducu situáciu popíšeme nasledovne:

Osvedčené postupy pre kontajnery Kubernetes: kontroly stavu

V našom príklade to robí k8s kontrola funkčnosti. Pri tomto type overovania kubelet priebežne kontroluje stav procesu v nádobe. Keď pochopí, že sa proces zastavil, reštartuje ho. Ak je možné chybu vyriešiť jednoduchým reštartovaním aplikácie a program je navrhnutý tak, aby sa pri akejkoľvek chybe vypol, potom je kontrola stavu procesu všetko, čo potrebujete podľa NOP a vzoru zdravotného testu. Jediná škoda je, že nie všetky chyby sa reštartovaním odstránia. V tomto prípade ponúka k8s 2 hlbšie spôsoby identifikácie problémov s modulom: živosť Sonda и pripravenosť Sonda.

LivenessProbe

Počas živosť Sonda kubelet vykonáva 3 typy kontrol: nielen zisťuje, či je modul spustený, ale aj to, či je pripravený prijímať a primerane reagovať na požiadavky:

  • Nastavte požiadavku HTTP na modul. Odpoveď musí obsahovať kód odpovede HTTP v rozsahu od 200 do 399. Kódy 5xx a 4xx teda signalizujú, že modul má problémy, aj keď je proces spustený.
  • Ak chcete testovať moduly so službami, ktoré nie sú HTTP (napríklad poštový server Postfix), musíte vytvoriť pripojenie TCP.
  • Vykonajte ľubovoľný príkaz pre modul (interne). Kontrola sa považuje za úspešnú, ak je kód dokončenia príkazu 0.

Príklad, ako to funguje. Ďalšia definícia pod obsahuje aplikáciu NodeJS, ktorá pri HTTP požiadavkách vyvolá chybu 500. Aby sme sa uistili, že kontajner sa pri prijatí takejto chyby reštartuje, používame parameter 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

Toto sa nelíši od akejkoľvek inej definície modulu, ale pridávame objekt .spec.containers.livenessProbe. Parameter httpGet akceptuje cestu, na ktorú sa odošle požiadavka HTTP GET (v našom príklade to je /, ale v bojových scenároch môže byť niečo ako /api/v1/status). Iná živosťProbe akceptuje parameter initialDelaySeconds, ktorý prikáže verifikačnej operácii počkať určitý počet sekúnd. Oneskorenie je potrebné, pretože kontajner potrebuje čas na spustenie a po reštartovaní bude nejaký čas nedostupný.

Ak chcete použiť toto nastavenie na klaster, použite:

kubectl apply -f pod.yaml

Po niekoľkých sekundách môžete obsah podložky skontrolovať pomocou nasledujúceho príkazu:

kubectl describe pods node500

Na konci výstupu nájdite to je čo.

Ako môžete vidieť, livenessProbe inicioval požiadavku HTTP GET, kontajner vygeneroval chybu 500 (na čo bol naprogramovaný) a kubelet ho reštartoval.

Ak vás zaujíma, ako bola naprogramovaná aplikácia NideJS, tu sú použité súbory 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 uvedomiť toto: livenessProbe reštartuje kontajner iba vtedy, ak zlyhá. Ak reštart neopraví chybu, ktorá bráni spusteniu kontajnera, kubelet nebude môcť vykonať akciu na odstránenie problému.

pripravenosť Sonda

readinessProbe funguje podobne ako livenessProbes (požiadavky GET, komunikácia TCP a vykonávanie príkazov), s výnimkou akcií pri riešení problémov. Kontajner, v ktorom sa zistí porucha, sa nereštartuje, ale je izolovaný od prichádzajúcej prevádzky. Predstavte si, že jeden z kontajnerov vykonáva veľa výpočtov alebo je veľmi zaťažený, čo spôsobuje predĺženie doby odozvy. V prípade livenessProbe sa spustí kontrola dostupnosti odpovede (cez parameter kontroly timeoutSeconds), po ktorej kubelet reštartuje kontajner. Po spustení kontajner začne vykonávať úlohy náročné na zdroje a znova sa reštartuje. To môže byť rozhodujúce pre aplikácie, ktoré vyžadujú rýchlosť odozvy. Napríklad auto na ceste čaká na odpoveď zo servera, odpoveď sa oneskorí – a auto sa stane nehodou.

Napíšme definíciu redinessProbe, ktorá nastaví čas odozvy požiadavky GET na maximálne dve sekundy a aplikácia odpovie na požiadavku GET po 5 sekundách. Súbor pod.yaml by mal vyzerať 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čkajme pár sekúnd a potom uvidíme, ako funguje ReadinessProbe:

kubectl describe pods nodedelayed

Na konci výstupu môžete vidieť, že niektoré udalosti sú podobné toto.

Ako vidíte, kubectl nereštartoval modul, keď čas kontroly presiahol 2 sekundy. Namiesto toho žiadosť zrušil. Prichádzajúca komunikácia je presmerovaná na iné, pracovné moduly.

Všimnite si, že teraz, keď je modul stiahnutý, kubectl naň znova smeruje požiadavky: odpovede na požiadavky GET už nie sú oneskorené.

Pre porovnanie, nižšie je upravený súbor 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
Pred príchodom cloudových aplikácií boli protokoly primárnym prostriedkom na monitorovanie a kontrolu stavu aplikácií. Neexistovali však žiadne prostriedky na vykonanie nápravných opatrení. Protokoly sú užitočné aj dnes, je potrebné ich zhromažďovať a odosielať do systému zberu protokolov na analýzu núdzových situácií a prijímanie rozhodnutí. [To všetko by sa dalo urobiť bez cloudových aplikácií napríklad pomocou monitu, ale s k8s to bolo oveľa jednoduchšie :) – pozn. ]

Dnes sa opravy musia robiť takmer v reálnom čase, takže aplikácie už nemusia byť čiernymi skrinkami. Nie, mali by zobrazovať koncové body, ktoré umožňujú monitorovacím systémom dotazovať sa a zbierať cenné údaje o stave procesov, aby mohli v prípade potreby okamžite reagovať. Toto sa nazýva návrhový vzor testu výkonnosti, ktorý sa riadi princípom vysokej pozorovateľnosti (HOP).

Kubernetes štandardne ponúka 2 typy zdravotných kontrol: readinessProbe a livenessProbe. Obidve používajú rovnaké typy kontrol (požiadavky HTTP GET, komunikácia TCP a vykonávanie príkazov). Líšia sa v tom, aké rozhodnutia robia v reakcii na problémy v strukoch. livenessProbe reštartuje kontajner v nádeji, že sa chyba nebude opakovať, a readinessProbe izoluje modul od prichádzajúcej prevádzky, kým sa príčina problému nevyrieši.

Správny návrh aplikácie by mal zahŕňať oba typy kontroly a zabezpečiť, aby zhromažďovali dostatok údajov, najmä keď je vyvolaná výnimka. Mal by tiež zobrazovať potrebné koncové body API, ktoré poskytujú monitorovaciemu systému (Prometheus) dôležité zdravotné metriky.

Zdroj: hab.com

Pridať komentár