Լավագույն պրակտիկա Kubernetes կոնտեյներների համար. առողջության ստուգումներ

Լավագույն պրակտիկա Kubernetes կոնտեյներների համար. առողջության ստուգումներ

TL. DR

  • Բեռնարկղերի և միկրոծառայությունների բարձր դիտելիության հասնելու համար գերանները և առաջնային չափումները բավարար չեն:
  • Ավելի արագ վերականգնման և ճկունության բարձրացման համար դիմումները պետք է կիրառեն Բարձր դիտարկելիության սկզբունքը (HOP):
  • Կիրառման մակարդակում NOP-ը պահանջում է.
  • Օգտագործեք չեկերը որպես NOR-ի տարր պատրաստակամության զոնդ и livenessProbe Կուբերնետես.

Ի՞նչ է առողջության ստուգման ձևանմուշը:

Առաքելության համար կարևոր և շատ հասանելի հավելված նախագծելիս շատ կարևոր է մտածել այնպիսի ասպեկտի մասին, ինչպիսին է սխալների հանդուրժողականությունը: Հավելվածը համարվում է սխալ հանդուրժող, եթե այն արագ վերականգնվում է ձախողումից: Տիպիկ ամպային հավելվածն օգտագործում է միկրոծառայությունների ճարտարապետություն, որտեղ յուրաքանչյուր բաղադրիչ տեղադրվում է առանձին կոնտեյներով: Եվ որպեսզի համոզվեք, որ k8s հավելվածը շատ հասանելի է, երբ դուք կլաստեր եք նախագծում, դուք պետք է հետևեք որոշակի օրինաչափությունների: Դրանց թվում է Առողջության ստուգման կաղապարը: Այն սահմանում է, թե ինչպես է հավելվածը հայտնում k8s-ին, որ այն առողջ է: Սա ոչ միայն տեղեկատվություն է այն մասին, թե արդյոք pod-ը աշխատում է, այլ նաև այն մասին, թե ինչպես է այն ընդունում և արձագանքում հարցումներին: Որքան շատ Kubernetes-ը իմանա պատի առողջության մասին, այնքան ավելի խելացի որոշումներ է կայացնում երթևեկության երթուղիների և բեռի հավասարակշռման վերաբերյալ: Այսպիսով, Բարձր դիտարկելիության սկզբունքը թույլ է տալիս հավելվածին ժամանակին պատասխանել հարցումներին:

Բարձր դիտարկելիության սկզբունք (HOP)

Բարձր դիտելիության սկզբունքը մեկն է կոնտեյներային հավելվածների նախագծման սկզբունքները. Միկրոծառայությունների ճարտարապետության մեջ ծառայություններին չեն հետաքրքրում, թե ինչպես է մշակվում իրենց հարցումը (և ճիշտ է այդպես), այլ կարևորն այն է, թե ինչպես են նրանք ստանում պատասխաններ ստացող ծառայություններից: Օրինակ՝ օգտատիրոջ իսկությունը հաստատելու համար մի բեռնարկղը HTTP հարցում է ուղարկում մյուսին՝ ակնկալելով պատասխան որոշակի ձևաչափով. այսքանը: PythonJS-ը կարող է նաև մշակել հարցումը, իսկ Python Flask-ը կարող է պատասխանել: Կոնտեյներները նման են սև արկղերի՝ միմյանց թաքնված պարունակությամբ: Այնուամենայնիվ, NOP սկզբունքը պահանջում է, որ յուրաքանչյուր ծառայություն ցուցադրի API-ի մի քանի վերջնակետեր, որոնք ցույց են տալիս, թե որքան առողջ է այն, ինչպես նաև դրա պատրաստակամությունը և սխալների հանդուրժողականության կարգավիճակը: Kubernetes-ը պահանջում է այս ցուցանիշները, որպեսզի մտածի երթուղավորման և բեռի հավասարակշռման հետագա քայլերի մասին:

