Best Practices for Kubernetes Containers: Cuntrolli di salute

Best Practices for Kubernetes Containers: Cuntrolli di salute

TL; DR

  • Per ottene una alta osservabilità di cuntenituri è microservizi, i logs è e metriche primarie ùn sò micca abbastanza.
  • Per una ricuperazione più rapida è una resilienza aumentata, l'applicazioni anu da applicà u Principiu di l'Alta Osservabilità (HOP).
  • À u livellu di l'applicazione, NOP richiede: logu propiu, monitoraghju strettu, cuntrolli di sanità, è traccia di rendiment / transizione.
  • Aduprate cuntrolli cum'è un elementu di NOR Prontu Probe и prova di vita Kubernetes.

Chì ghjè un mudellu di cuntrollu di salute?

Quandu cuncepisce una applicazione critica di missione è assai dispunibile, hè assai impurtante per pensà à un aspettu cum'è a tolleranza di difetti. Una applicazione hè cunsiderata tollerante à i difetti s'ellu si recupera rapidamente da u fallimentu. Una tipica applicazione cloud usa una architettura di microservizi - induve ogni cumpunente hè piazzatu in un containeru separatu. È per assicurà chì l'applicazione nantu à k8s hè assai dispunibule quandu cuncepite un cluster, avete bisognu di seguità certi mudelli. Frà elli hè u Template di Cuntrolla di Salute. Definisce cumu l'applicazione comunica à k8s chì hè sana. Questa ùn hè micca solu infurmazione nantu à se u pod hè in esecuzione, ma ancu nantu à cumu riceve è risponde à e dumande. Quantu più Kubernetes sà di a salute di u pod, e decisioni più intelligenti chì piglia nantu à u routing di u trafficu è l'equilibriu di carica. Cusì, u Principiu di l'Alta Osservabilità permette à l'applicazione di risponde à e dumande in una manera puntuale.

Principiu di l'Alta Osservabilità (HOP)

U principiu di alta observabilità hè unu di principii per u disignu di applicazioni containerizzate. In una architettura di microservizi, i servizii ùn importa micca cumu a so dumanda hè trattata (è ghjustu), ma ciò chì importa hè cumu ricevenu risposte da i servizii chì ricevenu. Per esempiu, per autentificà un utilizatore, un cuntainer manda una dumanda HTTP à un altru, aspittendu una risposta in un certu formatu - questu hè tuttu. PythonJS pò ancu processà a dumanda, è Python Flask pò risponde. I cuntenituri sò cum'è scatuli neri cù cuntenutu oculatu l'un à l'altru. In ogni casu, u principiu di NOP richiede chì ogni serviziu espose multiple endpoints API chì indicanu quantu hè sanu, è ancu a so prontezza è u statu di tolleranza à i difetti. Kubernetes dumanda questi indicatori per pensà à i prossimi passi per u routing è l'equilibriu di carica.

Una applicazione cloud ben cuncepita registra i so avvenimenti principali utilizendu i flussi I/O standard STDERR è STDOUT. Dopu vene un serviziu ausiliariu, per esempiu filebeat, logstash o fluentd, chì furnisce logs à un sistema di surviglianza centralizatu (per esempiu Prometheus) è un sistema di cullizzioni di log (suite di software ELK). U diagramma sottu mostra cumu funziona una applicazione in nuvola secondu u Pattern di Test di Salute è u Principiu d'Alta Observabilità.

Best Practices for Kubernetes Containers: Cuntrolli di salute

Cumu applicà u mudellu di cuntrollu di salute in Kubernetes?

Fora di a scatula, k8s monitoreghja u statutu di i pods utilizendu unu di i cuntrolli (Implichi, ReplicaSets, DaemonSets, StatefulSets ecc., ecc.). Dopu avè scupertu chì u pod hè cascatu per una certa ragione, u controller prova di riavvia o traslassi à un altru node. In ogni casu, un podu pò informà chì hè in funziunamentu, ma ellu stessu ùn funziona micca. Fighjemu un esempiu: a vostra applicazione usa Apache cum'è un servitore web, avete installatu u cumpunente nantu à parechji pods di u cluster. Siccomu a biblioteca hè stata cunfigurata incorrectamente, tutte e dumande à l'applicazione rispondenu cù u codice 500 (errore di u servitore internu). Quandu si cuntrolla a consegna, a verificazione di u statutu di pods dà un risultatu successu, ma i clienti pensanu in modu diversu. Descriveremu sta situazione indesiderata cusì:

Best Practices for Kubernetes Containers: Cuntrolli di salute

In u nostru esempiu, k8s faci verificazione di funziunalità. In questu tipu di verificazione, u kubelet verifica continuamente u statu di u prucessu in u cuntinuu. Una volta capisce chì u prucessu hè firmatu, riavviarà. Se l'errore pò esse risoltu da solu riavvia l'applicazione, è u prugramma hè pensatu per chjude ogni errore, allora un cuntrollu di salute di u prucessu hè tuttu ciò chì avete bisognu di seguità u NOP è u Pattern di Test di Salute. L'unica pietà hè chì micca tutti l'errori sò eliminati da u riavviu. In questu casu, k8s offre 2 modi più profondi per identificà i prublemi cù u pod: prova di vita и Prontu Probe.

LivenessProbe

Duranti u prova di vita kubelet esegue 3 tipi di cuntrolli: ùn solu determina se u pod hè in esecuzione, ma ancu s'ellu hè prontu à riceve è risponde bè à e dumande:

  • Configurate una dumanda HTTP à u pod. A risposta deve cuntene un codice di risposta HTTP in a gamma da 200 à 399. Cusì, i codici 5xx è 4xx signalanu chì u pod hè avè prublemi, ancu s'è u prucessu hè in esecuzione.
  • Per pruvà pods cù servizii non-HTTP (per esempiu, u servitore di posta Postfix), avete bisognu di stabilisce una cunnessione TCP.
  • Eseguite un cumandamentu arbitrariu per un pod (internu). A verificazione hè cunsiderata successu se u codice di cumpiimentu di u cumandamentu hè 0.

Un esempiu di cumu si travaglia. A prossima definizione di pod cuntene una applicazione NodeJS chì tira un errore 500 nantu à e dumande HTTP. Per assicurà chì u cuntinuu hè riavviatu quandu riceve un tali errore, usemu u paràmetru 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

