Kubernetese konteinerite parimad tavad: tervisekontroll

Kubernetese konteinerite parimad tavad: tervisekontroll

TL; DR

  • Konteinerite ja mikroteenuste kõrge jälgitavuse saavutamiseks ei piisa logidest ja esmastest mõõdikutest.
  • Kiiremaks taastamiseks ja vastupidavuse suurendamiseks peaksid rakendused rakendama kõrge jälgitavuse põhimõtet (HOP).
  • Rakenduse tasemel nõuab NOP: nõuetekohast logimist, hoolikat jälgimist, mõistuse kontrollimist ja jõudluse/ülemineku jälgimist.
  • Kasutage tšekke NOR elemendina valmisolek Sond и elavus Probe Kubernetes.

Mis on tervisekontrolli mall?

Missioonikriitilise ja kõrge kättesaadavusega rakenduse kavandamisel on väga oluline mõelda sellisele aspektile nagu veataluvus. Rakendus loetakse tõrketaluvaks, kui see taastub rikkest kiiresti. Tüüpiline pilverakendus kasutab mikroteenuste arhitektuuri – kus iga komponent on paigutatud eraldi konteinerisse. Ja selleks, et olla kindel, et k8s-i rakendus on klastri kujundamisel väga kättesaadav, peate järgima teatud mustreid. Nende hulgas on tervisekontrolli mall. See määratleb, kuidas rakendus teatab k8s-ile, et see on tervislik. See ei ole ainult teave selle kohta, kas pod töötab, vaid ka selle kohta, kuidas see päringuid vastu võtab ja neile vastab. Mida rohkem Kubernetes podi seisundist teab, seda nutikamaid otsuseid ta liikluse suunamise ja koormuse tasakaalustamise kohta teeb. Seega võimaldab kõrge jälgitavuse põhimõte rakendusel vastata päringutele õigeaegselt.

Kõrge jälgitavuse põhimõte (HOP)

Kõrge jälgitavuse põhimõte on üks konteinerrakenduste kavandamise põhimõtted. Mikroteenuste arhitektuuris ei huvita teenused, kuidas nende taotlust töödeldakse (ja seda õigustatult), kuid oluline on see, kuidas nad saavad vastuvõtvatelt teenustelt vastuseid. Näiteks kasutaja autentimiseks saadab üks konteiner teisele HTTP päringu, oodates vastust kindlas vormingus – see on kõik. PythonJS saab taotlust ka töödelda ja Python Flask saab vastata. Konteinerid on üksteisele nagu mustad kastid, mille sisu on peidetud. NOP-põhimõte nõuab aga, et iga teenus paljastaks mitu API lõpp-punkti, mis näitavad selle tervislikku seisundit, samuti selle valmisolekut ja tõrketaluvust. Kubernetes küsib neid indikaatoreid, et mõelda läbi järgmised marsruutimise ja koormuse tasakaalustamise sammud.

Hästi kavandatud pilverakendus logib oma peamised sündmused standardsete I/O voogude STDERR ja STDOUT abil. Edasi tuleb abiteenus, näiteks filebeat, logstash või fluentd, mis toimetab logid tsentraliseeritud jälgimissüsteemi (näiteks Prometheus) ja logide kogumise süsteemi (ELK tarkvarakomplekt). Allolev diagramm näitab, kuidas pilverakendus töötab tervisetesti mustri ja kõrge jälgitavuse põhimõtte kohaselt.

Kubernetese konteinerite parimad tavad: tervisekontroll

Kuidas Kubernetesis tervisekontrolli mustrit rakendada?

