A Kubernetes-tárolók bevált gyakorlatai: állapotfelmérés

A Kubernetes-tárolók bevált gyakorlatai: állapotfelmérés

TL, DR

  • A konténerek és mikroszolgáltatások jó megfigyelhetőségének eléréséhez a naplók és az elsődleges mérőszámok nem elegendőek.
  • A gyorsabb helyreállítás és a fokozott rugalmasság érdekében az alkalmazásoknak alkalmazniuk kell a High Observability Principle (HOP) elvet.
  • Alkalmazási szinten a NOP megköveteli: megfelelő naplózást, szoros megfigyelést, józansági ellenőrzéseket és teljesítmény/átmenet nyomon követést.
  • Használja a csekket a NOR elemeként készenléti szonda и elevenség Probe Kubernetes.

Mi az az állapotfelmérés sablon?

A kritikus fontosságú és magas rendelkezésre állású alkalmazás tervezésekor nagyon fontos olyan szempontra gondolni, mint a hibatűrés. Egy alkalmazás akkor tekinthető hibatűrőnek, ha gyorsan helyreáll a meghibásodás után. Egy tipikus felhőalkalmazás mikroszolgáltatási architektúrát használ – ahol minden egyes komponens külön tárolóban van elhelyezve. És annak érdekében, hogy a k8s-on lévő alkalmazás magas szinten elérhető legyen a fürt tervezésekor, bizonyos mintákat kell követnie. Ezek közé tartozik az állapotfelmérés sablonja. Meghatározza, hogy az alkalmazás hogyan kommunikálja a k8s-szal, hogy egészséges. Ez nem csak arról szól, hogy a pod fut-e, hanem arról is, hogyan fogadja és válaszolja meg a kéréseket. Minél többet tud a Kubernetes a pod állapotáról, annál okosabb döntéseket hoz a forgalomirányítással és a terheléselosztással kapcsolatban. Így a magas megfigyelhetőségi elv lehetővé teszi az alkalmazás számára, hogy időben válaszoljon a kérésekre.

Magas megfigyelhetőségi elv (HOP)

A magas megfigyelhetőség elve az egyik konténeres alkalmazások tervezésének alapelvei. A mikroszolgáltatások architektúrájában a szolgáltatásokat nem érdekli, hogyan dolgozzák fel kérésüket (és ez így van), hanem az számít, hogyan kapnak választ a fogadó szolgáltatásoktól. Például egy felhasználó hitelesítéséhez az egyik tároló HTTP-kérést küld a másiknak, és egy bizonyos formátumban vár választ – ennyi. A PythonJS is képes feldolgozni a kérést, és a Python Flask válaszolni is tud. A konténerek olyanok, mint egy fekete doboz, rejtett tartalommal egymás számára. A NOP-elv azonban megköveteli, hogy minden szolgáltatás több API-végpontot tegyen közzé, amelyek jelzik, hogy mennyire egészséges, valamint a készenléti és hibatűrési állapotát. A Kubernetes azért kéri ezeket a mutatókat, hogy átgondolja az útválasztás és a terheléselosztás következő lépéseit.

Egy jól megtervezett felhőalkalmazás a szabványos STDERR és STDOUT I/O adatfolyamok segítségével naplózza fő eseményeit. Ezután jön egy kiegészítő szolgáltatás, például a filebeat, logstash vagy fluentd, amely a naplókat egy központi felügyeleti rendszerhez (például Prometheus) és egy naplógyűjtő rendszerhez (ELK szoftvercsomag) szállítja. Az alábbi diagram bemutatja, hogyan működik egy felhőalkalmazás az állapotteszt minta és a magas megfigyelhetőségi elv szerint.

A Kubernetes-tárolók bevált gyakorlatai: állapotfelmérés

Hogyan kell alkalmazni az állapotfelmérés mintáját a Kubernetesben?

