Bästa metoder för Kubernetes-behållare: hälsokontroller

Bästa metoder för Kubernetes-behållare: hälsokontroller

TL; DR

  • För att uppnå hög observerbarhet av containrar och mikrotjänster räcker det inte med loggar och primära mätvärden.
  • För snabbare återhämtning och ökad motståndskraft bör tillämpningar tillämpa High Observability Principle (HOP).
  • På applikationsnivå kräver NOP: korrekt loggning, noggrann övervakning, sundhetskontroller och prestanda/övergångsspårning.
  • Använd checkar som en del av NOR beredskap Sond и livlighet Sond Kubernetes.

Vad är en mall för hälsokontroll?

När man designar en verksamhetskritisk och högtillgänglig applikation är det mycket viktigt att tänka på en sådan aspekt som feltolerans. En applikation anses feltolerant om den snabbt återhämtar sig från ett fel. En typisk molnapplikation använder en mikrotjänstarkitektur – där varje komponent placeras i en separat behållare. Och för att se till att applikationen på k8s är högst tillgänglig när du designar ett kluster måste du följa vissa mönster. Bland dem finns mallen för hälsokontroll. Den definierar hur applikationen kommunicerar till k8s att den är frisk. Detta är inte bara information om huruvida podden är igång, utan också om hur den tar emot och svarar på förfrågningar. Ju mer Kubernetes vet om poddens hälsa, desto smartare beslut fattar den om trafikdirigering och lastbalansering. Sålunda tillåter High Observability-principen att applikationen kan svara på förfrågningar i tid.

High Observability Principle (HOP)

Principen om hög observerbarhet är en av principer för att utforma containeriserade applikationer. I en mikrotjänstarkitektur bryr sig inte tjänsterna om hur deras begäran behandlas (och med rätta), men det som spelar roll är hur de får svar från de mottagande tjänsterna. Till exempel, för att autentisera en användare, skickar en behållare en HTTP-förfrågan till en annan och förväntar sig ett svar i ett visst format - det är allt. PythonJS kan också behandla begäran, och Python Flask kan svara. Behållare är som svarta lådor med dolt innehåll för varandra. NOP-principen kräver dock att varje tjänst exponerar flera API-slutpunkter som indikerar hur hälsosam den är, såväl som dess beredskap och feltoleransstatus. Kubernetes efterfrågar dessa indikatorer för att kunna tänka igenom nästa steg för routing och lastbalansering.

En väldesignad molnapplikation loggar sina huvudhändelser med standard I/O-strömmarna STDERR och STDOUT. Därefter kommer en hjälptjänst, till exempel filebeat, logstash eller fluentd, som levererar loggar till ett centraliserat övervakningssystem (till exempel Prometheus) och ett logginsamlingssystem (ELK-programsvit). Diagrammet nedan visar hur en molnapplikation fungerar enligt Health Test Pattern och High Observability Principle.

Bästa metoder för Kubernetes-behållare: hälsokontroller

Hur applicerar man hälsokontrollmönstret i Kubernetes?

Ur förpackningen övervakar k8s podarnas status med hjälp av en av kontrollerna (implementeringar, ReplicaSets, DaemonSets, StatefulSets etc., etc.). Efter att ha upptäckt att podden har fallit av någon anledning försöker styrenheten starta om den eller flytta den till en annan nod. En pod kan dock rapportera att den är igång, men att den själv inte fungerar. Låt oss ge ett exempel: din applikation använder Apache som webbserver, du installerade komponenten på flera pods i klustret. Eftersom biblioteket var felaktigt konfigurerat svarar alla förfrågningar till applikationen med kod 500 (internt serverfel). Vid kontroll av leverans ger en kontroll av poddarnas status ett lyckat resultat, men kunderna tycker annorlunda. Vi kommer att beskriva denna oönskade situation enligt följande:

Bästa metoder för Kubernetes-behållare: hälsokontroller

I vårt exempel gör k8s det funktionskontroll. Vid denna typ av verifiering kontrollerar kubelet kontinuerligt processens tillstånd i behållaren. När han förstår att processen har stoppat, kommer han att starta om den. Om felet kan lösas genom att helt enkelt starta om programmet, och programmet är designat för att stängas av vid eventuella fel, är en processhälsokontroll allt du behöver för att följa NOP och hälsotestmönstret. Den enda synden är att inte alla fel elimineras genom att starta om. I det här fallet erbjuder k8s två djupare sätt att identifiera problem med podden: livlighet Sond и beredskap Sond.

LivenessProbe

Under livlighet Sond kubelet utför 3 typer av kontroller: bestämmer inte bara om podden körs, utan också om den är redo att ta emot och svara på förfrågningar:

  • Ställ in en HTTP-förfrågan till podden. Svaret måste innehålla en HTTP-svarskod i intervallet från 200 till 399. Således signalerar koderna 5xx och 4xx att podden har problem, trots att processen körs.
  • För att testa pods med icke-HTTP-tjänster (till exempel Postfix-e-postservern) måste du upprätta en TCP-anslutning.
  • Utför ett godtyckligt kommando för en pod (internt). Kontrollen anses vara lyckad om kommandots slutförandekod är 0.

