Sjónræn leiðarvísir um bilanaleit Kubernetes

Athugið. þýð.: Þessi grein er hluti af verkefnaefninu sem gefið er út á almenningi læra8s, þjálfun fyrirtækja og einstakra stjórnenda til að vinna með Kubernetes. Þar deilir Daniele Polencic, verkefnastjóri, sjónrænum leiðbeiningum um hvaða skref eigi að taka ef upp koma almenn vandamál með forrit sem keyra á K8s klasanum.

Sjónræn leiðarvísir um bilanaleit Kubernetes

TL;DR: hér er skýringarmynd sem mun hjálpa þér að kemba uppsetningu í Kubernetes:

Sjónræn leiðarvísir um bilanaleit Kubernetes

Flæðirit til að finna og laga villur í klasa. Frumritið (á ensku) er fáanlegt á PDF и sem mynd.

Þegar forrit er sett í Kubernetes eru venjulega þrír þættir sem þú þarft að skilgreina:

  • dreifing - þetta er eins konar uppskrift að því að búa til afrit af forriti, sem kallast belg;
  • þjónusta - innri álagsjafnari sem dreifir umferð á milli belg;
  • Innstreymi — lýsing á því hvernig umferð mun berast frá umheiminum til þjónustunnar.

Hér er fljótleg myndræn samantekt:

1) Í Kubernetes fá forrit umferð frá umheiminum í gegnum tvö lög af álagsjafnara: innri og ytri.

Sjónræn leiðarvísir um bilanaleit Kubernetes

2) Innri jafnvægisstillirinn heitir Þjónusta, sá ytri heitir Ingress.

Sjónræn leiðarvísir um bilanaleit Kubernetes

3) Dreifing býr til belg og fylgist með þeim (þeir eru ekki búnir til handvirkt).

Sjónræn leiðarvísir um bilanaleit Kubernetes

Segjum að þú viljir nota einfalt forrit a la Halló heimur. YAML stillingin fyrir það mun líta svona út:

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

Skilgreiningin er nokkuð löng og auðvelt er að ruglast á því hvernig íhlutirnir tengjast hver öðrum.

Til dæmis:

  • Hvenær ættir þú að nota port 80 og hvenær ættir þú að nota 8080?
  • Ætti ég að búa til nýja höfn fyrir hverja þjónustu svo þau stangist ekki á?
  • Skipta nöfn merkimiða máli? Eiga þeir að vera eins alls staðar?

Áður en við einbeitum okkur að villuleit, skulum við muna hvernig þættirnir þrír tengjast hver öðrum. Byrjum á dreifingu og þjónustu.

Tengsl milli dreifingar og þjónustu

Þú verður hissa, en dreifing og þjónusta eru ekki tengd á nokkurn hátt. Þess í stað bendir Þjónusta beint á Pods, framhjá dreifingu.

Þannig höfum við áhuga á því hvernig pods og þjónusta tengjast hvert öðru. Þrennt sem þarf að muna:

  1. Valmynd (selector) fyrir þjónustu verður að passa við að minnsta kosti eitt Pod merki.
  2. targetPort verður að passa containerPort ílát inni í Pod.
  3. port Þjónusta getur verið hvað sem er. Mismunandi þjónustur geta notað sömu tengið vegna þess að þær hafa mismunandi IP tölur.

Eftirfarandi skýringarmynd sýnir allt ofangreint á myndrænu formi:

1) Ímyndaðu þér að þjónustan beini umferð að ákveðnum belg:

Sjónræn leiðarvísir um bilanaleit Kubernetes

2) Þegar þú býrð til pod verður þú að tilgreina containerPort fyrir hvert ílát í belg:

Sjónræn leiðarvísir um bilanaleit Kubernetes

3) Þegar þú býrð til þjónustu verður þú að tilgreina port и targetPort. En hver er notaður til að tengjast ílátinu?

Sjónræn leiðarvísir um bilanaleit Kubernetes

4) Í gegnum targetPort. Það verður að passa containerPort.

Sjónræn leiðarvísir um bilanaleit Kubernetes

