Najbolje prakse za Kubernetes kontejnere: provjere zdravlja

Najbolje prakse za Kubernetes kontejnere: provjere zdravlja

TL; DR

  • Da bi se postigla visoka vidljivost kontejnera i mikroservisa, evidencije i primarna metrika nisu dovoljni.
  • Za brži oporavak i povećanu otpornost, aplikacije bi trebale primjenjivati ​​princip visoke vidljivosti (HOP).
  • Na nivou aplikacije, NOP zahtijeva: pravilno evidentiranje, pažljivo praćenje, provjere ispravnosti i praćenje performansi/prijelaza.
  • Koristite provjere kao element NOR-a readinessProbe и livenessProbe Kubernetes.

Šta je predložak zdravstvenog pregleda?

Prilikom dizajniranja kritične i vrlo dostupne aplikacije, vrlo je važno razmišljati o takvom aspektu kao što je tolerancija grešaka. Aplikacija se smatra tolerantnom na greške ako se brzo oporavlja od kvara. Tipična aplikacija u oblaku koristi arhitekturu mikroservisa - gdje je svaka komponenta smještena u poseban kontejner. A kako biste bili sigurni da je aplikacija na k8s vrlo dostupna kada dizajnirate klaster, morate slijediti određene obrasce. Među njima je i predložak za provjeru zdravlja. Definira kako aplikacija komunicira k8s-u da je zdrava. Ovo nije samo informacija o tome da li pod radi, već i o tome kako prima i odgovara na zahtjeve. Što više Kubernetes zna o zdravlju pod-a, donosi pametnije odluke o usmjeravanju prometa i balansiranju opterećenja. Dakle, princip visoke uočljivosti omogućava aplikaciji da odgovori na zahtjeve na vrijeme.

Princip visoke uočljivosti (HOP)

Princip visoke uočljivosti je jedan od principi dizajniranja kontejnerskih aplikacija. U arhitekturi mikroservisa, uslugama nije važno kako se njihov zahtjev obrađuje (i to s pravom), već je važno kako primaju odgovore od usluga koje primaju. Na primjer, za autentifikaciju korisnika, jedan kontejner šalje HTTP zahtjev drugom, očekujući odgovor u određenom formatu - to je sve. PythonJS također može obraditi zahtjev, a Python Flask može odgovoriti. Kontejneri su kao crne kutije sa skrivenim sadržajem jedni drugima. Međutim, princip NOP zahtijeva da svaka usluga izloži nekoliko API krajnjih tačaka koje pokazuju koliko je zdrava, kao i njenu spremnost i status tolerancije grešaka. Kubernetes traži ove indikatore kako bi razmislio o sljedećim koracima za rutiranje i balansiranje opterećenja.

Dobro dizajnirana aplikacija u oblaku bilježi svoje glavne događaje koristeći standardne I/O tokove STDERR i STDOUT. Zatim dolazi pomoćni servis, na primjer filebeat, logstash ili fluentd, koji dostavlja dnevnike centraliziranom sustavu za nadzor (na primjer Prometheus) i sistemu za prikupljanje dnevnika (ELK softverski paket). Dijagram ispod pokazuje kako aplikacija u oblaku radi u skladu sa obrascem testiranja zdravlja i principom visoke uočljivosti.

Najbolje prakse za Kubernetes kontejnere: provjere zdravlja

Kako primijeniti obrazac zdravstvene provjere u Kubernetesu?

Izvan kutije, k8s prati status podova pomoću jednog od kontrolera (primene, ReplicaSets, DaemonSets, StatefulSets itd., itd.). Nakon što je otkrio da je pod iz nekog razloga pao, kontroler ga pokušava ponovo pokrenuti ili premjestiti na drugi čvor. Međutim, pod može prijaviti da je pokrenut i da radi, ali sam ne funkcionira. Dajemo primjer: vaša aplikacija koristi Apache kao web server, instalirali ste komponentu na nekoliko podova klastera. Pošto je biblioteka pogrešno konfigurisana, svi zahtevi aplikaciji odgovaraju kodom 500 (interna greška servera). Prilikom provjere isporuke, provjera statusa mahuna daje uspješan rezultat, ali kupci misle drugačije. Ovu nepoželjnu situaciju ćemo opisati na sljedeći način:

Najbolje prakse za Kubernetes kontejnere: provjere zdravlja

U našem primjeru, k8s radi provjera funkcionalnosti. U ovoj vrsti verifikacije, kubelet kontinuirano provjerava stanje procesa u kontejneru. Kada shvati da je proces zaustavljen, ponovo će ga pokrenuti. Ako se greška može riješiti jednostavnim ponovnim pokretanjem aplikacije, a program je dizajniran da se isključi u slučaju bilo kakve greške, onda je provjera stanja procesa sve što vam je potrebno da biste slijedili NOP i obrazac za testiranje zdravlja. Jedina šteta je što se ne otklanjaju sve greške ponovnim pokretanjem. U ovom slučaju, k8s nudi 2 dublja načina za identifikaciju problema s podom: livenessProbe и readinessProbe.

LivenessProbe

Tokom livenessProbe kubelet obavlja 3 vrste provjera: ne samo da utvrđuje da li je pod pokrenut, već i da li je spreman da primi i adekvatno odgovori na zahtjeve:

  • Postavite HTTP zahtjev za pod. Odgovor mora sadržavati HTTP kod odgovora u rasponu od 200 do 399. Dakle, kodovi 5xx i 4xx signaliziraju da pod ima problema, iako je proces pokrenut.
  • Da biste testirali podove sa ne-HTTP uslugama (na primjer, Postfix mail server), morate uspostaviti TCP vezu.
  • Izvrši proizvoljnu naredbu za pod (interno). Provjera se smatra uspješnom ako je kod za završetak naredbe 0.