A dobozból kivéve a k8s figyeli a podok állapotát az egyik vezérlő segítségével (Deployments, ReplicaSets, DaemonSets, StatefulSets stb. stb.). Miután felfedezte, hogy a pod valamilyen okból leesett, a vezérlő megpróbálja újraindítani, vagy áthelyezni egy másik csomópontra. A pod azonban jelezheti, hogy működik és működik, de maga nem működik. Nézzünk egy példát: az alkalmazásod az Apache-t használja webszerverként, a komponenst a fürt több podjára telepítetted. Mivel a könyvtár helytelenül lett konfigurálva, az alkalmazáshoz intézett összes kérés 500-as kóddal válaszol (belső szerverhiba). A kiszállítás ellenőrzésekor a hüvelyek állapotának ellenőrzése sikeres eredményt ad, de a vásárlók másként gondolkodnak. Ezt a nemkívánatos helyzetet a következőképpen írjuk le:

A Kubernetes-tárolók bevált gyakorlatai: állapotfelmérés

Példánkban a k8s igen működőképesség ellenőrzése. Az ilyen típusú ellenőrzés során a kubelet folyamatosan ellenőrzi a folyamat állapotát a tárolóban. Miután megérti, hogy a folyamat leállt, újraindítja. Ha a hiba az alkalmazás egyszerű újraindításával megoldható, és a program úgy van kialakítva, hogy bármilyen hiba esetén leálljon, akkor a folyamatállapot-ellenőrzésre van szükség a NOP és az állapotteszt minta követéséhez. Csak az a kár, hogy nem minden hiba szűnik meg újraindítással. Ebben az esetben a k8s két mélyebb módszert kínál a podlal kapcsolatos problémák azonosítására: elevenség Probe и készenléti szonda.

LivenessProbe

Alatt elevenség Probe A kubelet 3 típusú ellenőrzést hajt végre: nemcsak azt határozza meg, hogy a pod fut-e, hanem azt is, hogy készen áll-e a kérések fogadására és megfelelő megválaszolására:

  • Állítson be egy HTTP-kérést a podhoz. A válasznak 200 és 399 közötti HTTP-válaszkódot kell tartalmaznia. Így az 5xx és 4xx kódok azt jelzik, hogy a podban problémák vannak, még akkor is, ha a folyamat fut.
  • A nem HTTP-szolgáltatásokkal (például a Postfix levelezőkiszolgálóval) rendelkező pod-ok teszteléséhez TCP-kapcsolatot kell létrehoznia.
  • Tetszőleges parancs végrehajtása egy podhoz (belsőleg). Az ellenőrzés akkor tekinthető sikeresnek, ha a parancs befejezési kódja 0.

Egy példa ennek működésére. A következő pod-definíció egy NodeJS-alkalmazást tartalmaz, amely 500-as hibát dob ​​a HTTP-kéréseknél. Annak érdekében, hogy a tároló újrainduljon, amikor ilyen hiba érkezik, a livenessProbe paramétert használjuk:

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

Ez nem különbözik bármely más pod-definíciótól, de hozzáadunk egy objektumot .spec.containers.livenessProbe... Paraméter httpGet elfogadja azt az elérési utat, amelyre a HTTP GET kérést küldi (példánkban ez /, de harci forgatókönyvekben előfordulhat ilyesmi /api/v1/status). Egy másik livenessProbe paramétert fogad el initialDelaySeconds, amely arra utasítja az ellenőrzési műveletet, hogy várjon meghatározott számú másodpercet. A késleltetésre azért van szükség, mert a tárolónak időre van szüksége az induláshoz, és újraindításkor egy ideig nem lesz elérhető.

Ha ezt a beállítást egy fürtre szeretné alkalmazni, használja a következőket:

kubectl apply -f pod.yaml

Néhány másodperc múlva a következő paranccsal ellenőrizheti a pod tartalmát:

kubectl describe pods node500

A kimenet végén keresse meg ez az.

Amint láthatja, a livenessProbe HTTP GET kérést kezdeményezett, a tároló 500-as hibát generált (ezre volt programozva), és a kubelet újraindította.

Ha kíváncsi arra, hogyan lett programozva a NideJS alkalmazás, itt található a használt app.js és 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" ]

Ezt fontos megjegyezni: a livenessProbe csak akkor indítja újra a tárolót, ha az meghibásodik. Ha az újraindítás nem javítja a hibát, amely megakadályozza a tároló futását, a kubelet nem tud lépéseket tenni a probléma megoldására.

