Shënim. përkth.: Ky artikull është pjesë e materialeve të projektit të publikuara në domenin publik , 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ë О .
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:
apiVersion: apps/v1
kind: Deployment # <<<
metadata:
name: my-deployment
labels:
track: canary
spec:
selector:
matchLabels:
any-name: my-app
template:
metadata:
labels:
any-name: my-app
spec:
containers:
- name: cont1
image: learnk8s/app:1.0.0
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service # <<<
metadata:
name: my-service
spec:
ports:
- port: 80
targetPort: 8080
selector:
name: app
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress # <<<
metadata:
name: my-ingress
spec:
rules:
- http:
paths:
- backend:
serviceName: app
servicePort: 80
path: /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. -
targetPortduhet të përputhencontainerPortenë brenda Pod. -
portShë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:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
labels:
track: canary
spec:
selector:
matchLabels:
any-name: my-app
template:
metadata:
labels: # <<<
any-name: my-app # <<<
spec:
containers:
- name: cont1
image: learnk8s/app:1.0.0
ports:
- containerPort: 8080 # <<<
---
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
ports:
- port: 80
targetPort: 8080 # <<<
selector: # <<<
any-name: my-app # <<< 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-labelsOse, 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.
kubectl port-forward service/<service name> 3000:80këtu:
-
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ë
portshë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:
-
servicePortnë Ingress duhet të përputhet me parametrinportne sherbim; -
serviceNamenë Ingress duhet të përputhet me fushënnamene 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:
apiVersion: v1
kind: Service
metadata:
name: my-service # <<<
spec:
ports:
- port: 80 # <<<
targetPort: 8080
selector:
any-name: my-app
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- http:
paths:
- backend:
serviceName: my-service # <<<
servicePort: 80 # <<<
path: /Si të kontrolloni nëse Ingress po funksionon?
Ju mund të përdorni metodën me kubectl port-forward, por në vend të shërbimit duhet të lidheni me kontrolluesin Ingress.
Së pari ju duhet të zbuloni emrin e pod me kontrolluesin Ingress:
kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS
kube-system coredns-5644d7b6d9-jn7cq 1/1 Running
kube-system etcd-minikube 1/1 Running
kube-system kube-apiserver-minikube 1/1 Running
kube-system kube-controller-manager-minikube 1/1 Running
kube-system kube-proxy-zvf2h 1/1 Running
kube-system kube-scheduler-minikube 1/1 Running
kube-system nginx-ingress-controller-6fc5bcc 1/1 Running Gjeni podin e hyrjes (mund tĂ« jetĂ« nĂ« njĂ« hapĂ«sirĂ« ââtjetĂ«r emri) dhe ekzekutoni komandĂ«n describepĂ«r tĂ« gjetur numrat e portit:
kubectl describe pod nginx-ingress-controller-6fc5bcc
--namespace kube-system
| grep Ports
Ports: 80/TCP, 443/TCP, 18080/TCPSĂ« fundi, lidheni me podin:
kubectl port-forward nginx-ingress-controller-6fc5bcc 3000:80 --namespace kube-systemTani 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ë , 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;
-
targetPortnë përkufizim Shërbimi duhet të përputhetcontainerPortenë brenda një bishti; -
portnë 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; -
servicePortHyrja duhet të përputhetportnë përkufizimin e Shërbimit; - Emri i shërbimit duhet të përputhet me fushën
serviceNamenë 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'а> bashju 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 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;
- Enë ;
- Testi i Liveness ka dështuar shumë herë.
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> --previousAi 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
ResourceQuotadhe 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.creationTimestampPods 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ë:
kubectl port-forward service/<service-name> 3000:80këtu:
-
<service-name>- emri i shërbimit; - 3000 është porta që hapni në kompjuter;
- 80 - porta në anën e shërbimit.
3. Diagnostifikimi i hyrjes
Nëse keni lexuar deri këtu, atëherë:
- bishtajat renditen si
RunningОReady; - shërbimi shpërndan me sukses trafikun midis pods.
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):
kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS
kube-system coredns-5644d7b6d9-jn7cq 1/1 Running
kube-system etcd-minikube 1/1 Running
kube-system kube-apiserver-minikube 1/1 Running
kube-system kube-controller-manager-minikube 1/1 Running
kube-system kube-proxy-zvf2h 1/1 Running
kube-system kube-scheduler-minikube 1/1 Running
kube-system nginx-ingress-controller-6fc5bcc 1/1 Running Përdorni komandën describepër të vendosur portin:
kubectl describe pod nginx-ingress-controller-6fc5bcc
--namespace kube-system
| grep PortsSĂ« fundi, lidheni me podin:
kubectl port-forward nginx-ingress-controller-6fc5bcc 3000:80 --namespace kube-systemTani 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 - 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 ë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 . 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- çeqenginx.conf; -
kubectl ingress-nginx backendâ eksploron prapavijĂ«n (e ngjashme mekubectl describe ingress <ingress-name>); -
kubectl ingress-nginx logsâ kontrollon regjistrat.
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.
- Jobs boshe dhe CronJobs;
- StatefulSets dhe DaemonSets.
Unë shpreh mirënjohjen time , О për komente dhe shtesa të vlefshme.
PS nga përkthyesi
Lexoni edhe në blogun tonë:
- «"?
- «"?
- «"?
- «'.
Burimi: www.habr.com
