Bem. overs.: Denne artikel er en del af de offentligt tilgĂŠngelige materialer fra projektet , der trĂŠner brugen af Kubernetes for virksomheder og individuelle administratorer. I denne vejledning deler Daniele Polencic, projektleder, en visuel instruktionsguide om de skridt, der skal tages ved generelle problemer med applikationer, der kĂžrer i K8s-klyngen.

TL;DR: her er et diagram, der kan hjĂŠlpe dig med at debugge deployment i Kubernetes:
Flowchart til at finde og lÞse fejl i klyngen. Den originale (pÄ engelsk) kan findes i og .
Ved deployment af en applikation i Kubernetes er det normalt nĂždvendigt at definere tre komponenter:
- Deployment â en opskrift pĂ„ at oprette kopier af applikationen, kaldet pods;
- Service â en intern load balancer, der fordeler trafik til pods;
- Ingress â en beskrivelse af, hvordan trafikken vil nĂ„ fra den eksterne verden til Service.
Her er et kort grafisk resumé:
1) I Kubernetes fÄr applikationer trafik fra den eksterne verden gennem to lag af load balancere: intern og ekstern.

2) Den interne load balancer kaldes Service, den eksterne â Ingress.

3) Deployment opretter pods og overvÄger dem (de oprettes ikke manuelt).

Lad os antage, at du Þnsker at deployere en simpel applikation, som f.eks. Hello World. YAML-konfigurationen for den vil se sÄledes ud:
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: /Definitionen er ret lang, og det er let at blive forvirret over, hvordan komponenterne hĂŠnger sammen.
For eksempel:
- HvornÄr skal man bruge port 80, og hvornÄr skal man bruge 8080?
- Skal der oprettes en ny port for hver service for at undgÄ konflikter?
- Har navnet pÄ labels nogen betydning? Skal de vÊre ens overalt?
FÞr vi fokuserer pÄ debugging, lad os huske pÄ, hvordan de tre komponenter hÊnger sammen. Lad os starte med Deployment og Service.
Forholdet mellem Deployment og Service
Du vil blive overrasket, men Deployments og Services er ikke direkte forbundet. I stedet angiver Service direkte til Pods uden om Deployment.
SÄledes er vi interesserede i, hvordan Pods og Services er relateret til hinanden. Husk tre ting:
- VĂŠlger (
selector) for Service skal svare til mindst én label fra Pod. -
targetPortskal svare tilcontainerPorti containere inden for Pod. -
portPorten for Service kan vĂŠre hvilken som helst. Forskellige services kan bruge den samme port, da de har forskellige IP-adresser.
NÊste skema prÊsenterer alt det ovenstÄende i grafisk form:
1) Antag, at servicen dirigerer trafik til en pod:

2) NÄr du opretter en pod, skal du angive containerPort for hver container i pods:

3) NÄr du opretter en service, skal du angive port og targetPort. Men gennem hvilken gÄr forbindelsen til containeren?

4) Gennem targetPort. Det skal svare til containerPort.

5) Antag, at port 3000 er Äben i containeren. SÄ skal vÊrdien targetPort vÊre den samme.

I YAML-filen skal labels og ports / targetPort svare til:
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 # <<< Hvad med label track: canary i toppen af Deployment-sektionen? Skal den svare til?
Denne label tilhĂžrer deploymenten, og den bruges ikke af servicen til at dirigere trafik. Med andre ord kan den slettes eller tildeles en anden vĂŠrdi.
Hvad med vĂŠlgeren matchLabels?
Den skal altid svare til labels fra Pod,, da den bruges af Deployment til at spore pods.
Antag, at du har foretaget de korrekte ĂŠndringer. Hvordan tjekker du dem?
Du kan kontrollere labels for pods med fĂžlgende kommando:
kubectl get pods --show-labelsEller, hvis pods tilhĂžrer flere applikationer:
kubectl get pods --selector any-name=my-app --show-labels Where any-name=my-app â dette er label any-name: my-app.
Har du stadig problemer?
Du kan tilslutte til pod! For dette skal du bruge kommandoen port-forward i kubectl. Den giver mulighed for at oprette forbindelse til servicen og kontrollere forbindelsen.
kubectl port-forward service/<service name> 3000:80Her:
-
service/<service name>â navnet pĂ„ servicen; i vores tilfĂŠlde er detmy-service; - 3000 â den port, der skal Ă„bnes pĂ„ computeren;
- 80 â den port, der er angivet i feltet
portfor servicen.
Hvis forbindelsen kunne etableres, sÄ er indstillingerne korrekte.
Hvis forbindelsen ikke kunne oprettes, er der et problem med etiketterne, eller portene stemmer ikke overens.
Forbindelsen mellem Service og Ingress
Det nÊste skridt for at sikre adgang til applikationen involverer opsÊtning af Ingress. Ingress skal vide, hvordan man finder servicen, derefter finde pods og dirigere trafik til dem. Ingress finder den nÞdvendige service ud fra navn og Äben port.
I beskrivelsen af Ingress og Service skal to parametre vĂŠre ens:
-
servicePorti Ingress skal svare til parameterenporti Service; -
serviceNamei Ingress skal svare til feltetnamei Service.
FĂžlgende skema opsummerer tilslutningen af porte:
1) Som du allerede ved, lytter Service til en given port:

2) Ingress har en parameter, der kaldes servicePort:

3) Denne parameter (servicePort) skal altid svare til port i definitionen af Service:

4) Hvis porten i Service er sat til 80, skal servicePort ogsÄ vÊre lig med 80:

I praksis er det vigtigt at vÊre opmÊrksom pÄ fÞlgende linjer:
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: /Hvordan kan man kontrollere, om Ingress fungerer?
Man kan bruge metoden med kubectl port-forward, men i stedet for at forbinde til servicen skal man forbinde til Ingress-controlleren.
FÞrst skal du finde navnet pÄ pod'en med Ingress-controlleren:
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 Find Ingress-pod'en (den kan tilhĂžre et andet navnerum) og udfĂžr kommandoen describe, for at finde portnumrene:
kubectl describe pod nginx-ingress-controller-6fc5bcc
--namespace kube-system
| grep Ports
Ports: 80/TCP, 443/TCP, 18080/TCPEndelig skal du forbinde til pod'en:
kubectl port-forward nginx-ingress-controller-6fc5bcc 3000:80 --namespace kube-systemNu, hver gang du sender en forespÞrgsel til port 3000 pÄ din computer, vil den blive videresendt til port 80 pÄ pod'en med Ingress-controlleren. Ved at gÄ til , skal du kunne se siden oprettet af applikationen.
Resume om porte
Lad os endnu en gang huske, hvilke porte og etiketter der skal stemme overens:
- VÊlgeren i definitionen af Service skal svare til etiketten pÄ pod'en;
-
targetPorti definitionen af Service skal svare tilcontainerPortcontaineren inde i pod'en; -
portI definitionen af Service kan vĂŠre hvilken som helst. Forskellige tjenester kan bruge den samme port, da de har forskellige IP-adresser; -
servicePortIngress'ens skal matcheporti definitionen af Service; - Navnet pÄ tjenesten skal matche feltet
serviceNamei Ingress.
DesvĂŠrre er det ikke nok at vide, hvordan man korrekt strukturerer YAML-konfigurationen.
Hvad sker der, nÄr noget gÄr galt?
MÄske starter pod'en ikke, eller den falder.
3 trin til fejlfinding af applikationer i Kubernetes
FÞr du begynder at debugge deployment'en, er det nÞdvendigt at have en god forstÄelse af, hvordan Kubernetes fungerer.
Da hver K8s-applikation har tre komponenter, skal du debugge dem i en bestemt rĂŠkkefĂžlge, startende fra bunden.
- FĂžrst skal du sikre dig, at pod'erne fungerer, og derefter âŠ
- Kontrollerer, om tjenesten leverer trafik til pod'erne, og derefter âŠ
- Kontrollerer, om Ingress er korrekt konfigureret.
Visualisering:
1) Begynd at lede efter problemer fra bunden. FĂžrst skal du kontrollere, at pod'erne har status Klar og KĂžrende:

2) Hvis pod'erne er klar (Klar), skal du finde ud af, om tjenesten distribuerer trafik mellem pod'erne:

3) Endelig skal du analysere forbindelsen mellem tjenesten og Ingress:

1. Fejlfinding af pod'er
I de fleste tilfĂŠlde er problemet relateret til pod'en. SĂžrg for, at pod'erne er angivet som Klar og KĂžrende. Dette kan kontrolleres med kommandoen:
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 I outputtet fra ovenstÄende kommando er den sidste pod angivet som KÞrende og Klar, men for de to andre er det ikke tilfÊldet.
Hvordan forstÄr man, hvad der gik galt?
Der er fire nyttige kommandoer til fejlfinding af pod'er:
-
kubectl logsgiver mulighed for at hente logfiler fra containere i pod'en; -
kubectl describe podgiver mulighed for at se en liste over begivenheder relateret til pod'en; -
kubectl get podgiver mulighed for at fÄ YAML-konfigurationen for pod'en gemt i Kubernetes; -
kubectl exec -ti bashgiver mulighed for at starte en interaktiv kommandolinje i en af containerne i pod'en
Hvilken skal man vĂŠlge?
Problemet er, at der ikke er en universel kommando. Du skal bruge en kombination af dem.
Typiske problemer med pod'er
Der er to hovedtyper af fejl i pod'er: opstartsfejl (startup) og runtime-fejl.
Opstartsfejl:
-
ImagePullBackoff -
ImageInspectError -
ErrImagePull -
ErrImageNeverPull -
RegistryUnavailable -
UgyldigBilledeNavn
Runtime-fejl:
-
CrashLoopBackOff -
KĂžrContainerFejl -
DrĂŠbContainerFejl -
BekrĂŠftIkkeRodBrugerFejl -
KĂžrInitContainerFejl -
OpretPodSandboxFejl -
KonfigPodSandboxFejl -
DrĂŠbPodSandboxFejl -
OpsĂŠtteNetvĂŠrkFejl -
NedbrydeNetvĂŠrkFejl
Nogle fejl forekommer oftere end andre. Her er nogle af de mest almindelige fejl og mÄder at lÞse dem pÄ.
ImagePullBackOff
Denne fejl opstĂ„r, nĂ„r Kubernetes ikke kan hente et billede til en af podâens containere. Her er tre af de mest almindelige Ă„rsager til dette:
- Billednavnet er forkert angivet â for eksempel har du lavet en fejl i det, eller billedet eksisterer ikke;
- En ikke-eksisterende tag er angivet for billedet;
- Billedet opbevares i et privat register, og Kubernetes har ikke de nÞdvendige tilladelser til at fÄ adgang til det.
De to fĂžrste Ă„rsager er lette at lĂžse â du skal blot rette billednavnet og taggen. I tilfĂŠlde af den sidste skal du indtaste legitimationsoplysninger til det private register i Secret og tilfĂžje referencer til det i podâerne. I Kubernetes-dokumentationen pĂ„, hvordan dette kan gĂžres.
CrashLoopBackOff
Kubernetes viser en fejl CrashLoopBackOff, hvis containeren ikke kan starte. Dette sker normalt, nÄr:
- Der er en fejl i applikationen, der forhindrer den i at starte;
- Container ;
- Liveness-testen er mislykket for mange gange.
Det er nÞdvendigt at forsÞge at fÄ fat i loggene fra containeren for at finde ud af Ärsagen til dens nedbrud. Hvis adgangen til loggene er svÊr, da containeren genstarter for hurtigt, kan fÞlgende kommando bruges:
kubectl logs --previousDen viser fejlmeddelelser fra den tidligere inkarnation af containeren.
KĂžrContainerFejl
Denne fejl opstÄr, nÄr containeren ikke er i stand til at starte. Den svarer til Þjeblikket fÞr applikationen starter. à rsagen til dette er normalt en forkert konfiguration, sÄsom:
- forsĂžger at montere et ikke-eksisterende volumen, som ConfigMap eller Secrets;
- forsĂžger at montere et read-only volumen som read-write.
Til analyse af sÄdanne fejl er kommandoen kubectl describe pod.
Podâene er i Pending-status
Efter oprettelsen forbliver podâen i status Pending.
Hvorfor sker dette?
Her er mulige Ärsager (jeg forudsÊtter, at planlÊggeren fungerer korrekt):
- Der er ikke nok ressourcer i klyngen, sĂ„som beregningskraft og hukommelse, til at starte podâen.
- I det relevante navnerum er der oprettet et objekt
ResourceQuotaOg oprettelsen af en pod vil fĂžre til, at navnerummet overskrider kvoten. - Pod er knyttet til Pending
PersistentVolumeClaim.
I dette tilfĂŠlde anbefales det at bruge kommandoen kubectl describe og tjekke sektionen Begivenheder:
kubectl describe pod I tilfĂŠlde af fejl relateret til ResourceQuotas, anbefales det at se gennem klyngens logs med kommandoen
kubectl get events --sort-by=.metadata.creationTimestampPods er ikke i Ready tilstand
Hvis pod'en er markeret som KĂžrende, men ikke er i tilstanden Klar, betyder det, at pod'ens beredskabsprĂžve (readiness probe) mislykkes.
NÄr dette sker, opretter pod'en ikke forbindelse til tjenesten, og trafikken faktisk tilgÄr den ikke. Fejlen i beredskabsprÞven skyldes problemer i applikationen. I sÄ fald skal sektionen Begivenheder i udgangen af kommandoen kubectl describe.
2. Diagnostik af tjenester
Hvis pods er markeret som KĂžrende og Klar, men der stadig ikke er noget svar fra applikationen, skal tjenesteindstillingerne kontrolleres.
Tjenester hÄndterer trafikdirigering til pods baseret pÄ deres labels. Derfor er det fÞrste, man skal gÞre, at tjekke, hvor mange pods der arbejder med tjenesten. Dette kan gÞres ved at kontrollere endpoints i tjenesten:
kubectl describe service | grep Endpoints Endpoint er et par vĂŠrdier af typen <IP-аЎŃĐ”Ń:ĐżĐŸŃŃ>, og der skal vĂŠre mindst et sĂ„dant par i udgangen (det vil sige, at mindst Ă©n pod arbejder med tjenesten).
Hvis sektionen Endpoints er tom, er der to mulige scenarier:
- der er ingen pod's med den rigtige label (tip: tjek om navnerummet er korrekt valgt);
- der er en fejl i tjenestens labels i vĂŠlgeren.
Hvis du ser en liste over endpoints, men stadig ikke kan fÄ adgang til applikationen, er den sandsynlige skyldner en fejl i targetPort den beskrivelse af tjenesten.
Hvordan tjekker man, om tjenesten fungerer?
Uanset hvilken type tjeneste kan man bruge kommandoen kubectl port-forward til at oprette forbindelse til den:
kubectl port-forward service/ 3000:80Her:
-
<service-name>â navn pĂ„ tjenesten; - 3000 â porten, som du Ă„bner pĂ„ computeren;
- 80 â porten pĂ„ servicesiden.
3. Diagnostik af Ingress
Hvis du er nÄet hertil, sÄ:
- pods er markeret som
KĂžrendeogKlar; - tjenesten distribuerer trafik til pods med succes.
Men du kan stadig ikke "nÄ" applikationen.
Det betyder, at Ingress-controllernes opsĂŠtning sandsynligvis er forkert. Da Ingress-controlleren er en ekstern komponent i klyngen, er der forskellige fejlfindingsmetoder afhĂŠngigt af dens type.
Men fĂžr du bruger specielle vĂŠrktĂžjer til at konfigurere Ingress, kan du gĂžre noget ganske simpelt. Ingress bruger serviceName og servicePort til at oprette forbindelse til tjenesten. Det er nĂždvendigt at kontrollere, om de er korrekt konfigureret. Dette kan gĂžres med kommandoen:
kubectl describe ingress Hvis kolonnen Backend er tom, er der stor sandsynlighed for en fejl i konfigurationen. Hvis backend'en er pÄ plads, men du stadig ikke kan tilgÄ applikationen, kan problemet vÊre relateret til:
- indstillingerne for tilgĂŠngelighed af Ingress fra internettet;
- indstillingerne for tilgĂŠngelighed af klyngen fra internettet.
For at finde problemer med infrastrukturen kan du forbinde direkte til Ingress-pod'en. Find fĂžrst pod'en for Ingress-controlleren (den kan vĂŠre i et andet navnerum):
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 Brug kommandoen describe, for at sĂŠtte porten:
kubectl describe pod nginx-ingress-controller-6fc5bcc
--namespace kube-system
| grep PortsEndelig skal du forbinde til pod'en:
kubectl port-forward nginx-ingress-controller-6fc5bcc 3000:80 --namespace kube-systemNu vil alle forespÞrgsler til port 3000 pÄ computeren blive omdirigeret til port 80 af pod'en.
Fungerer det nu?
- Hvis ja, sÄ er der et problem med infrastrukturen. Det er nÞdvendigt at finde ud af, hvordan trafikken rutes til klyngen.
- Hvis nej, sÄ er problemet med Ingress-controlleren.
Hvis du ikke kan fÄ Ingress-controlleren til at fungere, skal den fejlfinding.
Der findes mange varianter af Ingress-controllere. De mest populĂŠre er Nginx, HAProxy, Traefik og andre. (mere om de eksisterende lĂžsninger, se â red. anm.) Det anbefales at fĂžlge fejlfindingguiden i dokumentationen for den relevante controller. Da er den mest populĂŠre Ingress-controller, har vi inkluderet nogle tips til lĂžsning af relaterede problemer i artiklen.
Fejlfinding af Ingress Nginx-controlleren
Projektet Ingress-nginx har en officiel . Kommandoen kubectl ingress-nginx kan bruges til:
- analyse af logs, backends, certifikater osv.;
- tilslutning til Ingress;
- undersĂžgelse af den aktuelle konfiguration.
De fĂžlgende tre kommandoer vil hjĂŠlpe dig med dette:
-
kubectl ingress-nginx lintâ tjekkernginx.conf; -
kubectl ingress-nginx backendâ undersĂžger backend (pĂ„ samme mĂ„de somkubectl describe ingress); -
kubectl ingress-nginx logsâ tjekker logs.
BemĂŠrk: i nogle tilfĂŠlde kan det vĂŠre nĂždvendigt at angive det korrekte navnerum for Ingress-controlleren med flaget --namespace.
CV
Fejlfinding i Kubernetes kan vĂŠre en udfordring, hvis man ikke ved, hvor man skal starte. Problemet bĂžr altid angrebet fra bunden opad: begynd med podâene, og gĂ„ derefter videre til tjenesten og Ingress. De debugmetoder, der beskrives i artiklen, kan ogsĂ„ anvendes pĂ„ andre objekter sĂ„som:
- fejlende Jobâere og CronJobâere;
- StatefulSetâere og DaemonSetâere.
Jeg vil gerne takke , og for vĂŠrdifulde bemĂŠrkninger og tilfĂžjelser.
P.S. fra oversĂŠtteren
LÊs ogsÄ pÄ vores blog:
- «»;
- «»;
- «»;
- «».
Kilde: habr.com