Լավ մշակված ամպային հավելվածը գրանցում է իր հիմնական իրադարձությունները՝ օգտագործելով ստանդարտ I/O հոսքերի STDERR և STDOUT: Հաջորդը գալիս է օժանդակ ծառայությունը, օրինակ՝ filebeat-ը, logstash-ը կամ fluentd-ը, տեղեկամատյանները տրամադրելով կենտրոնացված մոնիտորինգի համակարգին (օրինակ՝ Պրոմեթևս) և լոգերի հավաքման համակարգին (ELK ծրագրային փաթեթ): Ստորև բերված դիագրամը ցույց է տալիս, թե ինչպես է ամպային հավելվածն աշխատում՝ համաձայն Առողջության թեստի օրինակի և բարձր դիտելիության սկզբունքի:

Լավագույն պրակտիկա Kubernetes կոնտեյներների համար. առողջության ստուգումներ

Ինչպե՞ս կիրառել առողջության ստուգման օրինակը Kubernetes-ում:

Ներդիրից դուրս, k8s-ը վերահսկում է պատյանների կարգավիճակը՝ օգտագործելով կարգավորիչներից մեկը (Տեղակայումներ, ReplicaSets, DaemonSets, StatefulSets և այլն, և այլն): Բացահայտելով, որ պատիճը ինչ-ինչ պատճառներով ընկել է, վերահսկիչը փորձում է այն վերագործարկել կամ տեղափոխել այլ հանգույց: Այնուամենայնիվ, pod-ը կարող է հայտնել, որ այն աշխատում և աշխատում է, բայց ինքնին չի գործում: Եկեք օրինակ բերենք՝ ձեր հավելվածը օգտագործում է Apache-ն որպես վեբ սերվեր, դուք բաղադրիչը տեղադրել եք կլաստերի մի քանի փոդերի վրա։ Քանի որ գրադարանը սխալ է կազմաձևվել, հավելվածին ուղղված բոլոր հարցումները պատասխանում են 500 կոդով (ներքին սերվերի սխալ): Առաքումը ստուգելիս պատիճների կարգավիճակը ստուգելը հաջող արդյունք է տալիս, բայց հաճախորդներն այլ կերպ են մտածում: Այս անցանկալի իրավիճակը մենք նկարագրելու ենք հետևյալ կերպ.

Լավագույն պրակտիկա Kubernetes կոնտեյներների համար. առողջության ստուգումներ

Մեր օրինակում k8s-ն անում է ֆունկցիոնալության ստուգում. Այս տեսակի ստուգման ժամանակ kubelet-ը շարունակաբար ստուգում է կոնտեյներով գործընթացի վիճակը: Հենց նա հասկանա, որ գործընթացը կանգ է առել, կվերսկսի այն։ Եթե ​​սխալը կարող է լուծվել պարզապես հավելվածը վերագործարկելու միջոցով, և ծրագիրը նախատեսված է ցանկացած սխալի դեպքում անջատելու համար, ապա գործընթացի առողջության ստուգումն այն ամենն է, ինչ ձեզ հարկավոր է՝ հետևելու NOP-ին և առողջության թեստի օրինակին: Միակ ափսոսն այն է, որ ոչ բոլոր սխալներն են վերացվում վերագործարկման միջոցով: Այս դեպքում, k8s-ն առաջարկում է 2 ավելի խորը եղանակ՝ բացահայտելու պոդի հետ կապված խնդիրները. livenessProbe и պատրաստակամության զոնդ.

LivenessProbe

Ընթացքում livenessProbe kubelet-ը կատարում է 3 տեսակի ստուգումներ՝ ոչ միայն որոշում է, թե արդյոք pod-ը աշխատում է, այլ նաև՝ արդյոք այն պատրաստ է ընդունելու և համարժեք պատասխանելու հարցումներին.

  • Կարգավորեք HTTP հարցումը pod-ում: Պատասխանը պետք է պարունակի HTTP պատասխանի կոդը 200-ից մինչև 399 միջակայքում: Այսպիսով, 5xx և 4xx կոդերը ազդանշան են տալիս, որ pod-ը խնդիրներ ունի, չնայած որ գործընթացն աշխատում է:
  • Ոչ HTTP ծառայություններով (օրինակ՝ Postfix փոստի սերվեր) փորձարկելու համար անհրաժեշտ է TCP կապ հաստատել:
  • Կատարեք կամայական հրաման pod-ի համար (ներքին): Ստուգումը համարվում է հաջող, եթե հրամանի ավարտի կոդը 0 է:

Օրինակ, թե ինչպես է սա աշխատում: Հաջորդ pod սահմանումը պարունակում է NodeJS հավելված, որը 500 սխալ է նետում HTTP հարցումների վրա: Համոզվելու համար, որ կոնտեյները վերագործարկվում է նման սխալ ստանալու դեպքում, մենք օգտագործում ենք 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

Սա ոչնչով չի տարբերվում ցանկացած այլ pod սահմանումից, բայց մենք ավելացնում ենք օբյեկտ .spec.containers.livenessProbe. Պարամետր httpGet ընդունում է այն ուղին, որով ուղարկվում է HTTP GET հարցումը (մեր օրինակում սա է /, բայց մարտական ​​սցենարներում կարող է նման բան լինել /api/v1/status) Մեկ այլ livenessProbe-ն ընդունում է պարամետր initialDelaySeconds, որը ստուգման գործողությանը հանձնարարում է սպասել որոշակի քանակությամբ վայրկյան: Հետաձգումն անհրաժեշտ է, քանի որ բեռնարկղը գործարկելու համար ժամանակ է պահանջում, և երբ վերագործարկվի, այն որոշ ժամանակ անհասանելի կլինի:

Այս պարամետրը կլաստերի վրա կիրառելու համար օգտագործեք՝

kubectl apply -f pod.yaml

Մի քանի վայրկյան հետո կարող եք ստուգել պատի բովանդակությունը՝ օգտագործելով հետևյալ հրամանը.

kubectl describe pods node500

Ելքի վերջում գտեք ահա թե ինչ.

Ինչպես տեսնում եք, livenessProbe-ը նախաձեռնեց HTTP GET հարցում, կոնտեյները ստեղծեց 500 սխալ (ինչը ծրագրված էր անել), և kubelet-ը վերագործարկեց այն:

Եթե ​​ձեզ հետաքրքրում է, թե ինչպես է ծրագրավորվել NideJS հավելվածը, ահա app.js-ը և 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" ]

Կարևոր է նշել սա. livenessProbe-ը կվերագործարկի կոնտեյները միայն այն դեպքում, եթե այն ձախողվի: Եթե ​​վերագործարկումը չի ուղղում սխալը, որը խանգարում է բեռնարկղի գործարկմանը, kubelet-ը չի կարողանա գործողություններ ձեռնարկել խնդիրը շտկելու համար:

պատրաստակամության զոնդ

ReadinessProbe-ն աշխատում է այնպես, ինչպես livenessProbes-ը (GET հարցումներ, TCP հաղորդակցություններ և հրամանների կատարում), բացառությամբ անսարքությունների վերացման գործողությունների: Կոնտեյները, որում հայտնաբերվում է խափանումը, չի վերագործարկվում, այլ մեկուսացված է մուտքային տրաֆիկից: Պատկերացրեք, որ բեռնարկղերից մեկը շատ հաշվարկներ է կատարում կամ գտնվում է ծանր բեռի տակ, ինչը հանգեցնում է արձագանքման ժամանակի ավելացմանը: LivenessProbe-ի դեպքում գործարկվում է պատասխանի հասանելիության ստուգումը (timeoutSeconds ստուգման պարամետրի միջոցով), որից հետո kubelet-ը վերագործարկում է կոնտեյները: Երբ գործարկվում է, բեռնարկղը սկսում է կատարել ռեսուրսների ինտենսիվ առաջադրանքներ և նորից վերագործարկվում է: Սա կարող է չափազանց կարևոր լինել այն հավելվածների համար, որոնք արձագանքման արագության կարիք ունեն: Օրինակ, մեքենան, երբ ճանապարհին է, սպասում է սերվերի պատասխանին, պատասխանը հետաձգվում է, և մեքենան վթարի է ենթարկվում:

Եկեք գրենք redinessProbe-ի սահմանում, որը կսահմանի GET հարցման պատասխանի ժամանակը ոչ ավելի, քան երկու վայրկյան, իսկ հավելվածը կպատասխանի GET հարցմանը 5 վայրկյան հետո: pod.yaml ֆայլը պետք է այսպիսի տեսք ունենա.

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

Եկեք տեղադրենք pod kubectl-ով.

kubectl apply -f pod.yaml

Եկեք սպասենք մի քանի վայրկյան և հետո տեսնենք, թե ինչպես է աշխատել պատրաստականության հետաքննությունը.

kubectl describe pods nodedelayed

Արդյունքների վերջում դուք կարող եք տեսնել, որ որոշ իրադարձություններ նման են Այս մեկը.

Ինչպես տեսնում եք, kubectl-ը չի վերագործարկել pod-ը, երբ ստուգման ժամանակը գերազանցել է 2 վայրկյանը։ Փոխարենը նա չեղարկել է խնդրանքը։ Մուտքային հաղորդակցությունները վերահղվում են այլ, աշխատանքային պատյաններ:

Նկատի ունեցեք, որ այժմ, երբ pod-ը բեռնաթափված է, kubectl-ը կրկին հարցումներ է ուղարկում դեպի այն. GET հարցումների պատասխաններն այլևս չեն հետաձգվում:

Համեմատության համար ստորև ներկայացված է փոփոխված 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("Hellon");
   })
});

server.listen(3000, function() {
   console.log('Server is running at 3000')
})

TL. DR
Նախքան ամպային հավելվածների հայտնվելը, տեղեկամատյանները եղել են հավելվածների առողջությունը վերահսկելու և ստուգելու հիմնական միջոցը: Այնուամենայնիվ, որևէ ուղղիչ գործողություն ձեռնարկելու միջոցներ չկար։ Գրանցամատյանները դեռևս օգտակար են այսօր, դրանք պետք է հավաքվեն և ուղարկվեն մատյանների հավաքման համակարգ՝ արտակարգ իրավիճակները վերլուծելու և որոշումներ կայացնելու համար: [Այս ամենը կարելի էր անել առանց ամպային հավելվածների՝ օգտագործելով monit-ը, օրինակ, բայց k8-ով շատ ավելի հեշտ դարձավ :) – խմբագրի նշումը։ ]

Այսօր ուղղումները պետք է կատարվեն գրեթե իրական ժամանակում, ուստի դիմումներն այլևս չպետք է լինեն սև արկղեր: Ոչ, դրանք պետք է ցույց տան վերջնակետեր, որոնք թույլ են տալիս մոնիտորինգի համակարգերին հարցումներ կատարել և հավաքել արժեքավոր տվյալներ գործընթացների վիճակի մասին, որպեսզի անհրաժեշտության դեպքում նրանք կարողանան անմիջապես արձագանքել: Սա կոչվում է Performance Test Design Pattern, որը հետևում է Բարձր դիտարկելիության սկզբունքին (HOP):

Kubernetes-ը լռելյայն առաջարկում է 2 տեսակի առողջական ստուգումներ՝ readinessProbe և livenessProbe: Երկուսն էլ օգտագործում են նույն տեսակի ստուգումներ (HTTP GET հարցումներ, TCP հաղորդակցություններ և հրամանների կատարում): Նրանք տարբերվում են նրանով, թե ինչ որոշումներ են կայացնում՝ ի պատասխան պատիճների խնդիրների: livenessProbe-ը վերագործարկում է կոնտեյները՝ հուսալով, որ սխալն այլևս չի կրկնվի, և readinessProbe-ը մեկուսացնում է պատիճը մուտքային տրաֆիկից մինչև խնդրի պատճառը չլուծվի:

Հավելվածի պատշաճ ձևավորումը պետք է ներառի ստուգման երկու տեսակները և ապահովի, որ դրանք բավականաչափ տվյալներ են հավաքում, հատկապես, երբ բացառություն է արվում: Այն պետք է նաև ցույց տա անհրաժեշտ API-ի վերջնակետերը, որոնք ապահովում են մոնիտորինգի համակարգին (Պրոմեթևս) առողջության կարևոր ցուցանիշներով:

Source: www.habr.com

Добавить комментарий