Shën. përk.: Kyçongu është pjesë e materialeve të publikuara falas të projektit , i cili trajnon përdoruesit e Kubernetes dhe administratorët individualë. Në të, Daniele Polencic, menaxher i projektit, ndan një udhëzues vizual mbi hapat që duhet të ndikuti në rast se ndodhin probleme të zakonshme me aplikacionet e vendosura në klusterin K8s.

TL;DR: ja skema që do t'ju ndihmojë të depuroshni deployment-in në Kubernetes:
Diagram për gjetjen dhe rregullimin e gabimeve në kluster. Në origjinal (në anglisht) është e disponueshme në dhe .
Kur vendosni një aplikacion në Kubernetes zakonisht duhet të përcaktoni tre komponentë:
- Deployment â njĂ« lloj recete pĂ«r krijimin e kopjeve tĂ« aplikacionit, tĂ« quajtura pod-e;
- ShĂ«rbimi â njĂ« balancues ngarkese tĂ« brendshĂ«m qĂ« shpĂ«rndan trafikun nĂ« pod-e;
- Ingress â njĂ« pĂ«rshkrim se si trafiku do tĂ« arrijĂ« nga bota e jashtme te ShĂ«rbimi.
Ja një përmbledhje grafike e shkurtër:
1) Në Kubernetes, aplikacionet marrin trafik nga bota e jashtme përmes dy niveleve të balancuesve të ngarkesës: të brendshëm dhe të jashtëm.

2) Balancuesi i brendshĂ«m quhet ShĂ«rbim, i jashtmi â Ingress.

3) Deployment-i krijon pod-e dhe i monitoron ato (ato nuk krijohen manualisht).

Supozoni se dëshironi të vendosni një aplikacion të thjeshtë të ngjashëm me Hello World.Konfigurimi YAML për të do të dukej si më poshtë:
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: /Kjo përkufizim është mjaft i gjatë, dhe është e lehtë të humbasësh në lidhjen midis komponentëve.
Për shembull:
- Kur duhet të përdoret porta 80 dhe kur 8080?
- A duhet të krijoni një port të ri për çdo shërbim, që të mos kenë konflikte?
- Kanë rëndësi emrat e etiketave? A duhet të jenë të njëjta kudo?
Para se të përqendrohemi në depurim, le të kujtojmë se si janë të lidhur tre komponentët. Le të fillojmë me Deployment dhe Shërbimin.
Lidhja midis Deployment-it dhe Shërbimit
Do të habiteni, por Deployment-et dhe Shërbimet nuk janë të lidhura. Në vend të kësaj, Shërbimi tregon drejtpërdrejt për pod-et përmes Deployment-it.
Prandaj, ne jemi të interesuar për mënyrën se si lidhen pod-et dhe Shërbimet. Duhet të mbani mend tri gjëra:
- Selekori (
selector) i Shërbimit duhet të përputhet me të paktën një etiketë të pod-it. -
targetPortduhet të përputhet mecontainerPorte kontejnerit brenda pod-it. -
portPorti i Shërbimit mund të jetë çfarëdo. Shërbime të ndryshme mund të përdorin të njëjtin port, sepse kanë adresa IP të ndryshme.
Diagrami në vijim paraqet të gjitha të mësipërmet në formë grafike:
1) Le të imagjinojmë se shërbimi drejton trafikun në një pod:

2) Kur krijoni pod-in duhet të caktoni containerPort për çdo kontejner në pod-e:

3) Kur krijoni një shërbim, duhet të specificoni port dhe targetPort. Por përmes cilit po bëhet lidhja me kontejnerin?

4) Përmes targetPort. Ai duhet të përputhet me containerPort.

5) Supozoni se në kontejnerin është hapur porta 3000. Atëherë vlera targetPort duhet të jetë e njëjtë.