Primjer kako ovo funkcionira. Sljedeća definicija pod sadrži NodeJS aplikaciju koja na HTTP zahtjeve izbacuje grešku 500. Kako bismo osigurali da se spremnik ponovo pokrene kada primi ovu grešku, koristimo parametar 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

Ovo se ne razlikuje od bilo koje druge definicije pod, ali mi dodajemo objekt .spec.containers.livenessProbe. Parametar httpGet prihvaća putanju na koju se šalje HTTP GET zahtjev (u našem primjeru je to /, ali u borbenim scenarijima može postojati nešto slično /api/v1/status). Druga livenessProbe prihvata parametar initialDelaySeconds, koji nalaže operaciji verifikacije da čeka određeni broj sekundi. Odgoda je potrebna jer je kontejneru potrebno vrijeme da se pokrene, a kada se ponovo pokrene bit će nedostupan neko vrijeme.

Da biste ovu postavku primijenili na klaster, koristite:

kubectl apply -f pod.yaml

Nakon nekoliko sekundi, možete provjeriti sadržaj modula pomoću sljedeće naredbe:

kubectl describe pods node500

Na kraju izlaza pronađite to je to.

Kao što vidite, livenessProbe je pokrenuo HTTP GET zahtjev, kontejner je generirao grešku 500 (što je programiran da uradi), a kubelet ga je ponovo pokrenuo.

Ako se pitate kako je programirana NideJS aplikacija, evo app.js i Dockerfile koji su korišteni:

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" ]

Važno je napomenuti ovo: livenessProbe će ponovo pokrenuti kontejner samo ako ne uspije. Ako ponovno pokretanje ne ispravi grešku koja sprečava pokretanje kontejnera, kubelet neće moći poduzeti radnju da ispravi problem.

readinessProbe

readinessProbe radi slično kao i livenessProbes (GET zahtjevi, TCP komunikacije i izvršavanje naredbi), osim za akcije rješavanja problema. Kontejner u kojem je kvar otkriven se ne pokreće ponovo, već je izoliran od dolaznog prometa. Zamislite da jedan od kontejnera obavlja puno kalkulacija ili je pod velikim opterećenjem, što uzrokuje povećanje vremena odgovora. U slučaju livenessProbe, pokreće se provjera dostupnosti odgovora (preko parametra provjere timeoutSeconds), nakon čega kubelet ponovo pokreće kontejner. Kada se pokrene, kontejner počinje izvršavati resursno intenzivne zadatke i ponovo se pokreće. Ovo može biti kritično za aplikacije kojima je potrebna brzina odgovora. Na primjer, automobil dok je na putu čeka odgovor od servera, odgovor kasni - i automobil dolazi u nesreću.

Napišimo definiciju redinessProbe koja će postaviti vrijeme odgovora GET zahtjeva na ne više od dvije sekunde, a aplikacija će odgovoriti na GET zahtjev nakon 5 sekundi. Pod.yaml fajl bi trebao izgledati ovako:

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

Hajde da postavimo pod sa kubectl:

kubectl apply -f pod.yaml

Sačekajmo par sekundi i onda vidimo kako je radila sonda spremnosti:

kubectl describe pods nodedelayed

Na kraju izlaza možete vidjeti da su neki od događaja slični ovaj.

Kao što vidite, kubectl nije ponovo pokrenuo pod kada je vrijeme provjere premašilo 2 sekunde. Umjesto toga, poništio je zahtjev. Dolazne komunikacije se preusmjeravaju na druge, radne podove.

Imajte na umu da sada kada je pod istovaren, kubectl ponovo usmjerava zahtjeve na njega: odgovori na GET zahtjeve više ne kasne.

Za poređenje, ispod je modificirani app.js fajl:

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
Prije pojave aplikacija u oblaku, dnevnici su bili primarno sredstvo za praćenje i provjeru zdravlja aplikacija. Međutim, nije bilo sredstava da se poduzmu korektivne mjere. Dnevnici su i danas korisni; potrebno ih je prikupiti i poslati u sistem prikupljanja dnevnika za analizu vanrednih situacija i donošenje odluka. [Sve se to moglo uraditi bez aplikacija u oblaku koristeći monit, na primjer, ali sa k8s-om je postalo mnogo lakše :) – napomena urednika. ]

Danas se korekcije moraju vršiti gotovo u realnom vremenu, tako da aplikacije više ne moraju biti crne kutije. Ne, trebalo bi da prikazuju krajnje tačke koje omogućavaju sistemima za praćenje da postavljaju upite i prikupljaju vrijedne podatke o stanju procesa kako bi mogli odmah odgovoriti ako je potrebno. Ovo se zove obrazac dizajna testa performansi, koji slijedi princip visoke uočljivosti (HOP).

Kubernetes podrazumevano nudi 2 vrste provera zdravlja: readinessProbe i livenessProbe. Oba koriste iste vrste provjera (HTTP GET zahtjevi, TCP komunikacije i izvršavanje naredbi). Razlikuju se po tome koje odluke donose kao odgovor na probleme u kapsulama. livenessProbe ponovo pokreće kontejner u nadi da se greška neće ponoviti, a readinessProbe izoluje pod od dolaznog saobraćaja dok se ne otkloni uzrok problema.

Odgovarajući dizajn aplikacije trebao bi uključivati ​​obje vrste provjera i osigurati da prikupljaju dovoljno podataka, posebno kada se pojavi izuzetak. Takođe bi trebalo da pokaže neophodne API krajnje tačke koje obezbeđuju sistemu za praćenje (Prometheus) važne zdravstvene metrike.

izvor: www.habr.com

Dodajte komentar