BÀsta praxis för Kubernetes-containrar: hÀlsokontroller

BÀsta praxis för Kubernetes-containrar: hÀlsokontroller

TL;DR

  • För att uppnĂ„ hög observabilitet av containrar och mikrotjĂ€nster, loggar och primĂ€ra metrik rĂ€cker det inte med bara detta.
  • För snabbare Ă„terstĂ€llning och ökad motstĂ„ndskraft bör applikationer tillĂ€mpa Hög Observabilitetsprincip (HOP, High Observability Principle).
  • PĂ„ applikationsnivĂ„ för HOP krĂ€vs: adekvat loggning, noggrann övervakning, tillstĂ„ndskontroller och prestanda/trafikspĂ„rning.
  • Som en del av HOP, anvĂ€nd kontroller. beredskapskontroll och livenessProbe Kubernetes.

Vad Àr en tillstÄndskontrollmall?

NĂ€r du designar en kritisk och hög tillgĂ€nglig applikation Ă€r det viktigt att tĂ€nka pĂ„ aspekten av motstĂ„ndskraft. En applikation anses vara motstĂ„ndskraftig om den snabbt Ă„terhĂ€mtar sig efter ett fel. En typisk molnapplikation anvĂ€nder en mikrotjĂ€nstarkitektur – dĂ€r varje komponent placeras i en separat container. För att sĂ€kerstĂ€lla att applikationen pĂ„ k8s Ă€r hög tillgĂ€nglig, mĂ„ste du följa vissa mallar nĂ€r du designar klustret. Bland dem finns TillstĂ„ndskontrollmallen. Den definierar hur applikationen informerar k8s om sin tillgĂ€nglighet. Detta Ă€r inte bara information om huruvida podden fungerar, utan ocksĂ„ om hur den tar emot och svarar pĂ„ förfrĂ„gningar. Ju mer Kubernetes vet om poddens tillgĂ€nglighet, desto smartare beslut tar den om trafikdirigering och belastningsbalansering. PĂ„ sĂ„ sĂ€tt svarar Hög Observabilitetsprincip applikationen i tid pĂ„ förfrĂ„gningar.

Hög Observabilitetsprincip (HOP)

Hög Observabilitetsprincip Ă€r en av principerna för design av containeriserade applikationer. I mikroservicesarkitektur Ă€r tjĂ€nsterna oberoende av hur deras förfrĂ„gan behandlas (vilket Ă€r korrekt), men det viktiga Ă€r hur man fĂ„r svar frĂ„n mottagande tjĂ€nster. Till exempel, för autentisering av anvĂ€ndaren skickar en container en HTTP-förfrĂ„gan till en annan och vĂ€ntar pĂ„ svar i ett visst format – och det Ă€r allt. FörfrĂ„gan kan hanteras av PythonJS, och svaret kan ges av Python Flask. Containrar Ă€r för varandra som svarta lĂ„dor med dold information. Men principen för hĂ€lsa (NOR) krĂ€ver att varje tjĂ€nst avslöjar flera API-slutpunkter som visar hur fungerande den Ă€r, samt dess beredskaps- och redundansstatus. Dessa parametrar begĂ€rs av Kubernetes för att planera nĂ€sta steg för routing och belastningsbalansering.

Ett vÀl utformat molnapplikation loggar sina viktiga hÀndelser med hjÀlp av standard I/O-strömmarna STDERR och STDOUT. DÀrefter körs en hjÀlptjÀnst, som filebeat, logstash eller fluentd, som levererar loggarna till ett centraliserat övervakningssystem (t.ex. Prometheus) och ett loggsamling-system (ELK-stack). Diagrammet nedan visar hur molnapplikationen fungerar enligt HÀlsokontrollmönstret och Principen för hög observabilitet.

BÀsta praxis för Kubernetes-containrar: hÀlsokontroller

Hur tillÀmpar man HÀlsokontrollmönstret i Kubernetes?

