Plej bonaj Praktikoj por Kubernetes Ujoj: Sankontroloj

Plej bonaj Praktikoj por Kubernetes Ujoj: Sankontroloj

TL; DR

  • Por atingi altan observeblecon de ujoj kaj mikroservoj, protokoloj kaj primaraj metrikoj ne sufiĉas.
  • Por pli rapida reakiro kaj pliigita rezisteco, aplikoj devas apliki la Principon de Alta Observeblo (HOP).
  • Sur la aplika nivelo, NOP postulas: taŭgan registradon, proksiman monitoradon, prudentajn kontrolojn kaj agadon/transiran spuradon.
  • Uzu ĉekojn kiel elementon de NOR ReadinessProbe и livenessProbe Kubernetes.

Kio estas Sankontrola Ŝablono?

Kiam vi desegnas misi-kritikan kaj tre disponeblan aplikaĵon, estas tre grave pensi pri tia aspekto kiel erartoleremo. Apliko estas konsiderata eraro tolera se ĝi rapide resaniĝas post fiasko. Tipa nuba aplikaĵo uzas arkitekturon de mikroservoj - kie ĉiu komponanto estas metita en apartan ujon. Kaj por certigi, ke la aplikaĵo sur k8s estas tre disponebla kiam vi desegnas areton, vi devas sekvi certajn ŝablonojn. Inter ili estas la Ŝablono pri Sankontrolo. Ĝi difinas kiel la aplikaĵo komunikas al k8s ke ĝi estas sana. Ĉi tio ne estas nur informoj pri ĉu la pod funkcias, sed ankaŭ pri kiel ĝi ricevas kaj respondas al petoj. Ju pli Kubernetes scias pri la sano de la pod, des pli inteligentaj decidoj ĝi faras pri trafikvojigo kaj ŝarĝoekvilibro. Tiel, la Alta Observeblo-Principo permesas al la aplikaĵo respondi al petoj ĝustatempe.

Principo de Alta Observeblo (HOP)

La principo de alta observeblo estas unu el principoj por desegni konteneritajn aplikojn. En mikroserva arkitekturo, servoj ne zorgas pri kiel ilia peto estas procesita (kaj ĝuste), sed gravas kiel ili ricevas respondojn de la ricevantaj servoj. Ekzemple, por aŭtentikigi uzanton, unu ujo sendas HTTP-peton al alia, atendante respondon en certa formato - jen ĉio. PythonJS ankaŭ povas prilabori la peton, kaj Python Flask povas respondi. Ujoj estas kiel nigraj skatoloj kun kaŝita enhavo unu al la alia. Tamen, la NOP-principo postulas, ke ĉiu servo elmontru multoblajn API-finpunktojn, kiuj indikas kiom sana ĝi estas, same kiel ĝian pretecon kaj faŭltoleremo-statuson. Kubernetes petas ĉi tiujn indikilojn por pripensi la sekvajn paŝojn por vojigo kaj ŝarĝo-ekvilibro.

Bone desegnita nuba aplikaĵo registras siajn ĉefajn eventojn uzante la normajn I/O-fluojn STDERR kaj STDOUT. Poste venas helpa servo, ekzemple filebeat, logstash aŭ fluentd, liverante protokolojn al centralizita monitora sistemo (ekzemple Prometheus) kaj ŝtipkolekta sistemo (ELK-programaro). La suba diagramo montras kiel nuba aplikaĵo funkcias laŭ la Sana Testo-Ŝablono kaj la Alta Observeblo-Principo.

Plej bonaj Praktikoj por Kubernetes Ujoj: Sankontroloj

Kiel apliki la Sankontrolan ŝablonon en Kubernetes?