5) Segjum að port 3000 sé opið í gámnum. Þá gildið targetPort ætti að vera eins.

Sjónræn leiðarvísir um bilanaleit Kubernetes

Í YAML skránni eru merkingar og ports / targetPort verður að passa:

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

Hvað með merkimiðann track: canary efst í Deployment hlutanum? Ætti það að passa?

Þetta merki er dreifingarsértækt og er ekki notað af þjónustunni til að beina umferð. Með öðrum orðum, það er hægt að fjarlægja það eða úthluta öðru gildi.

Hvað með veljarann matchLabels?

Það verður alltaf að passa við merki Podsins, þar sem það er notað af Deployment til að rekja belg.

Gerum ráð fyrir að þú hafir gert réttar breytingar. Hvernig á að athuga þá?

Þú getur athugað belgmerkið með eftirfarandi skipun:

kubectl get pods --show-labels

Eða, ef fræbelgur tilheyra nokkrum forritum:

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

Hvar any-name=my-app er merki any-name: my-app.

Eru einhverjir erfiðleikar eftir?

Þú getur tengst pod! Til að gera þetta þarftu að nota skipunina port-forward í kubectl. Það gerir þér kleift að tengjast þjónustunni og athuga tenginguna.

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

Hér:

  • service/<service name> — nafn þjónustu; í okkar tilviki er það my-service;
  • 3000 er portið sem þarf að opna á tölvunni;
  • 80 - höfn tilgreind í reitnum port þjónusta.

Ef tengingunni var komið á, þá eru stillingarnar réttar.

Ef tengingin mistekst er vandamál með merkin eða tengin passa ekki saman.

Tengsl þjónustu og Ingress

Næsta skref í að veita aðgang að forritinu tengist uppsetningu Ingress. Ingress þarf að vita hvernig á að finna þjónustu, finna síðan belg og beina umferð til þeirra. Ingress finnur nauðsynlega þjónustu með nafni og opinni höfn.

Í lýsingunni á Ingress og Service verða tvær breytur að passa:

  1. servicePort í Ingress verður að passa við færibreytuna port í þjónustu;
  2. serviceName í Ingress verður að passa við völlinn name í þjónustu.

Eftirfarandi skýringarmynd dregur saman hafnartengingarnar:

1) Eins og þú veist nú þegar hlustar Þjónusta á ákveðinn port:

Sjónræn leiðarvísir um bilanaleit Kubernetes

2) Ingress hefur færibreytu sem kallast servicePort:

Sjónræn leiðarvísir um bilanaleit Kubernetes

3) Þessi breytu (servicePort) verður alltaf að passa port í þjónustuskilgreiningunni:

Sjónræn leiðarvísir um bilanaleit Kubernetes

4) Ef port 80 er tilgreint í Þjónusta, þá er nauðsynlegt að servicePort var líka jafnt og 80:

Sjónræn leiðarvísir um bilanaleit Kubernetes

Í reynd þarftu að borga eftirtekt til eftirfarandi línur:

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

Hvernig á að athuga hvort Ingress sé í gangi?

Þú getur notað aðferðina með kubectl port-forward, en í stað þjónustunnar þarftu að tengjast Ingress stjórnandanum.

Fyrst þarftu að finna út nafn belgsins með Ingress stjórnanda:

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

Finndu Ingress pod (það gæti verið í öðru nafnrými) og keyrðu skipunina describetil að finna gáttanúmerin:

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

Að lokum, tengdu við pod:

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

Nú í hvert skipti sem þú sendir beiðni til port 3000 á tölvunni þinni, verður það áframsend á port 80 á belgnum með Ingress stjórnandi. Með því að fara til http://localhost:3000, þú ættir að sjá síðuna sem forritið býr til.

Yfirlit yfir hafnir

Við skulum enn og aftur muna hvaða tengi og merki verða að passa:

  1. Valinn í þjónustuskilgreiningunni verður að passa við merki belgsins;
  2. targetPort í skilgreiningunni Þjónusta verður að passa containerPort ílát inni í belgnum;
  3. port í skilgreiningunni Þjónusta getur verið hvað sem er. Mismunandi þjónustur geta notað sömu tengið vegna þess að þær hafa mismunandi IP tölur;
  4. servicePort Ingress verður að passa port í skilgreiningunni á þjónustu;
  5. Þjónustuheitið verður að passa við reitinn serviceName í Ingress.