Ett exempel på hur detta fungerar. Nästa poddefinition innehåller en NodeJS-applikation som kastar ett 500-fel på HTTP-förfrågningar. För att säkerställa att behållaren startas om när ett sådant fel tas emot 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 poddefinition, men vi lägger till ett objekt .spec.containers.livenessProbe. Parameter httpGet accepterar sökvägen till vilken HTTP GET-begäran skickas (i vårt exempel är detta /, men i stridsscenarier kan det finnas något liknande /api/v1/status). En annan livenessProbe accepterar en parameter initialDelaySeconds, som instruerar verifieringsoperationen att vänta ett visst antal sekunder. Fördröjningen behövs eftersom behållaren behöver tid för att starta, och när den startas om kommer den att vara otillgänglig under en tid.

För att tillämpa den här inställningen på ett kluster, använd:

kubectl apply -f pod.yaml

Efter några sekunder kan du kontrollera innehållet i podden med följande kommando:

kubectl describe pods node500

I slutet av utgången, hitta det är vad.

Som du kan se initierade livenessProbe en HTTP GET-begäran, behållaren genererade ett fel 500 (vilket är vad den var programmerad att göra) och kubelet startade om den.

Om du undrar hur NideJS-applikationen programmerades, här är 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("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" ]

Det är viktigt att notera detta: livenessProbe kommer bara att starta om behållaren om den misslyckas. Om en omstart inte korrigerar felet som hindrar behållaren från att köras, kommer kubelet inte att kunna vidta åtgärder för att åtgärda problemet.

beredskap Sond

readinessProbe fungerar på samma sätt som livenessProbes (GET-förfrågningar, TCP-kommunikation och kommandoexekvering), förutom felsökningsåtgärder. Behållaren där felet upptäcks startas inte om utan är isolerad från inkommande trafik. Föreställ dig att en av behållarna utför många beräkningar eller är under tung belastning, vilket gör att svarstiderna ökar. I fallet med livenessProbe utlöses kontrollen av responstillgänglighet (via timeoutSeconds check-parametern), varefter kubelet startar om behållaren. När den startas börjar behållaren utföra resurskrävande uppgifter och startas om igen. Detta kan vara avgörande för applikationer som behöver svarshastighet. Till exempel, en bil på vägen väntar på svar från servern, svaret försenas - och bilen råkar ut för en olycka.

Låt oss skriva en redinessProbe-definition som kommer att ställa in GET-begärans svarstid till högst två sekunder, och applikationen kommer att svara på GET-begäran efter 5 sekunder. Filen pod.yaml ska se ut så här:

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 en pod med kubectl:

kubectl apply -f pod.yaml

Låt oss vänta ett par sekunder och sedan se hur beredskapsproben fungerade:

kubectl describe pods nodedelayed

I slutet av utgången kan du se att några av händelserna liknar varandra den här.

Som du kan se startade kubectl inte om podden när kontrolltiden översteg 2 sekunder. Istället avbröt han begäran. Inkommande kommunikation omdirigeras till andra fungerande poddar.

Observera att nu när podden är avladdad dirigerar kubectl förfrågningar till den igen: svar på GET-förfrågningar är inte längre försenade.

För jämförelse, nedan är den modifierade app.js-filen:

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öre tillkomsten av molnapplikationer var loggar det primära sättet att övervaka och kontrollera applikationernas hälsa. Det fanns dock inget sätt att vidta några korrigerande åtgärder. Loggar är fortfarande användbara idag, de måste samlas in och skickas till ett logginsamlingssystem för att analysera nödsituationer och fatta beslut. [Allt detta kunde göras utan molnapplikationer med till exempel monit, men med k8s blev det mycket enklare :) – reds. anmärkning. ]

Idag måste korrigeringar göras nästan i realtid, så ansökningar behöver inte längre vara svarta lådor. Nej, de bör visa slutpunkter som gör det möjligt för övervakningssystem att fråga och samla in värdefull data om processernas tillstånd så att de kan svara omedelbart om det behövs. Detta kallas Performance Test Design Pattern, som följer High Observability Principle (HOP).

Kubernetes erbjuder två typer av hälsokontroller som standard: readinessProbe och livenessProbe. Båda använder samma typer av kontroller (HTTP GET-förfrågningar, TCP-kommunikation och kommandoexekvering). De skiljer sig åt i vilka beslut de fattar som svar på problem i baljorna. livenessProbe startar om behållaren i hopp om att felet inte ska hända igen, och readinessProbe isolerar podden från inkommande trafik tills orsaken till problemet är löst.

Korrekt applikationsdesign bör innefatta båda typerna av kontroll och säkerställa att de samlar in tillräckligt med data, särskilt när ett undantag görs. Den bör också visa nödvändiga API-slutpunkter som förser övervakningssystemet (Prometheus) med viktiga hälsomått.

Källa: will.com

Lägg en kommentar