Najboljše prakse za vsebnike Kubernetes: pregledi stanja

Najboljše prakse za vsebnike Kubernetes: pregledi stanja

TL; DR

  • Da bi dosegli visoko opazljivost vsebnikov in mikrostoritev, dnevniki in primarne metrike niso dovolj.
  • Za hitrejše okrevanje in večjo odpornost morajo aplikacije uporabljati načelo visoke opaznosti (HOP).
  • Na ravni aplikacije NOP zahteva: pravilno beleženje, natančno spremljanje, preverjanje razumnosti in sledenje zmogljivosti/prehoda.
  • Uporabite čeke kot element NOR pripravljenost Sonda и živahnost Probe Kubernetes.

Kaj je predloga za pregled stanja?

Pri oblikovanju kritične in zelo razpoložljive aplikacije je zelo pomembno razmišljati o takem vidiku, kot je toleranca napak. Aplikacija velja za odporno na napake, če se po okvari hitro obnovi. Tipična aplikacija v oblaku uporablja arhitekturo mikrostoritev – kjer je vsaka komponenta nameščena v ločenem vsebniku. Da bi zagotovili visoko razpoložljivost aplikacije na k8s, ko oblikujete gručo, morate slediti določenim vzorcem. Med njimi je predloga za pregled stanja. Določa, kako aplikacija sporoči k8s, da je zdrava. To niso samo informacije o tem, ali pod deluje, ampak tudi o tem, kako sprejema zahteve in se odziva nanje. Bolj ko Kubernetes ve o zdravju sklopa, pametnejše odločitve sprejema o usmerjanju prometa in uravnoteženju obremenitve. Tako načelo visoke opazljivosti omogoča, da se aplikacija pravočasno odzove na zahteve.

Načelo visoke opaznosti (HOP)

Načelo visoke opazljivosti je eno od načela za načrtovanje kontejnerskih aplikacij. V arhitekturi mikrostoritev je storitvam vseeno, kako je njihova zahteva obdelana (in prav je tako), pomembno pa je, kako prejmejo odgovore od prejemnih storitev. Na primer, za avtentikacijo uporabnika en vsebnik pošlje zahtevo HTTP drugemu in pričakuje odgovor v določeni obliki - to je vse. PythonJS lahko tudi obdela zahtevo, Python Flask pa se lahko odzove. Zabojniki so kot črne skrinjice s skrito vsebino drug drugemu. Vendar pa načelo NOP zahteva, da vsaka storitev izpostavi več končnih točk API-ja, ki kažejo, kako zdrava je, pa tudi njeno stanje pripravljenosti in tolerance napak. Kubernetes zahteva te indikatorje, da lahko razmisli o naslednjih korakih za usmerjanje in uravnoteženje obremenitve.

Dobro zasnovana aplikacija v oblaku beleži svoje glavne dogodke z uporabo standardnih V/I tokov STDERR in STDOUT. Sledi pomožna storitev, na primer filebeat, logstash ali fluentd, ki dostavlja dnevnike v centraliziran nadzorni sistem (na primer Prometheus) in sistem za zbiranje dnevnikov (programska zbirka ELK). Spodnji diagram prikazuje, kako aplikacija v oblaku deluje v skladu s testnim vzorcem zdravja in načelom visoke opazljivosti.

Najboljše prakse za vsebnike Kubernetes: pregledi stanja

Kako uporabiti vzorec pregleda stanja v Kubernetesu?

K8s takoj po namestitvi nadzoruje stanje podov z enim od krmilnikov (Uvajanje, ReplicaSets, DaemonSets, StatefulSets itd. itd.). Ko odkrije, da je pod iz nekega razloga padel, ga krmilnik poskuša znova zagnati ali premakniti v drugo vozlišče. Vendar lahko enota sporoči, da deluje in deluje, sama pa ne deluje. Navedimo primer: vaša aplikacija uporablja Apache kot spletni strežnik, komponento ste namestili na več podov gruče. Ker je bila knjižnica nepravilno konfigurirana, se vse zahteve aplikaciji odzovejo s kodo 500 (notranja napaka strežnika). Pri preverjanju dostave preverjanje stanja strokov daje uspešen rezultat, kupci pa menijo drugače. To nezaželeno situacijo bomo opisali na naslednji način:

Najboljše prakse za vsebnike Kubernetes: pregledi stanja

V našem primeru to počne k8s preverjanje funkcionalnosti. Pri tej vrsti preverjanja kubelet nenehno preverja stanje procesa v vsebniku. Ko razume, da se je proces ustavil, ga bo znova zagnal. Če je napako mogoče odpraviti s preprostim ponovnim zagonom aplikacije in je program zasnovan tako, da se zaustavi ob kakršni koli napaki, potem je pregled zdravja procesa vse, kar potrebujete, da sledite NOP in vzorcu testa zdravja. Škoda je le, da se s ponovnim zagonom ne odpravijo vse napake. V tem primeru k8s ponuja 2 globlja načina za prepoznavanje težav s podom: živahnost Probe и pripravljenost Sonda.

LivenessProbe

V času živahnost Probe kubelet izvaja 3 vrste preverjanj: ne le ugotavlja, ali pod deluje, ampak tudi, ali je pripravljen sprejeti zahteve in se ustrezno odzvati nanje:

  • Nastavite zahtevo HTTP za pod. Odgovor mora vsebovati kodo odziva HTTP v razponu od 200 do 399. Tako kodi 5xx in 4xx signalizirata, da ima enota težave, čeprav se postopek izvaja.
  • Če želite preizkusiti pode s storitvami, ki niso HTTP (na primer poštni strežnik Postfix), morate vzpostaviti povezavo TCP.
  • Izvedite poljuben ukaz za pod (interno). Preverjanje se šteje za uspešno, če je koda zaključka ukaza 0.