Questu ùn hè micca sfarente di qualsiasi altra definizione di pod, ma aghjustemu un oggettu .spec.containers.livenessProbe. Parametru httpGet accetta a strada à quale hè mandata a dumanda HTTP GET (in u nostru esempiu questu hè /, ma in i scenarii di cummattimentu pò esse qualcosa cum'è /api/v1/status). Un altru livenessProbe accetta un paràmetru initialDelaySeconds, chì urdineghja l'operazione di verificazione per aspittà un numeru specificatu di seconde. U ritardu hè necessariu perchè u cuntinuu hà bisognu di tempu per inizià, è quandu riavviatu ùn serà micca dispunibule per qualchì tempu.

Per applicà sta paràmetra à un cluster, utilizate:

kubectl apply -f pod.yaml

Dopu qualchì seconde, pudete cuntrollà u cuntenutu di u pod cù u cumandimu seguitu:

kubectl describe pods node500

À a fine di l'output, truvate hè ciò chì.

Comu pudete vede, livenessProbe hà iniziatu una dumanda HTTP GET, u cuntinuu hà generatu un errore 500 (chì hè ciò chì era programatu per fà), è u kubelet hà riavviatu.

Sè vi dumandate cumu l'applicazione NideJS hè stata programata, eccu l'app.js è Dockerfile chì sò stati utilizati:

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

Hè impurtante di nutà questu: livenessProbe riavviarà u cuntinuu solu s'ellu falla. Se un riavviu ùn curreghja micca l'errore chì impedisce à u cuntinuu di correre, u kubelet ùn serà micca capaci di piglià l'azzione per corregge u prublema.

Prontu Probe

ReadinessProbe funziona in modu simile à livenessProbes (richieste GET, cumunicazioni TCP è esecuzione di cumandamenti), eccettu per l'azzioni di risoluzione di prublemi. U cuntinuu in u quale u fallimentu hè rilevatu ùn hè micca riavviatu, ma hè isolatu da u trafficu entrante. Imagine chì unu di i cuntenituri faci assai calculi o hè sottumessu à una carica pesante, facendu chì i tempi di risposta aumentanu. In u casu di livenessProbe, a verificazione di a dispunibilità di a risposta hè attivata (via u paràmetru di verificazione di timeoutSeconds), dopu chì u kubelet riavvia u cuntinuu. Quandu hà cuminciatu, u cuntinuu cumencia à eseguisce travaglii intensivi di risorse è hè riavviatu di novu. Questu pò esse criticu per l'applicazioni chì necessitanu rapidità di risposta. Per esempiu, una vittura mentre in a strada aspetta una risposta da u servitore, a risposta hè ritardata - è a vittura entra in un accidente.

Scrivemu una definizione di redinessProbe chì stabiliscerà u tempu di risposta di a dumanda GET à micca più di dui seconde, è l'applicazione risponde à a dumanda GET dopu à 5 seconde. U schedariu pod.yaml deve esse cusì:

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

Implementemu un pod cù kubectl:

kubectl apply -f pod.yaml

Aspittemu un paru di sicondi è poi vede cumu u ReadinessProbe hà travagliatu:

kubectl describe pods nodedelayed

À a fine di l'output, pudete vede chì certi avvenimenti sò simili questu.

Comu pudete vede, kubectl ùn hà micca riavviatu u pod quandu u tempu di cuntrollu superava 2 seconde. Invece, hà annullatu a dumanda. I cumunicazioni entranti sò rediretti à altri pods di travagliu.

Nota chì avà chì u pod hè scaricatu, kubectl indirizza e dumande à ellu di novu: e risposte à e dumande GET ùn sò più ritardate.

Per paragone, quì sottu hè u schedariu app.js mudificatu:

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
Prima di l'avventu di l'applicazioni in nuvola, i logs eranu i mezi primari di surviglianza è cuntrollà a salute di l'applicazioni. Tuttavia, ùn ci era micca mezzu per piglià alcuna azzione currettiva. I logs sò sempre utili oghje; anu da esse recullati è mandati à un sistema di cullizzioni di log per analizà e situazioni d'emergenza è piglià decisioni. [Tuttu chistu puderia esse fattu senza l'applicazioni in nuvola chì utilizanu monit, per esempiu, ma cù k8s hè diventatu assai più faciule :) - nota di l'editore. ]

Oghje, e currezzione devenu esse fatte quasi in tempu reale, cusì l'applicazioni ùn anu più esse scatuli neri. Innò, anu da mustrà i punti finali chì permettenu à i sistemi di monitoraghju di interrogà è raccoglie dati preziosi nantu à u statu di i prucessi in modu chì ponu risponde istantaneamente se necessariu. Questu hè chjamatu u Pattern di Disegnu di Test di Prestazione, chì seguita u Principiu di High Observability (HOP).

Kubernetes offre 2 tipi di cuntrolli di salute per difettu: ReadinessProbe è LivenessProbe. Tramindui utilizanu i stessi tipi di cuntrolli (richieste HTTP GET, cumunicazioni TCP è esecuzione di cumandamenti). Differiscenu in e decisioni chì facenu in risposta à i prublemi in i baccelli. livenessProbe riavvia u cuntinuu in a speranza chì l'errore ùn succede micca, è ReadinessProbe isola u pod da u trafficu entrante finu à chì a causa di u prublema hè risolta.

U disignu propiu di l'applicazione deve include i dui tipi di cuntrolli è assicuratevi chì recullanu abbastanza dati, soprattuttu quandu una eccezzioni hè ghjittata. Deve ancu vede l'endpoints API necessarii chì furnisce u sistema di monitoraghju (Prometheus) cù metriche di salute impurtanti.

Source: www.habr.com

Add a comment