Karbist välja võttes jälgib k8s kaustade olekut, kasutades ühte kontrolleritest (kasutuselevõttu, ReplicaSets, DaemonSets, StatefulSets jne jne). Olles avastanud, et pod on mingil põhjusel alla kukkunud, proovib kontroller seda taaskäivitada või teise sõlme teisaldada. Pod võib siiski teatada, et see on töökorras, kuid see ise ei tööta. Toome näite: teie rakendus kasutab veebiserverina Apache'i, installisite komponendi mitmele klastri kaustale. Kuna teek oli valesti konfigureeritud, vastavad kõik taotlused rakendusele koodiga 500 (serveri sisemine viga). Tarne kontrollimisel annab kaunade oleku kontrollimine eduka tulemuse, kuid kliendid arvavad teisiti. Kirjeldame seda soovimatut olukorda järgmiselt:

Kubernetese konteinerite parimad tavad: tervisekontroll

Meie näites teeb seda k8s funktsionaalsuse kontroll. Seda tüüpi kontrollimisel kontrollib kubelet pidevalt konteineris toimuva protsessi olekut. Kui ta mõistab, et protsess on peatunud, käivitab ta selle uuesti. Kui tõrke saab lahendada lihtsalt rakenduse taaskäivitamisega ja programm on loodud tõrgete korral välja lülituma, on protsessi tervisekontroll kõik, mida vajate, et järgida NOP-i ja tervisetesti mustrit. Kahju ainult sellest, et kõiki vigu ei kõrvaldata taaskäivitusega. Sel juhul pakub k8s 2 sügavamat viisi podiga seotud probleemide tuvastamiseks: elavus Probe и valmisolek Sond.

LivenessProbe

Ajal elavus Probe kubelet teostab kolme tüüpi kontrolle: mitte ainult ei määra, kas pod töötab, vaid ka seda, kas see on valmis päringuid vastu võtma ja neile adekvaatselt vastama:

  • Seadistage podile HTTP-päring. Vastus peab sisaldama HTTP vastuse koodi vahemikus 200 kuni 399. Seega annavad koodid 5xx ja 4xx märku, et podil on probleeme, kuigi protsess töötab.
  • Podide testimiseks mitte-HTTP-teenustega (nt Postfixi meiliserver) peate looma TCP-ühenduse.
  • Käivitage suvaline käsk podi jaoks (sisemiselt). Kontroll loetakse edukaks, kui käsu täitmise kood on 0.

Näide selle toimimisest. Järgmine podi definitsioon sisaldab NodeJS-i rakendust, mis annab HTTP-päringutele tõrke 500. Veendumaks, et konteiner taaskäivitatakse sellise vea saamisel, kasutame parameetrit 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

See ei erine ühestki teisest podi definitsioonist, kuid me lisame objekti .spec.containers.livenessProbe... Parameeter httpGet aktsepteerib teed, kuhu HTTP GET-i päring saadetakse (meie näites on see /, kuid lahingustsenaariumide puhul võib midagi sarnast olla /api/v1/status). Teine elavusProbe aktsepteerib parameetrit initialDelaySeconds, mis annab kinnitustoimingule korralduse oodata teatud arv sekundeid. Viivitus on vajalik, kuna konteiner vajab käivitumiseks aega ja taaskäivitamisel pole see mõnda aega saadaval.

Selle sätte rakendamiseks klastrile kasutage järgmist.

kubectl apply -f pod.yaml

Mõne sekundi pärast saate podi sisu kontrollida järgmise käsuga:

kubectl describe pods node500

Väljundi lõpus leidke see on mis.

Nagu näete, algatas livenessProbe HTTP GET-päringu, konteiner genereeris vea 500 (see oli see, milleks see oli programmeeritud) ja kubelet taaskäivitas selle.

Kui soovite teada, kuidas NideJS-i rakendus programmeeriti, siis siin on kasutatud failid app.js ja 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" ]

Oluline on seda tähele panna: livenessProbe taaskäivitab konteineri ainult siis, kui see ebaõnnestub. Kui taaskäivitamine ei paranda viga, mis takistab konteineri töötamist, ei saa kubelet probleemi lahendamiseks midagi ette võtta.

valmisolek Sond