Primer, kako to deluje. Naslednja definicija sklopa vsebuje aplikacijo NodeJS, ki pri zahtevah HTTP vrže napako 500. Za zagotovitev, da se vsebnik znova zažene, ko prejme takšno napako, uporabimo 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

To se ne razlikuje od katere koli druge definicije sklopa, vendar dodajamo objekt .spec.containers.livenessProbe... Parameter httpGet sprejme pot, na katero je poslana zahteva HTTP GET (v našem primeru je to /, toda v bojnih scenarijih je lahko nekaj podobnega /api/v1/status). Druga livenessProbe sprejme parameter initialDelaySeconds, ki operaciji preverjanja naroči, naj počaka določeno število sekund. Zakasnitev je potrebna, ker vsebnik potrebuje čas za zagon in ob ponovnem zagonu bo nekaj časa nedosegljiv.

Če želite uporabiti to nastavitev za gručo, uporabite:

kubectl apply -f pod.yaml

Po nekaj sekundah lahko preverite vsebino sklopa z naslednjim ukazom:

kubectl describe pods node500

Na koncu izhoda najdi to je tisto.

Kot lahko vidite, je livenessProbe sprožil zahtevo HTTP GET, vsebnik je ustvaril napako 500 (za kar je bil programiran) in kubelet ga je znova zagnal.

Če se sprašujete, kako je bila programirana aplikacija NideJS, sta uporabljena app.js in 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" ]

Pomembno je upoštevati naslednje: livenessProbe bo znova zagnal vsebnik samo, če ne uspe. Če ponovni zagon ne odpravi napake, ki preprečuje delovanje vsebnika, kubelet ne bo mogel ukrepati, da bi odpravil težavo.

pripravljenost Sonda

readinessProbe deluje podobno kot livenessProbes (zahteve GET, komunikacije TCP in izvajanje ukazov), razen za dejanja za odpravljanje težav. Vsebnik, v katerem je zaznana napaka, se ne zažene znova, ampak je izoliran od dohodnega prometa. Predstavljajte si, da eden od vsebnikov izvaja veliko izračunov ali je pod veliko obremenitvijo, zaradi česar se odzivni časi podaljšajo. V primeru livenessProbe se sproži preverjanje razpoložljivosti odziva (prek parametra preverjanja timeoutSeconds), po katerem kubelet znova zažene vsebnik. Ko se vsebnik zažene, začne izvajati naloge, ki zahtevajo veliko virov, in se znova zažene. To je lahko kritično za aplikacije, ki potrebujejo hitrost odziva. Na primer, avto na cesti čaka na odgovor strežnika, odgovor zamuja - in avto zaide v nesrečo.

Napišimo definicijo redinessProbe, ki bo nastavila odzivni čas zahteve GET na največ dve sekundi, aplikacija pa se bo na zahtevo GET odzvala po 5 sekundah. Datoteka pod.yaml bi morala izgledati takole:

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

Razmestimo pod s kubectl:

kubectl apply -f pod.yaml

Počakajmo nekaj sekund in nato poglejmo, kako je ReadinessProbe deloval:

kubectl describe pods nodedelayed

Na koncu izpisa lahko vidite, da so nekateri dogodki podobni tale.

Kot lahko vidite, kubectl ni znova zagnal sklopa, ko je čas preverjanja presegel 2 sekundi. Namesto tega je zahtevo preklical. Dohodna komunikacija je preusmerjena na druge delujoče enote.

Upoštevajte, da zdaj, ko je pod raztovorjen, kubectl znova usmerja zahteve vanj: odgovori na zahteve GET niso več zakasnjeni.

Za primerjavo je spodaj spremenjena datoteka 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 pojavom aplikacij v oblaku so bili dnevniki glavno sredstvo za spremljanje in preverjanje zdravja aplikacij. Vendar ni bilo sredstev za sprejetje kakršnih koli korektivnih ukrepov. Dnevniki so uporabni še danes, treba jih je zbrati in poslati v sistem zbiranja dnevnikov za analizo izrednih razmer in sprejemanje odločitev. [Vse to bi lahko storili brez aplikacij v oblaku, ki uporabljajo na primer monit, vendar je s k8s postalo veliko lažje :) – opomba urednika. ]

Danes je treba popravke izvajati skoraj v realnem času, zato aplikacijam ni več treba biti črne skrinjice. Ne, prikazati morajo končne točke, ki nadzornim sistemom omogočajo poizvedovanje in zbiranje dragocenih podatkov o stanju procesov, tako da se lahko po potrebi takoj odzovejo. To se imenuje vzorec zasnove preizkusa učinkovitosti, ki sledi načelu visoke opazljivosti (HOP).

Kubernetes privzeto ponuja 2 vrsti zdravstvenih pregledov: readinessProbe in livenessProbe. Oba uporabljata iste vrste preverjanj (HTTP GET zahteve, TCP komunikacije in izvajanje ukazov). Razlikujejo se po tem, kakšne odločitve sprejemajo kot odgovor na težave v strokih. livenessProbe znova zažene vsebnik v upanju, da se napaka ne bo ponovila, in readinessProbe izolira pod dohodnega prometa, dokler ni odpravljen vzrok težave.

Pravilna zasnova aplikacije mora vključevati obe vrsti preverjanja in zagotoviti, da zbereta dovolj podatkov, zlasti ko pride do izjeme. Prikazovati mora tudi potrebne končne točke API-ja, ki sistemu za spremljanje (Prometheus) zagotavljajo pomembne meritve zdravja.

Vir: www.habr.com

Dodaj komentar