'n Visuele gids vir die oplos van Kubernetes

Let wel. vertaal.: Hierdie artikel is deel van die vrylik beskikbare projekmateriaal leer 8swat maatskappye en individuele administrateurs leer hoe om met Kubernetes te werk. Daarin deel Daniele Polencic, projekleier, 'n visuele gids oor watter stappe om te neem as daar algemene probleme is met toepassings wat op 'n K8s-kluster loop.

'n Visuele gids vir die oplos van Kubernetes

TL;DR: Hier is 'n diagram om jou te help om jou Kubernetes-ontplooiing te ontfout:

'n Visuele gids vir die oplos van Kubernetes

Vloeidiagram om foute in 'n groepie te vind en reg te stel. Die oorspronklike (in Engels) is beskikbaar in PDF и as prentjie.

Wanneer 'n toepassing na Kubernetes ontplooi word, is daar gewoonlik drie komponente wat gedefinieer moet word:

  • Ontplooiing - dit is 'n resep vir die skep van kopieë van die toepassing, genoem peule;
  • Diens - 'n interne lasbalanseerder wat verkeer oor peule versprei;
  • Ingang - 'n beskrywing van hoe verkeer van die buitewêreld na die Diens sal kom.

Hier is 'n kort grafiese opsomming:

1) In Kubernetes ontvang toepassings verkeer van die buitewêreld deur twee lae lasbalanseerders: intern en ekstern.

'n Visuele gids vir die oplos van Kubernetes

2) Die interne balanseerder word Diens genoem, die eksterne is Ingress.

'n Visuele gids vir die oplos van Kubernetes

3) Ontplooiing skep peule en monitor hulle (hulle word nie met die hand geskep nie).

'n Visuele gids vir die oplos van Kubernetes

Gestel jy wil 'n eenvoudige toepassing a la ontplooi Hello Wêreld. Die YAML-konfigurasie daarvoor sal soos volg lyk:

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: /

Die definisie is redelik lank en dit is maklik om deurmekaar te raak oor hoe die komponente met mekaar verband hou.

Byvoorbeeld:

  • Wanneer moet ek poort 80 gebruik en wanneer moet ek 8080 gebruik?
  • Moet 'n nuwe poort vir elke diens geskep word sodat hulle nie bots nie?
  • Maak etiketname saak? Moet hulle oral dieselfde wees?

Voordat ons op ontfouting fokus, kom ons vertel hoe die drie komponente met mekaar verband hou. Kom ons begin met Ontplooiing en Diens.

Verwantskap tussen ontplooiing en diens

Jy sal verbaas wees, maar ontplooiings en dienste is op geen manier verbind nie. In plaas daarvan wys die diens direk na die peule en omseil die ontplooiing.

Ons stel dus belang in hoe peule en dienste met mekaar verband hou. Drie dinge om te onthou:

  1. Kieser (selector) vir 'n Diens moet by ten minste een Pod-etiket pas.
  2. targetPort moet ooreenstem met containerPort houer in die Pod.
  3. port Service'a kan enigiets wees. Verskillende dienste kan dieselfde poort gebruik omdat hulle verskillende IP-adresse het.

Die volgende diagram stel al die bogenoemde in grafiese vorm voor:

1) Stel jou voor dat die diens verkeer na 'n sekere peul stuur:

'n Visuele gids vir die oplos van Kubernetes

2) Wanneer jy 'n peul skep, moet jy stel containerPort vir elke houer in peule:

'n Visuele gids vir die oplos van Kubernetes

3) Wanneer u 'n diens skep, moet u spesifiseer port и targetPort. Maar deur watter van hulle gaan die verbinding met die houer?

'n Visuele gids vir die oplos van Kubernetes

4) Deur targetPort. Dit moet ooreenstem met containerPort.

'n Visuele gids vir die oplos van Kubernetes

5) Gestel poort 3000 is oop in die houer, dan is die waarde targetPort moet dieselfde wees.

'n Visuele gids vir die oplos van Kubernetes

In die YAML-lêer, die etikette en ports / targetPort moet ooreenstem:

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  # <<<