El la skatolo, k8s monitoras la staton de la podoj uzante unu el la regiloj (Malplenigoj, ReplicaSets, DaemonSets, StatefulSets ktp., ktp.). Malkovrinte, ke la balgo falis ial, la regilo provas rekomenci ĝin aŭ movi ĝin al alia nodo. Tamen, pod povas raporti ke ĝi funkcias, sed ĝi mem ne funkcias. Ni donu ekzemplon: via aplikaĵo uzas Apache kiel retservilon, vi instalis la komponanton sur pluraj podoj de la grapolo. Ĉar la biblioteko estis malĝuste agordita, ĉiuj petoj al la aplikaĵo respondas per kodo 500 (interna servila eraro). Kiam vi kontrolas liveron, kontroli la staton de balgoj donas sukcesan rezulton, sed klientoj pensas malsame. Ni priskribos ĉi tiun nedezirindan situacion jene:

Plej bonaj Praktikoj por Kubernetes Ujoj: Sankontroloj

En nia ekzemplo, k8s faras kontrolo de funkcieco. En ĉi tiu speco de konfirmo, la kubelet kontinue kontrolas la staton de la procezo en la ujo. Post kiam li komprenas, ke la procezo ĉesis, li rekomencos ĝin. Se la eraro povas esti solvita per simple rekomenco de la aplikaĵo, kaj la programo estas desegnita por malŝalti ajnan eraron, tiam proceza sankontrolo estas ĉio, kion vi bezonas por sekvi la NOP kaj la Sanan Testo-Ŝablonon. La sola domaĝo estas, ke ne ĉiuj eraroj estas forigitaj per rekomenco. En ĉi tiu kazo, k8s ofertas 2 pli profundajn manierojn identigi problemojn kun la pod: livenessProbe и ReadinessProbe.

LivenessProbe

Dum la livenessProbe kubelet faras 3 specojn de kontroloj: ne nur determinas ĉu la pod funkcias, sed ankaŭ ĉu ĝi estas preta ricevi kaj adekvate respondi al petoj:

  • Agordu HTTP-peton al la pod. La respondo devas enhavi HTTP-respondkodon en la intervalo de 200 ĝis 399. Tiel, kodoj 5xx kaj 4xx signalas ke la pod havas problemojn, kvankam la procezo funkcias.
  • Por testi podojn kun ne-HTTP-servoj (ekzemple, la poŝtservilo Postfix), vi devas establi TCP-konekton.
  • Efektivigu arbitran komandon por pod (interne). La kontrolo estas konsiderata sukcesa se la komanda finkodo estas 0.

Ekzemplo de kiel ĉi tio funkcias. La sekva poddifino enhavas NodeJS-aplikon, kiu ĵetas eraron 500 sur HTTP-petoj. Por certigi, ke la ujo estas rekomencita ricevinte tian eraron, ni uzas la parametron 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

Ĉi tio ne diferencas de iu ajn alia poddifino, sed ni aldonas objekton .spec.containers.livenessProbe... Parametro httpGet akceptas la vojon al kiu la HTTP GET-peto estas sendita (en nia ekzemplo tio estas /, sed en batalscenaroj povas esti io kiel /api/v1/status). Alia livenessProbe akceptas parametron initialDelaySeconds, kiu instrukcias la konfirmoperacion atendi difinitan nombron da sekundoj. La prokrasto estas necesa ĉar la ujo bezonas tempon por komenci, kaj kiam rekomencite ĝi estos neatingebla dum iom da tempo.

Por apliki ĉi tiun agordon al areto, uzu:

kubectl apply -f pod.yaml

Post kelkaj sekundoj, vi povas kontroli la enhavon de la pod per la sekva komando:

kubectl describe pods node500

Ĉe la fino de la eligo, trovu jen kio.

Kiel vi povas vidi, livenessProbe iniciatis HTTP GET peton, la ujo generis eraron 500 (kion ĝi estis programita fari), kaj la kubelet rekomencis ĝin.

Se vi scivolas kiel la aplikaĵo NideJS estis programita, jen la app.js kaj Dockerfile, kiuj estis uzataj:

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

Gravas noti ĉi tion: livenessProbe nur rekomencos la ujon se ĝi malsukcesas. Se rekomenco ne korektas la eraron, kiu malhelpas la ujon funkcii, la kubelet ne povos agi por korekti la problemon.

ReadinessProbe