készenléti szonda

A readinessProbe a livenessProbes-hoz hasonlóan működik (GET kérések, TCP-kommunikáció és parancsvégrehajtás), kivéve a hibaelhárítási műveleteket. A hibát észlelő tároló nem indul újra, hanem el van különítve a bejövő forgalomtól. Képzelje el, hogy az egyik tároló sok számítást végez, vagy nagy terhelés alatt áll, ami a válaszidő növekedését okozza. A livenessProbe esetén a válasz elérhetőség ellenőrzése indul (a timeoutSeconds check paraméteren keresztül), ami után a kubelet újraindítja a tárolót. Az indításkor a tároló erőforrás-igényes feladatokat kezd végrehajtani, és újraindul. Ez kritikus lehet azoknál az alkalmazásoknál, amelyek válaszsebességet igényelnek. Például egy autó, miközben úton van, a szerver válaszára vár, a válasz késik - és az autó balesetet szenved.

Írjunk egy redinessProbe definíciót, amely a GET kérés válaszidejét legfeljebb két másodpercre állítja be, és az alkalmazás 5 másodperc múlva válaszol a GET kérésre. A pod.yaml fájlnak így kell kinéznie:

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

Telepítsünk egy pod-ot a kubectl-lel:

kubectl apply -f pod.yaml

Várjunk néhány másodpercet, majd nézzük meg, hogyan működött a ReadinessProbe:

kubectl describe pods nodedelayed

A kimenet végén láthatja, hogy néhány esemény hasonló ezt.

Mint látható, a kubectl nem indította újra a pod-ot, amikor az ellenőrzési idő meghaladta a 2 másodpercet. Ehelyett visszavonta a kérést. A bejövő kommunikáció átirányításra kerül más, működő podokra.

Vegye figyelembe, hogy most, hogy a pod le van töltve, a kubectl ismét ráirányítja a kéréseket: a GET kérésekre adott válaszok többé nem késnek.

Összehasonlításképpen alább látható a módosított app.js fájl:

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
A felhőalkalmazások megjelenése előtt a naplók voltak az alkalmazások állapotának figyelésének és ellenőrzésének elsődleges eszközei. Korrekciós lépések megtételére azonban nem volt mód. A naplók ma is hasznosak, össze kell gyűjteni és el kell küldeni egy naplógyűjtő rendszerbe a vészhelyzetek elemzéséhez és a döntések meghozatalához. [Mindez például a monit segítségével felhőalkalmazások nélkül is megoldható volt, de a k8s-al sokkal egyszerűbb lett :) – a szerkesztő megjegyzése. ]

Ma a korrekciókat szinte valós időben kell elvégezni, így az alkalmazásoknak már nem kell fekete dobozoknak lenniük. Nem, olyan végpontokat kell mutatniuk, amelyek lehetővé teszik a megfigyelő rendszerek számára, hogy értékes adatokat kérdezzenek le és gyűjtsenek a folyamatok állapotáról, hogy szükség esetén azonnal válaszolhassanak. Ezt a teljesítményteszt tervezési mintának nevezik, amely a High Observability Principle (HOP) elvét követi.

A Kubernetes alapértelmezés szerint kétféle állapotellenőrzést kínál: readinessProbe és livenessProbe. Mindkettő azonos típusú ellenőrzéseket használ (HTTP GET kérések, TCP-kommunikáció és parancsvégrehajtás). Különböznek abban, hogy milyen döntéseket hoznak a hüvelyben fellépő problémákra válaszul. A livenessProbe újraindítja a tárolót abban a reményben, hogy a hiba nem fog megismétlődni, és a readinessProbe leválasztja a pod-ot a bejövő forgalomtól, amíg a probléma oka meg nem szűnik.

A megfelelő alkalmazástervezésnek tartalmaznia kell mindkét típusú ellenőrzést, és biztosítania kell, hogy elegendő adatot gyűjtsenek, különösen, ha kivételt tesznek. Meg kell mutatnia a szükséges API-végpontokat is, amelyek fontos állapotmérőkkel látják el a megfigyelőrendszert (Prometheus).

Forrás: will.com

Hozzászólás