ReadinessProbe töötab sarnaselt livenessProbes'iga (GET-päringud, TCP-suhtlus ja käskude täitmine), välja arvatud tõrkeotsingu toimingud. Konteinerit, milles rike tuvastati, ei taaskäivitata, vaid see isoleeritakse sissetulevast liiklusest. Kujutage ette, et üks konteineritest teeb palju arvutusi või on suure koormuse all, mistõttu reageerimisaeg pikeneb. LivenessProbe'i puhul käivitatakse vastuse saadavuse kontroll (kontrolli parameetri timeoutSeconds kaudu), mille järel kubelet taaskäivitab konteineri. Käivitamisel hakkab konteiner täitma ressursimahukaid ülesandeid ja taaskäivitatakse. See võib olla kriitilise tähtsusega rakenduste jaoks, mis vajavad reageerimiskiirust. Näiteks kui auto teel olles ootab serverilt vastust, vastus viibib – ja auto satub avariisse.

Kirjutame redinessProbe'i definitsiooni, mis seab GET-päringu reageerimisajaks mitte rohkem kui kaks sekundit ja rakendus vastab GET-päringule 5 sekundi pärast. Fail pod.yaml peaks välja nägema järgmine:

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

Juurutame kubectliga podi:

kubectl apply -f pod.yaml

Ootame paar sekundit ja siis vaatame, kuidas ReadinessProbe töötas:

kubectl describe pods nodedelayed

Väljundi lõpus on näha, et mõned sündmused on sarnased see.

Nagu näete, ei taaskäivitanud kubectl podi, kui kontrollaeg ületas 2 sekundit. Selle asemel tühistas ta taotluse. Sissetulevad sided suunatakse ümber teistele, töötavatele kaustadele.

Pange tähele, et nüüd, kui pod on maha laaditud, suunab kubectl päringud sellele uuesti: vastused GET-päringutele ei viibi enam.

Võrdluseks allpool on muudetud fail 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
Enne pilverakenduste tulekut olid logid peamised rakenduse tervise jälgimise ja kontrollimise vahendid. Parandusmeetmete võtmiseks polnud aga vahendeid. Logid on kasulikud ka tänapäeval, need tuleb kokku koguda ja saata eriolukordade analüüsimiseks ja otsuste tegemiseks logikogumissüsteemi. [Seda kõike sai teha ilma pilverakendusteta, kasutades näiteks monitit, kuid k8s-iga läks palju lihtsamaks :) – toimetaja märkus. ]

Tänapäeval tuleb parandusi teha peaaegu reaalajas, nii et rakendused ei pea enam olema mustad kastid. Ei, need peaksid näitama lõpp-punkte, mis võimaldavad seiresüsteemidel teha päringuid ja koguda väärtuslikke andmeid protsesside oleku kohta, et nad saaksid vajadusel kohe reageerida. Seda nimetatakse jõudluskatse disaini mustriks, mis järgib kõrge jälgitavuse põhimõtet (HOP).

Kubernetes pakub vaikimisi kahte tüüpi tervisekontrolli: readynessProbe ja livenessProbe. Mõlemad kasutavad sama tüüpi kontrolle (HTTP GET-päringud, TCP-side ja käskude täitmine). Need erinevad selle poolest, milliseid otsuseid nad kaunade probleemide korral teevad. livenessProbe taaskäivitab konteineri lootuses, et viga enam ei kordu, ja readinessProbe isoleerib podi sissetulevast liiklusest, kuni probleemi põhjus on lahendatud.

Õige rakenduse ülesehitus peaks hõlmama mõlemat tüüpi kontrolli ja tagama, et need koguksid piisavalt andmeid, eriti kui tehakse erand. Samuti peaks see näitama vajalikke API lõpp-punkte, mis pakuvad seiresüsteemile (Prometheus) olulisi tervisenäitajaid.

Allikas: www.habr.com

Lisa kommentaar