Wat van die etiket track: canary aan die bokant van die Ontplooiing-afdeling? Moet dit ooreenstem?

Hierdie etiket is ontplooiingspesifiek en word nie deur die diens gebruik om verkeer te stuur nie. Met ander woorde, dit kan verwyder word of 'n ander waarde toegeken word.

Wat van die keurder matchLabels?

Dit moet altyd by die Pod se etikette pas, aangesien dit deur Ontplooiing gebruik word om tred te hou met peule.

Kom ons neem aan dat jy die korrekte wysigings gemaak het. Hoe om hulle na te gaan?

U kan die etiket van peule nagaan met die volgende opdrag:

kubectl get pods --show-labels

Of, as die peule deur verskeie toepassings besit word:

kubectl get pods --selector any-name=my-app --show-labels

waar any-name=my-app is 'n etiket any-name: my-app.

Is daar enige probleme oor?

Jy kan aan 'n peul koppel! Hiervoor moet jy die opdrag gebruik port-forward in kubectl. Dit laat jou toe om aan die diens te koppel en die verbinding na te gaan.

kubectl port-forward service/<service name> 3000:80

hier:

  • service/<service name> - diens naam; in ons geval is dit my-service;
  • 3000 is die poort wat jy op die rekenaar wil oopmaak;
  • 80 - poort gespesifiseer in die veld port diens.

As die verbinding suksesvol tot stand gebring is, dan is die instellings korrek.

As die verbinding nie bewerkstellig kon word nie, is daar 'n probleem met die etikette of die poorte stem nie ooreen nie.

Verwantskap tussen Diens en Ingress

Die volgende stap in die verskaffing van toegang tot die toepassing hou verband met die opstel van die Ingress. Ingress moet weet hoe om die diens te vind, dan die peule te vind en verkeer na hulle te stuur. Ingress vind die gewenste diens op naam en oop poort.

In die beskrywing van Ingress en Service moet twee parameters ooreenstem:

  1. servicePort in Ingress moet ooreenstem met die parameter port in diens;
  2. serviceName in Ingress moet ooreenstem met die veld name in diens.

Die volgende diagram som die poortverbindings op:

1) Soos jy reeds weet, Diens luister na sommige port:

'n Visuele gids vir die oplos van Kubernetes

2) Ingress het 'n parameter genoem servicePort:

'n Visuele gids vir die oplos van Kubernetes

3) Hierdie parameter (servicePort) moet altyd ooreenstem port in die diensdefinisie:

'n Visuele gids vir die oplos van Kubernetes

4) As poort 80 in Diens gespesifiseer word, dan is dit nodig dat servicePort was ook gelyk aan 80:

'n Visuele gids vir die oplos van Kubernetes

In die praktyk moet u aandag gee aan die volgende reëls:

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: /

Hoe om te kyk of Ingress werk?

Jy kan die metode gebruik met kubectl port-forward, maar in plaas van 'n diens, moet jy aan die Ingress-beheerder koppel.

Eerstens moet jy die naam van die peul met die Ingress-beheerder uitvind:

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

Soek die Ingress-pod (dit kan in 'n ander naamruimte wees) en voer die opdrag uit describeom die poortnommers uit te vind:

kubectl describe pod nginx-ingress-controller-6fc5bcc 
--namespace kube-system 
 | grep Ports
Ports:         80/TCP, 443/TCP, 18080/TCP

Laastens, koppel aan die peul:

kubectl port-forward nginx-ingress-controller-6fc5bcc 3000:80 --namespace kube-system

Nou elke keer as jy 'n versoek na poort 3000 op die masjien stuur, sal dit na poort 80 van die Ingress-pod herlei word. Gaan na http://localhost:3000, moet jy die bladsy sien wat deur die toepassing gegenereer word.

Opsomming deur hawens

Kom ons onthou weer watter poorte en etikette moet ooreenstem:

  1. Die keurder in die Diensdefinisie moet ooreenstem met die peul se etiket;
  2. targetPort in die Diensdefinisie moet ooreenstem containerPort 'n houer in 'n peul;
  3. port in die diensdefinisie kan enigiets wees. Verskillende dienste kan dieselfde poort gebruik omdat hulle verskillende IP-adresse het;
  4. servicePort Ingang moet ooreenstem port in die Diensdefinisie;
  5. Die diensnaam moet ooreenstem met die veld serviceName in Ingress.

Helaas, dit is nie genoeg om te weet hoe om 'n YAML-konfigurasie behoorlik te struktureer nie.

Wat gebeur as iets verkeerd loop?

Die peul begin dalk nie of dit kan val.

3 stappe om toepassings in Kubernetes op te los

Voordat jy begin om jou ontplooiing te ontfout, moet jy 'n goeie begrip hê van hoe Kubernetes werk.

Aangesien daar drie komponente is in elke afgelaaide toepassing in K8's, ontfout hulle in 'n sekere volgorde, begin van onder.

  1. Eerstens moet jy seker maak dat die peule werk, dan ...
  2. Kyk of die diens verkeer na die peule lewer, en dan ...
  3. Kyk of Ingress korrek opgestel is.

Visuele voorstelling:

1) Begin soek na probleme van onder af. Kontroleer eers dat die peule statusse het Ready и Running:

'n Visuele gids vir die oplos van Kubernetes

2) As die peule gereed is (Ready), moet jy uitvind of die diens verkeer tussen peule versprei:

'n Visuele gids vir die oplos van Kubernetes

3) Ten slotte moet u die verband tussen die diens en Ingress ontleed:

'n Visuele gids vir die oplos van Kubernetes

1. Peuldiagnostiek

In die meeste gevalle hou die probleem verband met die peul. Maak seker die peule is gelys as Ready и Running. U kan dit kontroleer met die opdrag:

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

In die opdraguitvoer hierbo word die laaste peul gelys as Running и Ready, maar dit is nie die geval vir die ander twee nie.

Hoe om te verstaan ​​wat verkeerd geloop het?

Daar is vier nuttige opdragte om peule te diagnoseer:

  1. kubectl logs <имя pod'а> laat jou toe om stompe uit houers in 'n peul te onttrek;
  2. kubectl describe pod <имя pod'а> laat jou toe om die lys van gebeure wat met die peul geassosieer word te sien;
  3. kubectl get pod <имя pod'а> laat jou toe om die YAML-konfigurasie te kry van 'n peul wat in Kubernetes gestoor is;
  4. kubectl exec -ti <имя pod'а> bash laat jou toe om 'n interaktiewe opdragdop in een van die peul se houers uit te voer

Watter een om te kies?

Die feit is dat daar geen universele opdrag is nie. 'n Kombinasie daarvan moet gebruik word.

Algemene peulprobleme

Daar is twee hooftipes peulfoute: opstartfoute en looptydfoute.

Beginfoute:

  • ImagePullBackoff
  • ImageInspectError
  • ErrImagePull
  • ErrImageNeverPull
  • RegistryUnavailable
  • InvalidImageName

Runtime foute:

  • CrashLoopBackOff
  • RunContainerError
  • KillContainerError
  • VerifyNonRootError
  • RunInitContainerError
  • CreatePodSandboxError
  • ConfigPodSandboxError
  • KillPodSandboxError
  • SetupNetworkError
  • TeardownNetworkError

Sommige foute is meer algemeen as ander. Hier is 'n paar van die mees algemene foute en hoe om dit reg te stel.

ImagePullBackOff

Hierdie fout kom voor wanneer Kubernetes nie 'n prent vir een van die peul se houers kan kry nie. Hier is die drie mees algemene redes hiervoor:

  1. Die naam van die prent is verkeerd - jy het byvoorbeeld 'n fout daarin gemaak, of die prent bestaan ​​nie;
  2. 'n Ongeldige merker is vir die prent gespesifiseer;
  3. Die prent word in 'n private register gestoor en Kubernetes het nie toestemming om toegang daartoe te verkry nie.

Die eerste twee redes is maklik om reg te stel - maak net die prentnaam en merker reg. In die geval van laasgenoemde is dit nodig om geloofsbriewe vir die private register in Geheim in te voer en skakels daarby in peule by te voeg. In die Kubernetes-dokumentasie daar is 'n voorbeeld hoe dit gedoen kan word.

Crash Loop Terug Af

Kubenetes gooi 'n fout CrashLoopBackOffas die houer nie kan begin nie. Dit gebeur gewoonlik wanneer:

  1. Die toepassing het 'n fout wat verhoed dat dit loop;
  2. Houer verkeerd gekonfigureer;
  3. Die Liveness-toets het te veel keer gedruip.

Dit is nodig om te probeer om by die stompe uit die houer te kom om die rede vir die mislukking daarvan uit te vind. As toegang tot die logboeke moeilik is omdat die houer te vinnig herbegin, kan jy die volgende opdrag gebruik:

kubectl logs <pod-name> --previous

Dit druk foutboodskappe van die houer se vorige reïnkarnasie.

RunContainerError

Hierdie fout kom voor wanneer die houer nie kan begin nie. Dit stem ooreen met die oomblik voordat die toepassing begin. Dit word gewoonlik veroorsaak deur 'n wankonfigurasie, soos:

  • probeer om 'n nie-bestaande volume soos ConfigMap of Secrets te monteer;
  • probeer om 'n leesalleen-volume as lees-skryf te monteer.

Die opdrag is goed geskik vir die ontleding van sulke foute. kubectl describe pod <pod-name>.

Peule in die hangende toestand

Na die skepping bly die peul in die staat Pending.

Hoekom gebeur dit?

Hier is die moontlike oorsake (ek neem aan die skeduleerder werk goed):

  1. Die groep het nie genoeg hulpbronne, soos verwerkingskrag en geheue, om die peul te laat loop nie.
  2. 'n Voorwerp word in die toepaslike naamruimte gestel ResourceQuota en die skep van 'n pod sal veroorsaak dat die naamruimte buite kwota gaan.
  3. Peul vasgemaak aan Hangende PersistentVolumeClaim.

In hierdie geval word dit aanbeveel om die opdrag te gebruik kubectl describe en kontroleer afdeling Events:

kubectl describe pod <pod name>

In die geval van foute wat verband hou met ResourceQuotas, word dit aanbeveel om die cluster logs te sien deur die opdrag te gebruik

kubectl get events --sort-by=.metadata.creationTimestamp

Peule nie gereed nie

As peul gelys word as Running, maar is nie in die staat nie Ready, beteken om sy gereedheid na te gaan (gereedheidsondersoek) misluk.

Wanneer dit gebeur, koppel die pod nie aan die diens nie en geen verkeer word daarna gestuur nie. Die mislukking van die gereedheidstoets word veroorsaak deur probleme in die toepassing. In hierdie geval, om die fout te vind, moet jy die afdeling ontleed Events in opdraguitvoer kubectl describe.

2. Diensdiagnostiek

As peule gelys word as Running и Ready, maar daar is steeds geen reaksie van die toepassing nie, moet u die diensinstellings nagaan.

Dienste is besig om verkeer na peule te stuur, afhangende van hul etikette. Daarom is die eerste ding om te doen om te kyk hoeveel peule met die diens werk. Om dit te doen, kan u die eindpunte in die diens nagaan:

kubectl describe service <service-name> | grep Endpoints

Eindpunt is 'n paar waardes van die vorm <IP-адрес:порт>, en ten minste een so 'n paar moet teenwoordig wees in die uitvoer (dit wil sê, ten minste een peul werk met die diens).

Indien afdeling Endpoins leeg, daar is twee opsies:

  1. daar is geen peule met die korrekte etiket nie (wenk: kyk of die naamspasie korrek is);
  2. daar is 'n fout in die diensetikette in die kieser.

As jy 'n lys eindpunte sien, maar steeds nie toegang tot die toepassing kry nie, is die waarskynlike skuldige 'n fout in targetPort in die diensbeskrywing.

Hoe om te kyk of die diens werk?

Ongeag die tipe diens, jy kan die opdrag gebruik kubectl port-forward om daaraan te koppel:

kubectl port-forward service/<service-name> 3000:80

hier:

  • <service-name> — diens naam;
  • 3000 is die poort wat jy op die rekenaar oopmaak;
  • 80 - hawe aan die dienskant.

3. Intredediagnostiek

As jy tot hier gelees het, dan:

  • peule word gelys as Running и Ready;
  • die diens versprei verkeer suksesvol onder peule.

Jy kan egter steeds nie "deurkom" na die toepassing nie.

Dit beteken dat die Ingress-beheerder heel waarskynlik verkeerd gekonfigureer is. Aangesien die Ingress-beheerder 'n derdeparty-komponent in die groepering is, is daar verskillende ontfoutingsmetodes afhangende van die tipe.

Maar voordat u gebruik maak van spesiale gereedskap om Ingress'a op te stel, kan u iets baie eenvoudig doen. Ingress gebruike serviceName и servicePort om aan die diens te koppel. Jy moet kyk of hulle korrek opgestel is. Jy kan dit doen met die opdrag:

kubectl describe ingress <ingress-name>

As kolom Backend leeg is, is daar 'n hoë waarskynlikheid van 'n konfigurasiefout. As die backends in plek is, maar die toepassing is steeds nie toeganklik nie, kan die probleem verband hou met:

  • Toeganklikheidsinstellings vanaf die publieke internet binnekom;
  • groepering toeganklikheid instellings vanaf die publieke internet.

U kan probleme met die infrastruktuur identifiseer deur direk aan die Ingress-pod te koppel. Om dit te doen, vind eers die pod van die Ingress-beheerder (dit kan in 'n ander naamruimte wees):

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

Gebruik die span describeom die poort te stel:

kubectl describe pod nginx-ingress-controller-6fc5bcc
--namespace kube-system 
 | grep Ports

Laastens, koppel aan die peul:

kubectl port-forward nginx-ingress-controller-6fc5bcc 3000:80 --namespace kube-system

Nou sal alle versoeke op poort 3000 op die rekenaar herlei word na poort 80 van die pod.

Werk dit nou?

  • Indien wel, dan is die probleem by die infrastruktuur. Dit is nodig om uit te vind presies hoe verkeer na die groep gelei word.
  • Indien nie, dan is die probleem by die Ingress-beheerder.

As jy nie die Ingress-beheerder kan laat werk nie, sal jy dit moet ontfout.

Daar is baie variëteite van Ingress-beheerders. Die gewildste is Nginx, HAProxy, Traefik, ens. (vir meer inligting oor bestaande oplossings, sien ons resensie - ongeveer. vertaal.) Verwys na die probleemoplossingsgids in die dokumentasie vir die toepaslike beheerder. Omdat die Ingress Nginx is die gewildste Ingress-beheerder, het ons 'n paar wenke ingesluit oor hoe om dit te hanteer in hierdie artikel.

Ontfouting van 'n Nginx Ingress Controller

Die Ingress-nginx-projek het 'n amptenaar inprop vir kubectl. span kubectl ingress-nginx kan gebruik word vir:

  • ontleding van logs, backends, sertifikate, ens.;
  • verbinding met Ingress'u;
  • die huidige opset ondersoek.

Die volgende drie opdragte sal jou hiermee help:

  • kubectl ingress-nginx lint - tjeks nginx.conf;
  • kubectl ingress-nginx backend - verken die agterkant (soortgelyk aan kubectl describe ingress <ingress-name>);
  • kubectl ingress-nginx logs - kontroleer die logs.

Neem asseblief kennis dat dit in sommige gevalle nodig mag wees om die korrekte naamspasie vir die Ingress-beheerder met behulp van die vlag te spesifiseer --namespace <name>.

Opsomming

Die oplos van Kubernetes kan moeilik wees as jy nie weet waar om te begin nie. Die probleem moet altyd van onder na bo benader word: begin met peule, en gaan dan aan na die diens en Ingress. Die ontfoutingsmetodes wat in die artikel beskryf word, kan op ander voorwerpe toegepas word, soos:

  • ledige Jobs en CronJobs;
  • StatefulSets en DaemonSets.

Ek spreek my dankbaarheid uit Gergely Risko, Daniel Weibel и Charles Christyraj vir waardevolle kommentaar en byvoegings.

PS van vertaler

Lees ook op ons blog:

Bron: will.com

Voeg 'n opmerking