Në skedarin YAML, etiketat dhe portet / 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 # <<<< Por çfarë bëhet fjalë për etiketën track: canary në pjesën e sipërme të seksionit Deployment? A duhet të përputhet?
Kjo etiketĂ« i referohet deployment-it, dhe nuk pĂ«rdoret nga shĂ«rbimi pĂ«r rrufti trafikun. Me fjalĂ« tĂ« tjera, mund ta hiqni atĂ« ose tâi japĂ« njĂ« vlerĂ« tjetĂ«r.
Dhe çfarë për selektorin matchLabels?
matchLabelsAi gjithmonë duhet të përputhet me etiketat e pod-it
, sepse përdoret nga Deployment-i për të ndjekur pod-et.
Supozoni se keni bërë korrigjimet e duhura. Si mund t'i kontrolloni ato?
Kontrolloni etiketat e pod-eve me komandën e mëposhtme:kubectl get pods --show-labels
Ose, nĂ«se pod-et i pĂ«rkasin disa aplikacioneve: Ku kubectl get pods --selector any-name=my-app --show-labels any-name=my-app â kjo Ă«shtĂ« njĂ« etiketĂ«.
any-name: my-app
Akoma keni probleme? port-forward Mund të lidheni me pod-in! Për këtë duhet të përdorni komandën
në kubectl. Kjo lejon lidhjen me shërbimin dhe kontrollimin e lidhjes.Këtu:
-
kubectl port-forward service/ 3000:80service/â emri i shĂ«rbimit; nĂ« rastin tonĂ« Ă«shtĂ«; - my-service
- 3000 â porta qĂ« duhet tĂ« hapet nĂ« kompjuter;
port80 â porta qĂ« Ă«shtĂ« caktuar nĂ« fushĂ«n
e shërbimit.
Nëse arritët të bëni lidhjen, atëherë konfigurimi është i saktë.
Nëse lidhja nuk mund të krijohet, atëherë problemi është me etiketat ose portat nuk përputhen.
Hapi tjetër për të siguruar aksesin në aplikacion lidhet me konfigurimin e Ingress-it. Ingress duhet të dijë se si të gjejë shërbimin, pastaj të gjejë pod-at dhe të drejtojë trafik aty. Ingress e gjen shërbimin e kërkuar sipas emrit dhe portit të hapur.
Në përshkrimin e Ingress-it dhe Shërbimit duhet të përputhen dy parametra:
-
servicePortnë Ingress duhet të përputhet me parametrinportnë Shërbim; -
serviceNamenë Ingress duhet të përputhet me fushënemrinë Shërbim.
Skema e mëposhtme përmbledh lidhjen e porteve:
1) Siç e dini, Shërbimi dëgjon një port të caktuar port:

2) Ingress ka një parametr të quajtur servicePort:

3) Ky parametr (servicePort) gjithmonë duhet të përputhet me port në përkufizimin e Shërbimit:

4) Nëse porti në Shërbim është 80, atëherë duhet që servicePort të jetë gjithashtu 80:

Në praktikë, duhet të keni parasysh rreshtat e mëposhtëm:
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 funksionon?
Mund të përdorni metodën me kubectl port-forward, por në vend të shërbimit duhet të lidheni me kontrolluesin e Ingress-it.
Së pari, duhet të dini emrin e pod-it me kontrolluesin e Ingress-it:
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 pod-in e Ingress-it (ndoshta i takon një hapësire tjetër emri) dhe kryeni komandën describe, për të mësuar numrat e porteve:
kubectl describe pod nginx-ingress-controller-6fc5bcc
--namespace kube-system
| grep Ports
Ports: 80/TCP, 443/TCP, 18080/TCPNĂ« fund, lidheni me pod-in:
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ë redirektohet në portin 80 të pod-it me kontrolluesin e Ingress-it. Duke shkuar në , duhet të shihni faqen e krijuar nga aplikacioni.
Përmbledhje për portet
Le të kujtojmë përsëri se cilat porte dhe etiketa duhet të përputhen:
- Seletori në përkufizimin e Shërbimit duhet të përputhet me etiketën e pod-it;
-
targetPortnë përkufizimin e Shërbimit duhet të përputhet mecontainerPortkonfigurimin brenda pod-it; -
portnë përkufizimin e Shërbimit mund të jetë ndonjë. Shërbime të ndryshme mund të përdorin të njëjtin port, pasi kanë adresa IP të ndryshme; -
servicePortIngress-it duhet të përputhet meportnë përkufizimin e Shërbimit; - Emri i shërbimit duhet të përputhet me fushën
serviceNamenë Ingress.
Fatkeqësisht, nuk është e mjaftueshme të dini se si të strukurosh siç duhet konfigurimin YAML.
ĂfarĂ« ndodh kur diçka shkon keq?
Ndoshta pod-i nuk është duke u nisur apo po dështon.
3 hapa për diagnostikimin e problemeve në aplikacionet në Kubernetes
Para se të filloni të depuroni deployment-in, është e nevojshme të keni një përkuptim të mirë se si funksionon Kubernetes.
Duke qenë se në çdo aplikacion të depozituar në K8s ka tre komponente, depurimi i tyre duhet të bëhet në një rend të caktuar, duke filluar nga më poshtë.
- Së pari, duhet të siguroheni që pod-at janë në funksionim, pastaj...
- Kontrolloni nëse shërbimi po dërgon trafik te pod-at, dhe më pas...
- Kontrolloni nëse Ingress është konfiguruar siç duhet.
Prezantimi vizual:
1) Duhet të filloni kërkimin e problemeve nga më poshtë. Së pari kontrolloni që pod-at të kenë statuset Gati dhe Running:

2) Nëse pod-at janë të gatshëm (Gati), duhet të zbulohet nëse shërbimi po dërgon trafik midis pod-ave:

3) Në fund, duhet të analizoni lidhjen e shërbimit dhe Ingress-it:

1. Diagnostika e pod-ave
Në shumicën e rasteve, problemi është i lidhur me pod-in. Sigurohuni që pod-at të jenë të regjistruar si Gati dhe Running. Këtë mund ta kontrolloni me 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, pod-i i fundit është i regjistruar si Running dhe Gati, megjithatë për dy të tjerët nuk është kështu.
Si mund ta kuptoni se çfarë ka shkuar keq?
Ka katër komanda të dobishme për diagnostikimin e pod-ave:
-
kubectl logs <emri i pod'it>lejon të nxjerrësh log-ët nga kontenierët në pod; -
kubectl describe pod <emri i pod'it>lejon të shikosh listën e ngjarjeve që lidhen me pod-in; -
kubectl get pod <emri i pod'it>lejon të marrësh konfigurimin YAML të pod-it, i cili ruhet në Kubernetes; -
kubectl exec -ti <emri i pod'it> bashlejon të fillosh një ndërfaqe të komandës interaktive në një nga kontenierët e pod-it.
Cilën të zgjedhim?
E vërteta është se nuk ka një komandë universale. Duhet të përdoren në kombinim.
Problemet tipike të pod-ave
Ka dy lloje të zakonshme gabimesh në pod: gabime gjatë lançimit (startup) dhe gabime gjatë funksionimit (runtime).
Gabimet e lançimit:
-
ImagePullBackoff -
ImageInspectError -
ErrImagePull -
ErrImageNeverPull -
RegistryUnavailable -
InvalidImageName
Gabimet në rrjedhë:
-
CrashLoopBackOff -
RunContainerError -
KillContainerError -
VerifyNonRootError -
RunInitContainerError -
CreatePodSandboxError -
ConfigPodSandboxError -
KillPodSandboxError -
SetupNetworkError -
TeardownNetworkError
Disa disa, disa disa takime me shpeshtosi: Disa gabime ndodhin më shpesh se të tjerat. Këtu janë disa nga gabimet më të zakonshme dhe mënyrat për t'i ndrequr ato.
ImagePullBackOff
Ky gabim shfaqet kur Kubernetes nuk mund të marrë imazhin për një nga konteinerët e pod-it. Këtu janë tri arsyet më të zakonshme për këtë:
- Emri i imazhit është i pasaktë - për shembull, keni bërë një gabim në të ose imazhi nuk ekziston;
- ĂshtĂ« vendosur njĂ« etikĂ«t e pamjaftueshme pĂ«r imazhin;
- Imazhi ruhet në një regjistër privat dhe Kubernetes nuk ka autorizim për të hyrë në të.
Dy arsyet e para janë të lehta për t'u ndrequr - mjafton të rregulloni emrin e imazhit dhe etikën. Në rastin e fundit, duhet të futni kredencialet për regjistrin privat në Secret dhe të shtoni lidhjet në pod-et. Në dokumentacionin e Kubernetes se si mund ta bëni këtë.
CrashLoopBackOff
Kubernetes shfaq një gabim CrashLoopBackOff, nëse kontejneri nuk mund të nisë. Kjo ndodh zakonisht kur:
- Ka një gabim në aplikacion që nuk e lejon atë të nisë;
- Kontejner ;
- Testi i Liveness ka dështuar shumë shpesh.
Duhet të përpiqeni të arrini në regjistrat nga kontejneri për të zbuluar arsyen e dështimit të tij. Nëse është e vështirë të qaseni në regjistrat për shkak se kontejneri rilansohet shumë shpejt, mund të përdorni komandën e mëposhtme:
kubectl logs --previousAjo shfaq mesazhet e gabimeve nga rinovimi i mëparshëm i kontejnerit.
RunContainerError
Ky gabim shfaqet kur kontejneri nuk është në gjendje të nisë. Ai korrespondon me momentin para nisjes së aplikacionit. Zakonisht shkaku i saj është një konfigurim i gabuar, për shembull:
- përpjekja për të montuar një volum që nuk ekziston, siç është ConfigMap ose Secrets;
- përpjekja për të montuar një volum të tipit read-only si read-write.
Për analizimin e këtyre gabimeve, komanda e përshtatshme është kubectl describe pod.
Pod-et në gjendje Pending
Pas krijimit, pod-i mbetet në gjendje Pending.
Pse ndodh kjo?
Ja disa arsye të mundshme (po supozoj se planifikuesi po funksionon normalisht):
- Në klaster ka mungesë burimesh, si kapacitet kompjuterik dhe memorie, për të nisur pod-in.
- Në hapësirën përkatëse të emrave është vendosur një objekt
ResourceQuotadhe krijimi i pod-it do të çojë në kalimin e kufijve të kuotës në hapësirën përkatëse. - Pod është i ngjitur me Pending
PersistentVolumeClaim.
Në këtë rast, rekomandohet të përdorni komandën kubectl describe dhe kontrolloni seksionin Ngjarjet:
kubectl describe pod Në rast gabimesh të lidhura me ResourceQuotas, rekomandohet të shqyrtoni regjistrat e klasterit duke përdorur komandën
kubectl get events --sort-by=.metadata.creationTimestampPod-et nuk janë në gjendje të Gatshme
Nëse pod-i shënohet si Running, por nuk ndodhet në gjendje Gati, atëherë kontrolli i gatshmërisë së tij (readiness probe) dështoi.
Kur ndodh kjo, pod-i nuk lidhet me shërbimin, dhe trafiku nuk i shkon atij. Dështimi i testit të gatshmërisë shkaktohet nga probleme në aplikacion. Në këtë rast, për të gjetur gabimin, duhet të analizoni seksionin Ngjarjet në rezultatin e komandës kubectl describe.
2. Diagnostika e shërbimeve
Nëse pod-et shënohen si Running dhe Gati, por nuk ka ende përgjigje nga aplikacioni, duhet të kontrolloni konfigurimin e shërbimit.
Shërbimet merret me rrugëzimin e trafikut drejt pod-eve në varësi të etiketeve të tyre. Prandaj, gjëja e parë që duhet të bësh - kontrollo se sa pod-e janë duke punuar me shërbimin. Për këtë, mund të kontrolloni endpoint-et në shërbim:
kubectl describe service | grep Endpoints Endpoint Ă«shtĂ« njĂ« çift vlerash tĂ« tipit <IP-аЎŃĐ”Ń:ĐżĐŸŃŃ>, dhe nĂ« rezultatin duhet tĂ« ketĂ« tĂ« paktĂ«n njĂ« çift tĂ« tillĂ« (pra, me shĂ«rbimin punon tĂ« paktĂ«n njĂ« pod).
Nëse seksioni Endpoints është bosh, ka dy mundësi:
- nuk ka asnjë pod me etiketë të saktë (këshillë: kontrolloni nëse është zgjedhur saktë hapësira e emrave);
- ka një gabim në etiketat e shërbimit në selektor.
Nëse shihni një listë endpoint-esh, por ende nuk mund të aksesoni aplikacionin, atëherë një fajtor i mundshëm është gabimi në targetPort përshkrimin e shërbimit.
Si të kontrolloni funksionimin 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/ 3000:80Këtu:
-
<service-name>â emri i shĂ«rbimit; - 3000 â porti qĂ« po e hapni nĂ« kompjuterin tuaj;
- 80 â porta nga ana e shĂ«rbimit.
3. Diagnostika e Ingress
Nëse ke lexuar deri në këtë pikë, atëherë:
- pod-et shënohen si
RunningdheGati; - shërbimi shpërndan me sukses trafik drejt pod-eve.
Megjithatë, ende nuk mund të "arrini" në aplikacion.
Kjo do të thotë se, me shumë gjasa, kontrolluesi i Ingress është konfiguruar në mënyrë të gabuar. Duke qenë se kontrolluesi i Ingress është një komponent i jashtëm në klaster, ekzistojnë metoda të ndryshme për debug në varësi të llojit të tij.
Por përpara se të shfrytëzoni ndihmën e mjeteve të veçanta për konfiguruar Ingress, mund të bëni diçka mjaft të thjeshtë. Ingress përdor serviceName dhe servicePort për t'u lidhur me shërbimin. është e nevojshme të kontrolloni nëse ato janë konfiguruar siç duhet. Këtë mund ta bëni me komandën:
kubectl describe ingress Nëse kolona Backend është bosh, ka një probabilitet të lartë për një gabim në konfigurim. Nëse backend-et janë në vend, por ende nuk ka qasje në aplikacion, atëherë problemi mund të lidhet me:
- konfigurat e aksesit të Ingress nga interneti publik;
- konfigurat e aksesit të klasës nga interneti publik.
Mund të identifikoni problemet me infrastrukturën duke u lidhur drejtpërdrejt me pod-in e Ingress-it. Për këtë, fillimisht gjeni pod-in e kontrolluesit të Ingress (ai mund të gjendet 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 describe, për të vendosur portin:
kubectl describe pod nginx-ingress-controller-6fc5bcc
--namespace kube-system
| grep PortsNĂ« fund, lidheni me pod-in:
kubectl port-forward nginx-ingress-controller-6fc5bcc 3000:80 --namespace kube-systemTani të gjitha kërkesat në portin 3000 në kompjuterin tuaj do të ridrejtohen në portin 80 të pod-it.
A funksionon tani?
- NĂ«se po, atĂ«herĂ« problemi Ă«shtĂ« me infrastrukturĂ«n. ĂshtĂ« e nevojshme tĂ« zbulohet se si po realizohet rrugĂ«zimi i trafikut nĂ« klasĂ«.
- Nëse jo, atëherë problemi është me kontrolluesin e Ingress.
Nëse nuk arrini ta bëni të funksionojë kontrolluesin e Ingress, do të duhet ta debug-oni atë.
Ka shumĂ« lloje kontrolluesish tĂ« Ingress. MĂ« tĂ« njohurit janĂ« Nginx, HAProxy, Traefik dhe tĂ« tjerĂ«. (pĂ«r mĂ« shumĂ« rreth zgjidhjeve ekzistuese, shihni nĂ« â shĂ«nim i pĂ«rkthyesit.) Duhet tĂ« pĂ«rdorni udhĂ«zuesin pĂ«r zgjidhjen e problemeve nĂ« dokumentacionin e kontrolluesit pĂ«rkatĂ«s. Duke qenĂ« se Ă«shtĂ« kontrolluesi mĂ« i njohur i Ingress, ne pĂ«rfshimĂ« disa kĂ«shilla pĂ«r zgjidhjen e problemeve me tĂ« nĂ« artikull.
Debugging i kontrolluesit Ingress Nginx
Projekti Ingress-nginx ka një . Komandën kubectl ingress-nginx mund ta përdorni për:
- analizimin e logeve, backend-eve, certifikateve, etj.;
- të lidheni me Ingress-in;
- të studioni konfigurimin aktual.
Do t'ju ndihmojnë këto tri komanda:
-
kubectl ingress-nginx lintâ kontrollonnginx.conf; -
kubectl ingress-nginx backendâ shqyrton backend-in (siç Ă«shtĂ«kubectl describe ingress); -
kubectl ingress-nginx logsâ kontrollon loget.
Kujdes: në disa raste, mund të jetë e nevojshme të përcaktoni hapësirën e duhur të emrit për kontrolluesin e Ingress duke përdorur flamurin --namespace.
Curriculum Vitae
Diagnoza në Kubernetes mund të jetë një detyrë e vështirë nëse nuk e dini nga të filloni. Problemi gjithmonë duhet të qaset sipas parimit 'nga poshtë-lart': filloni nga pod-t, dhe pastaj kaloni te shërbimi dhe Ingress-i. Metodat e debugging që janë përshkruar në artikull mund të aplikohen gjithashtu në objekte të tjera, si:
- Job-et dhe CronJob-et që nuk funksionojnë;
- StatefulSet-et dhe DaemonSet-et.
Faleminderit , dhe për vërejtjet dhe sugjerimet e vlefshme.
P.S. nga përkthyesi
Lexoni gjithashtu në blogun tonë:
- «»;
- «»;
- «»;
- «».
Burimi: habr.com