ReadinessProbe funkcias simile al livenessProbes (GET-petoj, TCP-komunikadoj kaj komando-ekzekuto), krom por solvo de problemoj. La ujo en kiu la fiasko estas detektita ne estas rekomencita, sed estas izolita de envenanta trafiko. Imagu, ke unu el la ujoj faras multajn kalkulojn aŭ estas sub peza ŝarĝo, igante respondajn tempojn pliiĝi. En la kazo de livenessProbe, la responda havebleckontrolo estas ekigita (per la timeoutSeconds-kontrola parametro), post kio la kubelet rekomencas la ujon. Kiam komencita, la ujo komencas plenumi resurs-intensajn taskojn kaj denove estas rekomencita. Ĉi tio povas esti kritika por aplikoj kiuj bezonas respondrapidecon. Ekzemple, aŭto dum survoje atendas respondon de la servilo, la respondo estas prokrastita - kaj la aŭto eniras akcidenton.

Ni skribu redinessProbe-difinon, kiu starigos la respondtempon de GET-peto al ne pli ol du sekundoj, kaj la aplikaĵo respondos al la GET-peto post 5 sekundoj. La pod.yaml dosiero devus aspekti jene:

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

Ni disfaldu pod kun kubectl:

kubectl apply -f pod.yaml

Ni atendu kelkajn sekundojn kaj poste vidu kiel funkciis la ReadinessProbe:

kubectl describe pods nodedelayed

Ĉe la fino de la eligo vi povas vidi ke kelkaj el la eventoj estas similaj ĉi tiun.

Kiel vi povas vidi, kubectl ne rekomencis la pod kiam la tempo de kontrolo superis 2 sekundojn. Anstataŭe, li nuligis la peton. Envenantaj komunikadoj estas redirektitaj al aliaj, funkciaj podoj.

Notu, ke nun kiam la pod estas malŝarĝita, kubectl denove sendas petojn al ĝi: respondoj al GET-petoj ne plu estas prokrastaj.

Por komparo, malsupre estas la modifita app.js-dosiero:

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
Antaŭ la apero de nubaj aplikaĵoj, protokoloj estis la ĉefaj rimedoj por kontroli kaj kontroli aplikaĵan sanon. Tamen ne estis rimedo por fari ajnan korektan agon. Tagaloj daŭre estas utilaj hodiaŭ; ili devas esti kolektitaj kaj senditaj al tagalo-kolekta sistemo por analizi krizajn situaciojn kaj fari decidojn. [Ĉio ĉi povus esti farita sen nubaj aplikaĵoj uzante monit, ekzemple, sed kun k8s ĝi fariĝis multe pli facila :) - noto de la redaktoro. ]

Hodiaŭ, korektoj devas esti faritaj preskaŭ en reala tempo, do aplikoj ne plu devas esti nigraj skatoloj. Ne, ili devus montri finpunktojn, kiuj permesas monitorajn sistemojn pridemandi kaj kolekti valorajn datumojn pri la stato de procezoj, por ke ili povu respondi tuj se necese. Ĉi tio estas nomita la Performance Test Design Pattern, kiu sekvas la High Observability Principle (HOP).

Kubernetes ofertas 2 specojn de sankontroloj defaŭlte: ReadinessProbe kaj livenessProbe. Ambaŭ uzas la samajn specojn de kontroloj (HTTP GET-petoj, TCP-komunikadoj kaj komanda ekzekuto). Ili malsamas en kiaj decidoj ili faras responde al problemoj en la balgoj. livenessProbe rekomencas la ujon kun la espero, ke la eraro ne okazos denove, kaj readinessProbe izolas la pod de envenanta trafiko ĝis la kaŭzo de la problemo estas solvita.

Taŭga aplika dezajno devus inkluzivi ambaŭ specojn de kontrolo kaj certigi ke ili kolektas sufiĉe da datumoj, precipe kiam escepto estas ĵetita. Ĝi ankaŭ devus montri la necesajn API-finpunktojn, kiuj provizas la monitoran sistemon (Prometheus) per gravaj sanmetrikoj.

fonto: www.habr.com

Aldoni komenton