TL; DR
- For at opnå høj observerbarhed af containere og mikrotjenester er logfiler og primære metrikker ikke nok.
- For hurtigere genopretning og øget modstandsdygtighed bør applikationer anvende High Observability Principle (HOP).
- På applikationsniveau kræver NOP: korrekt logning, tæt overvågning, sundhedstjek og præstations-/overgangssporing.
- Brug checks som et element i NOR parathed Probe и livlighed Sonde Kubernetes.
Hvad er en Health Check-skabelon?
Når man designer en missionskritisk og yderst tilgængelig applikation, er det meget vigtigt at tænke på et sådant aspekt som fejltolerance. En applikation betragtes som fejltolerant, hvis den kommer sig hurtigt efter fejl. En typisk cloud-applikation bruger en microservices-arkitektur - hvor hver komponent er placeret i en separat container. Og for at sikre, at applikationen på k8s er yderst tilgængelig, når du designer en klynge, skal du følge visse mønstre. Blandt dem er Health Check-skabelonen. Den definerer, hvordan applikationen kommunikerer til k8s, at den er sund. Dette er ikke kun information om, hvorvidt poden kører, men også om, hvordan den modtager og reagerer på anmodninger. Jo mere Kubernetes ved om pod'ens sundhed, jo smartere beslutninger træffer den om trafikdirigering og belastningsbalancering. Således giver High Observability Princippet applikationen mulighed for at reagere på anmodninger rettidigt.
High Observability Principle (HOP)
Princippet om høj observerbarhed er et af
En veldesignet cloud-applikation logger sine vigtigste begivenheder ved hjælp af standard I/O-streams STDERR og STDOUT. Dernæst kommer en hjælpetjeneste, for eksempel filebeat, logstash eller fluentd, der leverer logfiler til et centraliseret overvågningssystem (for eksempel Prometheus) og et logopsamlingssystem (ELK-softwaresuite). Diagrammet nedenfor viser, hvordan en cloud-applikation fungerer i henhold til Health Test Pattern og High Observability Principle.
Hvordan anvender man sundhedstjekmønsteret i Kubernetes?
Ud af æsken overvåger k8s podsens status ved hjælp af en af controllerne (
I vores eksempel gør k8s funktionstjek. Ved denne type verifikation kontrollerer kubelet løbende processens tilstand i containeren. Når han forstår, at processen er stoppet, vil han genstarte den. Hvis fejlen kan løses ved blot at genstarte applikationen, og programmet er designet til at lukke ned ved enhver fejl, så er et processundhedstjek alt hvad du behøver for at følge NOP og Health Test Pattern. Den eneste skam er, at ikke alle fejl elimineres ved genstart. I dette tilfælde tilbyder k8s 2 dybere måder at identificere problemer med poden på:
LivenessProbe
Under livlighed Sonde kubelet udfører 3 typer kontroller: ikke kun bestemmer, om poden kører, men også om den er klar til at modtage og reagere tilstrækkeligt på anmodninger:
- Konfigurer en HTTP-anmodning til poden. Svaret skal indeholde en HTTP-svarkode i området fra 200 til 399. Koderne 5xx og 4xx signalerer således, at poden har problemer, selvom processen kører.
- For at teste pods med ikke-HTTP-tjenester (f.eks. Postfix-mailserveren), skal du oprette en TCP-forbindelse.
- Udfør en vilkårlig kommando for en pod (internt). Kontrollen anses for at være vellykket, hvis kommandoudførelseskoden er 0.
Et eksempel på, hvordan dette fungerer. Den næste pod-definition indeholder en NodeJS-applikation, der kaster en 500-fejl på HTTP-anmodninger. For at sikre, at containeren genstartes, når der modtages en sådan fejl, bruger vi parameteren 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
Dette adskiller sig ikke fra enhver anden pod-definition, men vi tilføjer et objekt .spec.containers.livenessProbe
. Parameter httpGet
accepterer stien, som HTTP GET-anmodningen sendes til (i vores eksempel er dette /
, men i kampscenarier kan der være noget lignende /api/v1/status
). En anden livenessProbe accepterer en parameter initialDelaySeconds
, som instruerer verifikationsoperationen til at vente et angivet antal sekunder. Forsinkelsen er nødvendig, fordi containeren har brug for tid til at starte, og når den genstartes, vil den være utilgængelig i nogen tid.
For at anvende denne indstilling på en klynge skal du bruge:
kubectl apply -f pod.yaml
Efter et par sekunder kan du kontrollere indholdet af poden ved hjælp af følgende kommando:
kubectl describe pods node500
Find i slutningen af outputtet
Som du kan se, startede livenessProbe en HTTP GET-anmodning, containeren genererede en fejl 500 (hvilket er, hvad den var programmeret til at gøre), og kubelet genstartede den.
Hvis du undrer dig over, hvordan NideJS-applikationen blev programmeret, er her app.js og Dockerfile, der blev brugt:
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')
})
Dockerfil
FROM node
COPY app.js /
EXPOSE 3000
ENTRYPOINT [ "node","/app.js" ]
Det er vigtigt at bemærke dette: livenessProbe genstarter kun containeren, hvis den fejler. Hvis en genstart ikke retter den fejl, der forhindrer beholderen i at køre, vil kubelet ikke være i stand til at foretage sig noget for at rette problemet.
parathed Probe
readinessProbe fungerer på samme måde som livenessProbes (GET-anmodninger, TCP-kommunikation og kommandoudførelse), bortset fra fejlfindingshandlinger. Containeren, hvori fejlen er registreret, genstartes ikke, men er isoleret fra indgående trafik. Forestil dig, at en af containerne udfører mange beregninger eller er under stor belastning, hvilket får responstiden til at øges. I tilfælde af livenessProbe udløses responstilgængelighedskontrollen (via timeoutSeconds check-parameteren), hvorefter kubelet genstarter containeren. Når den startes, begynder containeren at udføre ressourcekrævende opgaver og genstartes igen. Dette kan være kritisk for applikationer, der har brug for responshastighed. For eksempel venter en bil på vejen på svar fra serveren, responsen er forsinket - og bilen kommer ud for en ulykke.
Lad os skrive en redinessProbe-definition, der vil indstille GET-anmodningssvartiden til ikke mere end to sekunder, og applikationen vil svare på GET-anmodningen efter 5 sekunder. Filen pod.yaml skulle se sådan ud:
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
Lad os implementere en pod med kubectl:
kubectl apply -f pod.yaml
Lad os vente et par sekunder og så se, hvordan parathedsproben fungerede:
kubectl describe pods nodedelayed
I slutningen af outputtet kan du se, at nogle af begivenhederne ligner hinanden
Som du kan se, genstartede kubectl ikke poden, da kontroltiden oversteg 2 sekunder. I stedet annullerede han anmodningen. Indgående kommunikation omdirigeres til andre fungerende pods.
Bemærk, at nu hvor poden er afloadet, dirigerer kubectl anmodninger til den igen: svar på GET-anmodninger er ikke længere forsinket.
Til sammenligning er nedenfor den ændrede app.js-fil:
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
Før fremkomsten af cloud-applikationer var logfiler det primære middel til at overvåge og kontrollere applikationstilstand. Der var dog ingen midler til at træffe korrigerende foranstaltninger. Logs er stadig nyttige i dag; de skal indsamles og sendes til et logindsamlingssystem for at analysere nødsituationer og træffe beslutninger. [Alt dette kunne gøres uden cloud-applikationer ved hjælp af for eksempel monit, men med k8s blev det meget nemmere :) – red. bemærkning. ]
I dag skal rettelser foretages næsten i realtid, så ansøgninger ikke længere skal være sorte bokse. Nej, de bør vise endepunkter, der gør det muligt for overvågningssystemer at forespørge og indsamle værdifulde data om processernes tilstand, så de kan reagere øjeblikkeligt, hvis det er nødvendigt. Dette kaldes Performance Test Design Pattern, som følger High Observability Principle (HOP).
Kubernetes tilbyder som standard 2 typer sundhedstjek: ReadinessProbe og livenessProbe. Begge bruger de samme typer kontroller (HTTP GET-anmodninger, TCP-kommunikation og kommandoudførelse). De er forskellige i, hvilke beslutninger de træffer som reaktion på problemer i bælgerne. livenessProbe genstarter containeren i håb om, at fejlen ikke vil ske igen, og readinessProbe isolerer poden fra indgående trafik, indtil årsagen til problemet er løst.
Korrekt applikationsdesign bør omfatte begge typer kontrol og sikre, at de indsamler nok data, især når der er smidt en undtagelse. Det bør også vise de nødvendige API-endepunkter, der forsyner overvågningssystemet (Prometheus) med vigtige sundhedsmålinger.
Kilde: www.habr.com