K8s övervakar poddarnas status direkt med hjÀlp av en av kontrollerarna (Deployments, ReplicaSets, DaemonSets, StatefulSets och sÄ vidare). Om en pod av nÄgon anledning kraschar försöker kontrollern att starta om den eller schemalÀgga den pÄ en annan nod. Men en pod kan rapportera att den Àr igÄng och fungerar, nÀr den i sjÀlva verket inte gör det. LÄt oss ge ett exempel: din applikation anvÀnder Apache som webserver och du har installerat komponenten pÄ flera pods i klustret. Eftersom biblioteket var felkonfigurerat svarar alla förfrÄgningar till applikationen med kod 500 (intern serverfel). Vid kontroll av leveransen ger poddarnas status kontroller ett positivt resultat, men kunderna tycker annorlunda. Denna oönskade situation kan vi beskriva pÄ följande sÀtt:

BÀsta praxis för Kubernetes-containrar: hÀlsokontroller

I vÄrt exempel utför k8s hÀlsokontrollen. I denna typ av kontroll övervakar kubelet stÀndigt tillstÄndet för processen i containern. SÄ snart den inser att processen har stannat, startar den om den. Om felet kan lösas med en enkel omstart av applikationen, och programmet Àr utformat för att koppla bort vid varje fel, dÄ Àr det tillrÀckligt med en kontroll av processens livslÀngd enligt NORM och Liveness-prototypen. Det Àr bara synd att inte alla fel kan ÄtgÀrdas med en omstart. För sÄdana fall erbjuder k8s tvÄ mer djupgÄende metoder för att identifiera problem med podden: livenessProbe och beredskapskontroll.

LivenessProbe

Under tiden livenessProbe kubelet genomför tre typer av kontroller: den undersöker inte bara om podden fungerar, utan ocksÄ om den Àr redo att ta emot och korrekt svara pÄ förfrÄgningar:

  • StĂ€ll in en HTTP-förfrĂ„gan till podden. Svaret ska innehĂ„lla en HTTP-statuskod mellan 200 och 399. PĂ„ sĂ„ sĂ€tt signalerar 5xx och 4xx koder att podden har problem, Ă€ven om processen fungerar.
  • För att kontrollera poddar med icke-HTTP-tjĂ€nster (till exempel e-postservern Postfix) mĂ„ste en TCP-anslutning upprĂ€ttas.
  • Exekvering av ett godtyckligt kommando för podden (inuti). Kontroll Ă€r framgĂ„ngsrik om kommandots avslutningskod Ă€r 0.

Ett exempel pÄ hur detta fungerar. Definitionen av följande podd innehÄller en NodeJS-applikation som ger ett 500-fel pÄ HTTP-förfrÄgningar. För att sÀkerstÀlla att containern startas om nÀr ett sÄdant fel intrÀffar, anvÀnder vi parametern 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

Detta skiljer sig inte frÄn nÄgon annan pod-definition, men vi lÀgger till objektet .spec.containers.livenessProbe. Parametern httpGet anger sökvÀgen för HTTP GET-förfrÄgan (i vÄrt exempel Àr detta /, men i verkliga scenarier kan det vara nÄgot som /api/v1/status). LivenessProbe tar ocksÄ parametern initialDelaySeconds, som ÄlÀgger kontrolloperationen att vÀnta angivna antal sekunder. Fördröjningen behövs eftersom containern behöver tid för att starta, och efter en omstart kommer den att vara otillgÀnglig under en period.

För att tillÀmpa denna instÀllning pÄ klustret, anvÀnd:

kubectl apply -f pod.yaml

Efter nÄgra sekunder kan innehÄllet i podden kontrolleras med följande kommando:

kubectl describe pods node500

Sök efter detta i slutet av utskriften.

Som ni ser initierade livenessProbe en HTTP GET-begÀran, containern gav ett fel 500 (som den var programmerad att göra), kubelet startade om den.

Om du Àr intresserad av hur NideJS-applikationen programmerades, hÀr Àr filerna app.js och Dockerfile som anvÀndes:

app.js

var http = require('http');

var server = http.createServer(function(req, res) {
    res.writeHead(500, { "Content-type": "text/plain" });
    res.end("Vi har stött pÄ ett feln");
});

server.listen(3000, function() {
    console.log('Server körs pÄ 3000')
})

Dockerfile

FROM node
COPY app.js /
EXPOSE 3000
ENTRYPOINT [ "node","/app.js" ]

Det Àr viktigt att notera följande: livenessProbe startar om containern endast vid fel. Om omstarten inte ÄtgÀrdar problemet som hindrar containern frÄn att fungera, kan kubelet inte vidta ÄtgÀrder för att lösa felet.

