Një udhëzues vizual për zgjidhjen e problemeve të Kubernetes
Shënim. përkth.: Ky artikull është pjesë e materialeve të projektit të publikuara në domenin publik Learnk8s, trajnimin e kompanive dhe administratorëve individualë për të punuar me Kubernetes. Në të, Daniele Polencic, menaxher i projektit, ndan udhëzime vizuale se çfarë hapash duhet të ndërmerren në rast të problemeve të përgjithshme me aplikacionet që funksionojnë në grupin K8s.
TL;DR: këtu është një diagram që do t'ju ndihmojë të korrigjoni vendosjen në Kubernetes:
Tabela e rrjedhës për gjetjen dhe rregullimin e gabimeve në një grup. Origjinali (në anglisht) gjendet në PDF и si foto.
Kur vendosni një aplikacion në Kubernetes, zakonisht ekzistojnë tre komponentë që duhet të përcaktoni:
shpërndarje - kjo është një lloj recete për krijimin e kopjeve të aplikacionit, të quajtur pods;
Shërbime — balancues i brendshëm i ngarkesës që shpërndan trafikun midis podseve;
Hyrje — një përshkrim se si trafiku do të kalojë nga bota e jashtme te Shërbimi.
Këtu është një përmbledhje e shpejtë grafike:
1) Në Kubernetes, aplikacionet marrin trafik nga bota e jashtme përmes dy shtresave të balancuesve të ngarkesës: të brendshme dhe të jashtme.
2) Balancuesi i brendshëm quhet Service, ai i jashtëm quhet Ingress.
3) Deployment krijon pods dhe i monitoron ato (ato nuk krijohen manualisht).
Le të themi se dëshironi të vendosni një aplikacion të thjeshtë a la Përshëndetje Botë. Konfigurimi YAML për të do të duket si ky:
Përkufizimi është mjaft i gjatë dhe është e lehtë të ngatërrohesh për mënyrën se si komponentët lidhen me njëri-tjetrin.
Për shembull:
Kur duhet të përdorni portin 80 dhe kur duhet të përdorni 8080?
A duhet të krijoj një port të ri për çdo shërbim në mënyrë që të mos bien ndesh?
A kanë rëndësi emrat e etiketave? A duhet të jenë të njëjta kudo?
Përpara se të fokusohemi në korrigjimin e gabimeve, le të kujtojmë se si lidhen të tre komponentët me njëri-tjetrin. Le të fillojmë me vendosjen dhe shërbimin.
Marrëdhënia ndërmjet vendosjes dhe shërbimit
Do të habiteni, por vendosja dhe shërbimi nuk kanë asnjë lidhje. Në vend të kësaj, Shërbimi tregon drejtpërdrejt te Pods, duke anashkaluar vendosjen.
Kështu, ne jemi të interesuar se si Pods dhe Shërbimet janë të lidhura me njëra-tjetrën. Tre gjëra për të mbajtur mend:
Përzgjedhësi (selector) për Shërbimin duhet të përputhet me të paktën një etiketë Pod.
targetPort duhet të përputhen containerPort enë brenda Pod.
port Shërbimi mund të jetë çdo gjë. Shërbime të ndryshme mund të përdorin të njëjtin port sepse kanë adresa IP të ndryshme.
Diagrami i mëposhtëm paraqet të gjitha sa më sipër në formë grafike:
1) Imagjinoni që shërbimi drejton trafikun në një pod të caktuar:
2) Kur krijoni një pod, duhet të specifikoni containerPort për çdo enë në bishtaja:
3) Kur krijoni një shërbim, duhet të specifikoni port и targetPort. Por cili përdoret për t'u lidhur me kontejnerin?
4) Nëpërmjet targetPort. Duhet të përputhet containerPort.
5) Le të themi se porti 3000 është i hapur në kontejner. Pastaj vlera targetPort duhet të jetë e njëjtë.
Në skedarin YAML, etiketat dhe ports / targetPort duhet të përputhen:
Po etiketa track: canary në krye të seksionit të vendosjes? A duhet të përputhet?
Kjo etiketë është specifike për vendosjen dhe nuk përdoret nga shërbimi për të drejtuar trafikun. Me fjalë të tjera, mund të hiqet ose t'i caktohet një vlerë tjetër.
Po përzgjedhësi matchLabels?
Duhet të përputhet gjithmonë me etiketat e Pod-it, pasi përdoret nga Deployment për të gjurmuar pods.
Le të supozojmë se keni bërë modifikimet e sakta. Si t'i kontrolloni ato?
Ju mund të kontrolloni etiketën e pod me komandën e mëposhtme:
kubectl get pods --show-labels
Ose, nëse pods i përkasin disa aplikacioneve:
kubectl get pods --selector any-name=my-app --show-labels
ku any-name=my-app është një etiketë any-name: my-app.
A ka mbetur ndonjë vështirësi?
Mund të lidheni me podin! Për ta bërë këtë ju duhet të përdorni komandën port-forward në kubectl. Kjo ju lejon të lidheni me shërbimin dhe të kontrolloni lidhjen.
service/<service name> - emri i shërbimit; në rastin tonë është my-service;
3000 është porti që duhet të hapet në kompjuter;
80 - porti i specifikuar në fushë port shërbimi
Nëse lidhja është krijuar, atëherë cilësimet janë të sakta.
Nëse lidhja dështon, ka një problem me etiketat ose portat nuk përputhen.
Marrëdhënia midis Shërbimit dhe Ingress
Hapi tjetër në sigurimin e aksesit në aplikacion përfshin konfigurimin e Ingress. Ingress duhet të dijë se si të gjejë një shërbim, më pas të gjejë pods dhe të drejtojë trafikun drejt tyre. Ingress gjen shërbimin e kërkuar me emër dhe port të hapur.
Në përshkrimin e hyrjes dhe shërbimit, dy parametra duhet të përputhen:
servicePort në Ingress duhet të përputhet me parametrin port ne sherbim;
serviceName në Ingress duhet të përputhet me fushën name ne sherbim.
Diagrami i mëposhtëm përmbledh lidhjet e portit:
1) Siç e dini tashmë, Shërbimi dëgjon një të caktuar port:
2) Ingress ka një parametër të quajtur servicePort:
3) Ky parametër (servicePort) duhet të përputhet gjithmonë port në përkufizimin e Shërbimit:
4) Nëse porta 80 është e specifikuar në Shërbimin, atëherë është e nevojshme që servicePort ishte gjithashtu e barabartë me 80:
Në praktikë, duhet t'i kushtoni vëmendje linjave të mëposhtme:
Tani sa herë që dërgoni një kërkesë në portin 3000 në kompjuterin tuaj, ajo do të përcillet në portin 80 të pod me kontrolluesin Ingress. Duke shkuar në http://localhost:3000, duhet të shihni faqen e krijuar nga aplikacioni.
Përmbledhje e porteve
Le të kujtojmë edhe një herë se cilat porte dhe etiketa duhet të përputhen:
Zgjedhësi në përkufizimin e Shërbimit duhet të përputhet me etiketën e pod;
targetPort në përkufizim Shërbimi duhet të përputhet containerPort enë brenda një bishti;
port në përkufizim Shërbimi mund të jetë çdo gjë. Shërbime të ndryshme mund të përdorin të njëjtin port sepse kanë adresa IP të ndryshme;
servicePort Hyrja duhet të përputhet port në përkufizimin e Shërbimit;
Emri i shërbimit duhet të përputhet me fushën serviceName në Ingress.
Fatkeqësisht, nuk mjafton të dish se si të strukturosh siç duhet një konfigurim YAML.
Çfarë ndodh kur gjërat shkojnë keq?
Mbushja mund të mos fillojë ose mund të rrëzohet.
3 hapa për të diagnostikuar problemet e aplikimit në Kubernetes
Përpara se të filloni të korrigjoni vendosjen tuaj, duhet të keni një kuptim të mirë se si funksionon Kubernetes.
Meqenëse çdo aplikacion i shkarkuar në K8 ka tre komponentë, ato duhet të korrigjohen në një mënyrë të caktuar, duke filluar nga fundi.
Fillimisht duhet të siguroheni që bishtajat po funksionojnë, më pas...
Kontrolloni nëse shërbimi furnizon trafikun në pods dhe më pas...
Kontrolloni nëse Ingress është konfiguruar saktë.
Përfaqësimi vizual:
1) Duhet të filloni të kërkoni problemet nga fundi. Së pari kontrolloni që podat të kenë statuse Ready и Running:
2) Nëse bishtajat janë gati (Ready), duhet të zbuloni nëse shërbimi shpërndan trafikun midis pods:
3) Së fundi, ju duhet të analizoni lidhjen midis shërbimit dhe hyrjes:
1. Diagnostifikimi i bishtajave
Në shumicën e rasteve problemi ka të bëjë me pod. Sigurohuni që bishtajat të jenë të listuara si Ready и Running. Ju mund ta kontrolloni këtë duke përdorur komandën:
kubectl get pods
NAME READY STATUS RESTARTS AGE
app1 0/1 ImagePullBackOff 0 47h
app2 0/1 Error 0 47h
app3-76f9fcd46b-xbv4k 1/1 Running 1 47h
Në daljen e komandës më sipër, podi i fundit renditet si Running и Ready, megjithatë, ky nuk është rasti për dy të tjerët.
Si të kuptoni se çfarë shkoi keq?
Ekzistojnë katër komanda të dobishme për diagnostikimin e pods:
kubectl logs <имя pod'а> ju lejon të nxirrni trungje nga kontejnerët në një pod;
kubectl describe pod <имя pod'а> ju lejon të shikoni një listë të ngjarjeve të lidhura me pod;
kubectl get pod <имя pod'а> ju lejon të merrni konfigurimin YAML të një pod të ruajtur në Kubernetes;
kubectl exec -ti <имя pod'а> bash ju lejon të lëshoni një guaskë komanduese ndërvepruese në një nga kontejnerët e pod
Cilin duhet të zgjidhni?
Fakti është se nuk ka asnjë komandë universale. Duhet të përdoret një kombinim i tyre.
Probleme tipike të pod
Ekzistojnë dy lloje kryesore të gabimeve të pod: gabimet e fillimit dhe gabimet në kohën e ekzekutimit.
Gabimet e nisjes:
ImagePullBackoff
ImageInspectError
ErrImagePull
ErrImageNeverPull
RegistryUnavailable
InvalidImageName
Gabimet e kohës së ekzekutimit:
CrashLoopBackOff
RunContainerError
KillContainerError
VerifyNonRootError
RunInitContainerError
CreatePodSandboxError
ConfigPodSandboxError
KillPodSandboxError
SetupNetworkError
TeardownNetworkError
Disa gabime janë më të zakonshme se të tjerët. Këtu janë disa nga gabimet më të zakonshme dhe si t'i rregulloni ato.
ImagePullBackOff
Ky gabim ndodh kur Kubernetes nuk është në gjendje të marrë një imazh për një nga kontejnerët e pod. Këtu janë tre arsyet më të zakonshme për këtë:
Emri i figurës është i pasaktë - për shembull, keni bërë një gabim në të, ose imazhi nuk ekziston;
Për imazhin u specifikua një etiketë joekzistente;
Imazhi ruhet në një regjistër privat dhe Kubernetes nuk ka leje për të hyrë në të.
Dy arsyet e para janë të lehta për t'u eliminuar - thjesht korrigjoni emrin dhe etiketën e figurës. Në rastin e kësaj të fundit, duhet të futni kredencialet për regjistrin e mbyllur në Secret dhe të shtoni lidhje me të në pods. Në dokumentacionin e Kubernetes ka një shembull si mund të bëhet kjo.
Crash Loop Back Off
Kubenetes hedh një gabim CrashLoopBackOff, nëse kontejneri nuk mund të fillojë. Kjo zakonisht ndodh kur:
Ekziston një gabim në aplikacion që e pengon atë të niset;
Duhet të përpiqeni të arrini në shkrimet nga kontejneri për të zbuluar arsyen e dështimit të tij. Nëse është e vështirë për të hyrë në regjistrat sepse kontejneri riniset shumë shpejt, mund të përdorni komandën e mëposhtme:
kubectl logs <pod-name> --previous
Ai shfaq mesazhe gabimi nga mishërimi i mëparshëm i kontejnerit.
RunContainerError
Ky gabim ndodh kur kontejneri nuk fillon të fillojë. Ai korrespondon me momentin përpara se të hapet aplikacioni. Zakonisht shkaktohet nga cilësimet e gabuara, për shembull:
përpjekje për të montuar një vëllim jo-ekzistent si ConfigMap ose Secrets;
një përpjekje për të montuar një vëllim vetëm për lexim si lexim-shkrim.
Ekipi është i përshtatshëm për të analizuar gabime të tilla kubectl describe pod <pod-name>.
Pods janë në gjendje në pritje
Pasi të krijohet, pod mbetet në gjendje Pending.
Pse po ndodh kjo?
Këtu janë arsyet e mundshme (po supozoj se planifikuesi po funksionon mirë):
Grupi nuk ka burime të mjaftueshme, si fuqia përpunuese dhe memorie, për të drejtuar podin.
Objekti është i instaluar në hapësirën e duhur të emrave ResourceQuota dhe krijimi i një pod do të bëjë që hapësira e emrave të shkojë përtej kuotës.
Pod është i lidhur në pritje PersistentVolumeClaim.
Në këtë rast, rekomandohet të përdorni komandën kubectl describe dhe kontrolloni seksionin Events:
kubectl describe pod <pod name>
Në rast të gabimeve që lidhen me ResourceQuotas, rekomandohet të shikoni regjistrat e grupimeve duke përdorur komandën
kubectl get events --sort-by=.metadata.creationTimestamp
Pods nuk janë gati
Nëse pod është renditur si Running, por nuk është në gjendje Ready, do të thotë të kontrollosh gatishmërinë e tij (sondë gatishmërie) dështon.
Kur kjo ndodh, pod nuk lidhet me shërbimin dhe asnjë trafik nuk rrjedh drejt tij. Dështimi i testit të gatishmërisë është shkaktuar nga problemet në aplikacion. Në këtë rast, për të gjetur gabimin, duhet të analizoni seksionin Events në daljen e komandës kubectl describe.
2. Diagnostifikimi i shërbimit
Nëse bishtajat renditen si Running и Ready, por ende nuk ka asnjë përgjigje nga aplikacioni, duhet të kontrolloni cilësimet e shërbimit.
Shërbimet janë përgjegjëse për drejtimin e trafikut në pods në varësi të etiketave të tyre. Prandaj, gjëja e parë që duhet të bëni është të kontrolloni se sa pods punojnë me shërbimin. Për ta bërë këtë, mund të kontrolloni pikat fundore në shërbim:
kubectl describe service <service-name> | grep Endpoints
Pika përfundimtare është një palë vlerash të formës <IP-адрес:порт>, dhe të paktën një çift i tillë duhet të jetë i pranishëm në dalje (d.m.th., të paktën një pod punon me shërbimin).
Nëse seksioni Endpoins bosh, dy opsione janë të mundshme:
nuk ka pods me etiketën e saktë (udhëzim: kontrolloni nëse hapësira e emrave është zgjedhur saktë);
Ka një gabim në etiketat e shërbimit në përzgjedhës.
Nëse shihni një listë të pikave fundore, por ende nuk mund të hyni në aplikacion, atëherë fajtori i mundshëm është një defekt targetPort në përshkrimin e shërbimit.
Si të kontrolloni funksionalitetin e shërbimit?
Pavarësisht nga lloji i shërbimit, mund të përdorni komandën kubectl port-forward për t'u lidhur me të:
Megjithatë, ju ende nuk mund ta arrini aplikacionin.
Kjo do të thotë që kontrolluesi Ingress ka shumë të ngjarë të mos jetë konfiguruar saktë. Meqenëse kontrolluesi Ingress është një komponent i palës së tretë në grup, ekzistojnë metoda të ndryshme korrigjimi në varësi të llojit të tij.
Por, përpara se të përdorni mjete speciale për të konfiguruar Ingress, mund të bëni diçka shumë të thjeshtë. Ingress përdor serviceName и servicePort për t'u lidhur me shërbimin. Ju duhet të kontrolloni nëse ato janë konfiguruar saktë. Ju mund ta bëni këtë duke përdorur komandën:
kubectl describe ingress <ingress-name>
Nëse kolona Backend bosh, ka një probabilitet të lartë për një gabim konfigurimi. Nëse backend-et janë në vend, por aplikacioni nuk është ende i aksesueshëm, atëherë problemi mund të lidhet me:
Cilësimet e hyrjes së aksesit nga interneti publik;
cilësimet e aksesueshmërisë së grupit nga interneti publik.
Ju mund të identifikoni problemet me infrastrukturën duke u lidhur drejtpërdrejt me podin e hyrjes. Për ta bërë këtë, së pari gjeni podin e Kontrolluesit të hyrjes (mund të jetë në një hapësirë tjetër emri):
Tani të gjitha kërkesat për portin 3000 në kompjuter do të ridrejtohen në portin 80 të pod.
A funksionon tani?
Nëse po, atëherë problemi është me infrastrukturën. Është e nevojshme të zbulohet saktësisht se si trafiku drejtohet në grup.
Nëse jo, atëherë problemi është me kontrolluesin Ingress.
Nëse nuk mund ta aktivizoni kontrolluesin Ingress, do t'ju duhet ta korrigjoni atë.
Ka shumë lloje të kontrollorëve Ingress. Më të njohurit janë Nginx, HAProxy, Traefik, etj. (për më shumë informacion rreth zgjidhjeve ekzistuese, shihni rishikimi ynë - përafërsisht. përkth.) Ju duhet t'i referoheni udhëzuesit për zgjidhjen e problemeve në dokumentacionin përkatës të kontrolluesit. Sepse Ingress Nginx është kontrolluesi më i njohur Ingress, ne kemi përfshirë disa këshilla në artikull për të zgjidhur problemet që lidhen me të.
Korrigjimi i kontrolluesit Ingress Nginx
Projekti Ingress-nginx ka një zyrtar plugin për kubectl. Ekipi kubectl ingress-nginx mund të përdoret për:
analiza e regjistrave, backend-eve, certifikatave, etj.;
lidhjet me Ingress;
duke studiuar konfigurimin aktual.
Tre komandat e mëposhtme do t'ju ndihmojnë me këtë:
kubectl ingress-nginx lint - çeqe nginx.conf;
kubectl ingress-nginx backend — eksploron prapavijën (e ngjashme me kubectl describe ingress <ingress-name>);
Vini re se në disa raste mund t'ju duhet të specifikoni hapësirën e saktë të emrave për kontrolluesin Ingress duke përdorur flamurin --namespace <name>.
Përmbledhje
Zgjidhja e problemeve të Kubernetes mund të jetë sfiduese nëse nuk dini nga të filloni. Gjithmonë duhet t'i qaseni problemit nga poshtë lart: filloni me pods dhe më pas kaloni te shërbimi dhe Ingress. Teknikat e korrigjimit të përshkruara në këtë artikull mund të aplikohen në objekte të tjera, si p.sh.