Því miður er ekki nóg að vita hvernig á að skipuleggja YAML uppsetningu á réttan hátt.

Hvað gerist þegar hlutirnir fara úrskeiðis?

Hugsanlegt er að hólfið ræsist ekki eða það getur hrunið.

3 skref til að greina forritavandamál í Kubernetes

Áður en þú byrjar að kemba uppsetningu þína þarftu að hafa góðan skilning á því hvernig Kubernetes virkar.

Þar sem hvert forrit sem er hlaðið niður í K8s hefur þrjá hluti, ætti að kemba þá í ákveðinni röð, byrjað alveg frá botninum.

  1. Fyrst þarftu að ganga úr skugga um að belgirnir virki, síðan...
  2. Athugaðu hvort þjónustan veitir umferð til belganna og þá...
  3. Athugaðu hvort Ingress sé rétt stillt.

Sjónræn framsetning:

1) Þú ættir að byrja að leita að vandamálum alveg frá botni. Athugaðu fyrst hvort belg hafi stöður Ready и Running:

Sjónræn leiðarvísir um bilanaleit Kubernetes

2) Ef fræbelgirnir eru tilbúnir (Ready), ættir þú að komast að því hvort þjónustan dreifir umferð á milli belg:

Sjónræn leiðarvísir um bilanaleit Kubernetes

3) Að lokum þarftu að greina tengslin milli þjónustunnar og Ingress:

Sjónræn leiðarvísir um bilanaleit Kubernetes

1. Greining á belgjum

Í flestum tilfellum er vandamálið tengt belgnum. Gakktu úr skugga um að belgirnir séu skráðir sem Ready и Running. Þú getur athugað þetta með því að nota skipunina:

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

Í skipunarúttakinu hér að ofan er síðasta belgurinn skráður sem Running и Readyþetta á hins vegar ekki við um hina tvo.

Hvernig á að skilja hvað fór úrskeiðis?

Það eru fjórar gagnlegar skipanir til að greina belg:

  1. kubectl logs <имя pod'а> gerir þér kleift að draga logs úr ílátum í belg;
  2. kubectl describe pod <имя pod'а> gerir þér kleift að skoða lista yfir atburði sem tengjast belgnum;
  3. kubectl get pod <имя pod'а> gerir þér kleift að fá YAML stillingar á belg sem er geymdur í Kubernetes;
  4. kubectl exec -ti <имя pod'а> bash gerir þér kleift að ræsa gagnvirka stjórnskel í einu af belgílátunum

Hvorn ættir þú að velja?

Staðreyndin er sú að það er engin algild skipun. Sambland af þessu ætti að nota.

Dæmigert pod vandamál

Það eru tvær megingerðir af pod-villum: ræsingarvillur og afturkreistingarvillur.

Ræsingarvillur:

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

Runtime villur:

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

Sumar villur eru algengari en aðrar. Hér eru nokkrar af algengustu villunum og hvernig á að laga þær.

ImagePullBackOff

Þessi villa birtist þegar Kubernetes getur ekki fengið mynd fyrir einn af belgílátunum. Hér eru þrjár algengustu ástæðurnar fyrir þessu:

  1. Nafn myndarinnar er rangt - þú gerðir til dæmis mistök í henni eða myndin er ekki til;
  2. Merki sem ekki var til var tilgreint fyrir myndina;
  3. Myndin er geymd í einkaskrá og Kubernetes hefur ekki aðgang að henni.

Auðvelt er að útrýma fyrstu tveimur ástæðunum - leiðréttu bara nafn myndarinnar og merkið. Þegar um hið síðarnefnda er að ræða þarftu að slá inn skilríki fyrir lokaða skráninguna í Secret og bæta við tenglum við hana í belg. Í Kubernetes skjölunum það er dæmi hvernig er hægt að gera þetta.

Crash Loop Back Off

Kubenetes kastar villu CrashLoopBackOff, ef ílátið getur ekki ræst. Þetta gerist venjulega þegar:

  1. Það er villa í forritinu sem kemur í veg fyrir að það ræsist;
  2. ílát rangt stillt;
  3. Liveness prófið hefur fallið of oft.

Þú verður að reyna að komast að annálunum úr ílátinu til að komast að ástæðunni fyrir bilun hans. Ef það er erfitt að nálgast annálana vegna þess að gámurinn endurræsir sig of fljótt geturðu notað eftirfarandi skipun:

kubectl logs <pod-name> --previous

Það sýnir villuboð frá fyrri holdgun ílátsins.

RunContainerError

Þessi villa kemur upp þegar ekki tekst að ræsa ílátið. Það samsvarar augnablikinu áður en forritið er ræst. Það stafar venjulega af röngum stillingum, til dæmis:

  • að reyna að tengja hljóðstyrk sem ekki er til eins og ConfigMap eða Secrets;
  • tilraun til að tengja skrifvarið bindi sem lesa-skrifa.

Liðið er vel til þess fallið að greina slíkar villur kubectl describe pod <pod-name>.

Bækur eru í biðstöðu

Þegar belgurinn er búinn til er hann áfram í ríkinu Pending.

Hvers vegna er þetta að gerast?

Hér eru mögulegar ástæður (ég geri ráð fyrir að tímaáætlunin virki vel):

  1. Klasinn hefur ekki nægjanlegt fjármagn, svo sem vinnsluorku og minni, til að keyra hólfið.
  2. Hluturinn er settur upp í viðeigandi nafnrými ResourceQuota og að búa til pod mun valda því að nafnrýmið fer út fyrir kvótann.
  3. Pod er bundið í bið PersistentVolumeClaim.

Í þessu tilviki er mælt með því að nota skipunina kubectl describe og athugaðu kaflann Events:

kubectl describe pod <pod name>

Ef um villur er að ræða sem tengjast ResourceQuotas, er mælt með því að skoða klasaskrárnar með því að nota skipunina

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

Pods eru ekki tilbúnir

Ef fræbelgur er skráður sem Running, en er ekki í ástandi Ready, þýðir að athuga viðbúnað þess (viðbúnaðarrannsókn) mistekst.

Þegar þetta gerist tengist podinn ekki þjónustunni og engin umferð rennur til hans. Bilun í viðbúnaðarprófinu stafar af vandamálum í forritinu. Í þessu tilviki, til að finna villuna, þarftu að greina hlutann Events í skipunarúttakinu kubectl describe.

2. Þjónustugreining

Ef fræbelgir eru skráðir sem Running и Ready, en það er enn ekkert svar frá forritinu, þú ættir að athuga þjónustustillingarnar.

Þjónusta er ábyrg fyrir því að beina umferð til fræbelgs eftir merkjum þeirra. Þess vegna er það fyrsta sem þú þarft að gera að athuga hversu margir belg vinna með þjónustunni. Til að gera þetta geturðu athugað endapunktana í þjónustunni:

kubectl describe service <service-name> | grep Endpoints

Endapunktur er par af gildum formsins <IP-адрес:порт>, og að minnsta kosti eitt slíkt par verður að vera til staðar í úttakinu (þ.e. að minnsta kosti einn pod vinnur með þjónustunni).

Ef kafla Endpoins tómt, tveir valkostir eru mögulegir:

  1. það eru engir belg með réttu merki (vísbending: athugaðu hvort nafnrýmið sé rétt valið);
  2. Það er villa í þjónustumerkingum í veljaranum.

Ef þú sérð lista yfir endapunkta en hefur samt ekki aðgang að forritinu, þá er líklegur sökudólgur galla í targetPort í þjónustulýsingu.

Hvernig á að athuga virkni þjónustunnar?

Óháð tegund þjónustu geturðu notað skipunina kubectl port-forward til að tengjast því:

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

Hér:

  • <service-name> — nafn þjónustu;
  • 3000 er portið sem þú opnar á tölvunni;
  • 80 - port á þjónustuhlið.

3. Ingress greiningar

Ef þú hefur lesið hingað til, þá:

  • fræbelgir eru skráðir sem Running и Ready;
  • þjónustan dreifir umferð um belg.

Hins vegar geturðu enn ekki náð í appið.

Þetta þýðir að Ingress stjórnandi er líklega ekki rétt stilltur. Þar sem Ingress stjórnandi er þriðja aðila íhlutur í þyrpingunni eru mismunandi villuleitaraðferðir eftir tegund hans.

En áður en þú grípur til þess að nota sérstök verkfæri til að stilla Ingress geturðu gert eitthvað mjög einfalt. Ingress notar serviceName и servicePort til að tengjast þjónustunni. Þú þarft að athuga hvort þau séu rétt stillt. Þú getur gert þetta með því að nota skipunina:

kubectl describe ingress <ingress-name>

Ef dálkur Backend tóm, það eru miklar líkur á stillingarvillu. Ef bakendarnir eru til staðar, en forritið er enn ekki aðgengilegt, gæti vandamálið tengst:

  • Inngangur aðgengisstillingar frá almenna internetinu;
  • klasaaðgengisstillingar frá almenna internetinu.

Þú getur greint vandamál með innviðina með því að tengjast beint við Ingress pod. Til að gera þetta, finndu fyrst Ingress Controller pod (það gæti verið í öðru nafnrými):

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

Notaðu skipunina describetil að stilla höfnina:

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

Að lokum, tengdu við pod:

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

Nú verður öllum beiðnum um port 3000 á tölvunni vísað á port 80 á pod.

Virkar það núna?

  • Ef já, þá er vandamálið með innviðina. Nauðsynlegt er að komast að því nákvæmlega hvernig umferð er beint að klasanum.
  • Ef ekki, þá er vandamálið með Ingress stjórnanda.

Ef þú getur ekki fengið Ingress stjórnandi til að virka þarftu að kemba hann.

Það eru margar tegundir af Ingress stýringar. Vinsælast eru Nginx, HAProxy, Traefik o.fl. (fyrir frekari upplýsingar um núverandi lausnir, sjá umfjöllun okkar - ca. þýðing.) Þú ættir að vísa til bilanaleitarleiðbeininganna í viðeigandi skjölum stjórnanda. Vegna þess að Ingress Nginx er vinsælasti Ingress stjórnandi, við höfum sett inn nokkur ráð í greininni til að leysa vandamál sem tengjast honum.

Villuleit í Ingress Nginx stjórnanda

Ingress-nginx verkefnið hefur embættismann viðbót fyrir kubectl. Lið kubectl ingress-nginx hægt að nota fyrir:

  • greining á annálum, bakenda, vottorðum osfrv.;
  • tengingar við Ingress;
  • að rannsaka núverandi uppsetningu.

Eftirfarandi þrjár skipanir munu hjálpa þér með þetta:

  • kubectl ingress-nginx lint — ávísanir nginx.conf;
  • kubectl ingress-nginx backend — kannar bakenda (svipað og kubectl describe ingress <ingress-name>);
  • kubectl ingress-nginx logs — skoðar skrárnar.

Athugaðu að í sumum tilfellum gætir þú þurft að tilgreina rétt nafnrými fyrir Ingress stjórnandi með því að nota fánann --namespace <name>.

Yfirlit

Úrræðaleit Kubernetes getur verið krefjandi ef þú veist ekki hvar þú átt að byrja. Þú ættir alltaf að nálgast vandamálið á botn-upp hátt: Byrjaðu með fræbelg og farðu síðan yfir í þjónustuna og Ingress. Villuleitaraðferðirnar sem lýst er í þessari grein er hægt að beita á aðra hluti, svo sem:

  • aðgerðalaus störf og CronJobs;
  • StatefulSets og DaemonSets.

Ég lýsi þakklæti mínu Gergely Risko, Daniel Weibel и Charles Christyraj fyrir mikilvægar athugasemdir og viðbætur.

PS frá þýðanda

Lestu líka á blogginu okkar:

Heimild: www.habr.com

Bæta við athugasemd