beredskapskontroll

readinessProbe fungerar pÄ liknande sÀtt som livenessProbes (GET-begÀran, TCP-anslutningar och kommandokörning), med undantag för ÄtgÀrder för att lösa fel. En container som har registrerat ett fel startas inte om, utan isoleras frÄn inkommande trafik. FörestÀll dig att en av containrarna utför mÄnga berÀkningar eller utsÀtts för tung belastning, vilket ökar svarstiden för begÀrningar. I fall av livenessProbe aktiveras tillgÀnglighetskontrollen (via timeoutSeconds-parametern), varefter kubelet startar om containern. NÀr containern startas, börjar den utföra resurskrÀvande uppgifter och den startas om igen. Detta kan vara kritiskt för applikationer dÀr svarstiden Àr viktig. Till exempel, om en maskin Àr pÄ vÀg och vÀntar pÄ ett svar frÄn servern, om svaret dröjer kan maskinen krascha.

LÄt oss skriva en definition för readinessProbe som stÀller in svarstiden pÄ GET-begÀran till högst tvÄ sekunder, medan applikationen svarar pÄ GET-begÀran efter 5 sekunder. Filen pod.yaml ska se ut pÄ följande sÀtt:

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

LÄt oss distribuera pod med kubectl:

kubectl apply -f pod.yaml

VÀnta ett par sekunder och titta sedan pÄ hur readinessProbe svarade:

kubectl describe pods nodedelayed

I slutet av utskriften kan du se att en del av evenemangen Àr lika med det hÀr.

Som ni ser valde kubectl att inte starta om pod nÀr kontrolltiden överskred 2 sekunder. IstÀllet avbröt den begÀran. Inkommande anslutningar omdirigeras till andra, fungerande poddar.

Observera: nu, nÀr den onödiga belastningen har tagits bort frÄn pod'en, riktar kubectl Äterigen sina förfrÄgningar till den: svaren pÄ GET-förfrÄgningar dröjer inte lÀngre.

För jÀmförelse: hÀr Àr den Àndrade filen 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("Hello\n");
   })
});

server.listen(3000, function() {
   console.log('Servern körs pÄ 3000')
})

TL;DR
Före lanseringen av molnapplikationer var loggar huvudverktyget för övervakning och tillstĂ„ndskontroll av applikationer. Det fanns dock inga medel för att vidta Ă„tgĂ€rder för att Ă„tgĂ€rda problem. Loggar Ă€r fortfarande anvĂ€ndbara idag, de bör samlas in och skickas till logghanteringssystemet för analys av nödsituationer och beslutsfattande. [detta var allt möjligt att göra utan molnapplikationer med hjĂ€lp av monit, till exempel, men med k8s har det blivit mycket enklare 🙂 – red. anm. ]

Idag mÄste Àndringar göras nÀstan i realtid, sÄ applikationer fÄr inte lÀngre vara svarta lÄdor. Nej, de mÄste visa slutpunkter som gör det möjligt för övervakningssystem att begÀra och samla in vÀrdefulla data om processernas tillstÄnd, sÄ att man snabbt kan reagera om det behövs. Detta kallas designmönster för hÀlsoundersökning, som följer principen om hög observabilitet (HOP).

Kubernetes erbjuder som standard 2 typer av hĂ€lsoundersökningar: readinessProbe och livenessProbe. BĂ„da anvĂ€nder samma typer av kontroller (HTTP GET-förfrĂ„gningar, TCP-anslutningar och kommandokörning). De skiljer sig Ă„t i vilka Ă„tgĂ€rder som vidtas som svar pĂ„ problem i pod'ar. livenessProbe startar om containern i hopp om att felet inte upprepas, medan readinessProbe isolerar pod'en frĂ„n inkommande trafik – tills problemet Ă€r löst.

Korrekt applikationsdesign bör inkludera bÄda typer av kontroller, och de bör samla tillrÀckligt med data, sÀrskilt nÀr en extraordinÀr situation har uppstÄtt. Den bör ocksÄ visa nödvÀndiga API-slutpunkter som överför viktiga driftsstatusmetrik till övervakningssystemet (samma Prometheus).

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster