Visuaalne juhend Kubernetese tõrkeotsinguks

Märge. tõlge: see artikkel on osa avalikus omandis avaldatud projekti materjalidest õppida8s, koolitage ettevõtteid ja üksikadministraatoreid Kubernetesega töötamiseks. Selles jagab projektijuht Daniele Polencic visuaalseid juhiseid selle kohta, milliseid samme teha üldiste probleemide korral K8s klastris töötavate rakendustega.

Visuaalne juhend Kubernetese tõrkeotsinguks

TL;DR: siin on diagramm, mis aitab teil Kubernetes juurutamist siluda:

Visuaalne juhend Kubernetese tõrkeotsinguks

Vooskeem klastris vigade leidmiseks ja parandamiseks. Originaal (ingliskeelne) on saadaval aadressil pDF и pildina.

Rakenduse Kubernetes juurutamisel peate tavaliselt määratlema kolm komponenti.

  • Deployment - see on omamoodi retsept rakenduse koopiate loomiseks, mida nimetatakse kaunadeks;
  • Teenus — sisemine koormuse tasakaalustaja, mis jaotab liikluse kaustade vahel;
  • Ingress — kirjeldus selle kohta, kuidas liiklus välismaailmast teenusesse jõuab.

Siin on kiire graafiline kokkuvõte:

1) Kubernetes saavad rakendused välismaailmast liiklust kahe koormuse tasakaalustajate kihi kaudu: sisemine ja väline.

Visuaalne juhend Kubernetese tõrkeotsinguks

2) Sisemise tasakaalustaja nimeks on Service, välist Ingressiks.

Visuaalne juhend Kubernetese tõrkeotsinguks

3) juurutamine loob podid ja jälgib neid (neid ei looda käsitsi).

Visuaalne juhend Kubernetese tõrkeotsinguks

Oletame, et soovite juurutada lihtsa rakenduse a la Tere maailm. Selle YAML-i konfiguratsioon näeb välja selline:

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

Määratlus on üsna pikk ja komponendid üksteisega seotud on kergesti segadusse.

Näiteks:

  • Millal peaksite kasutama porti 80 ja millal peaksite kasutama porti 8080?
  • Kas peaksin looma iga teenuse jaoks uue pordi, et need ei oleks vastuolus?
  • Kas siltide nimed on olulised? Kas need peaksid igal pool ühesugused olema?

Enne silumisele keskendumist meenutagem, kuidas need kolm komponenti on omavahel seotud. Alustame juurutamise ja teenindusega.

Kasutuselevõtu ja teenuse vaheline seos

Teid üllatab, kuid juurutamine ja teenus pole kuidagi seotud. Selle asemel osutab teenus otse Podidele, minnes juurutamisest mööda.

Seega oleme huvitatud sellest, kuidas Pods ja Services on üksteisega seotud. Kolm asja, mida meeles pidada:

  1. Valija (selector) teenuse jaoks peab vastama vähemalt ühele Podi sildile.
  2. targetPort peab sobima containerPort konteineri sees.
  3. port Teenus võib olla ükskõik milline. Erinevad teenused võivad kasutada sama porti, kuna neil on erinevad IP-aadressid.

Järgmine diagramm kujutab kõike ülaltoodut graafilisel kujul:

1) Kujutage ette, et teenus suunab liikluse teatud kausta:

Visuaalne juhend Kubernetese tõrkeotsinguks

2) Podi loomisel tuleb täpsustada containerPort iga kaunades oleva konteineri kohta:

Visuaalne juhend Kubernetese tõrkeotsinguks

3) Teenuse loomisel tuleb täpsustada port и targetPort. Kuid kumba kasutatakse konteineriga ühendamiseks?

Visuaalne juhend Kubernetese tõrkeotsinguks

4) Via targetPort. See peab sobima containerPort.

Visuaalne juhend Kubernetese tõrkeotsinguks

5) Oletame, et konteineris on avatud port 3000. Siis väärtus targetPort peaks olema sama.

Visuaalne juhend Kubernetese tõrkeotsinguks

YAML-failis sildid ja ports / targetPort peab sobima:

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

Aga etikett track: canary juurutamise jaotise ülaosas? Kas peaks sobima?

See silt on juurutusspetsiifiline ja teenus ei kasuta seda liikluse suunamiseks. Teisisõnu, selle saab eemaldada või määrata sellele muu väärtuse.

Aga valija matchLabels?

See peab alati vastama Podi siltidele, kuna juurutamine kasutab seda kaustade jälgimiseks.

Oletame, et tegite õiged muudatused. Kuidas neid kontrollida?

Podi silti saate kontrollida järgmise käsuga:

kubectl get pods --show-labels

Või kui kaunad kuuluvad mitmesse rakendusse:

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

kus any-name=my-app on silt any-name: my-app.

Kas raskusi on jäänud?

Saate ühendada podiga! Selleks peate kasutama käsku port-forward in kubectl. See võimaldab teil teenusega ühenduse luua ja ühendust kontrollida.

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

Siin:

  • service/<service name> — teenuse nimi; meie puhul on see nii my-service;
  • 3000 on port, mis tuleb arvutis avada;
  • 80 - väljal määratud port port teenus.

Kui ühendus loodi, on sätted õiged.

Kui ühendus ebaõnnestub, on probleem siltidega või pordid ei ühti.

Service ja Ingressi suhe

Järgmine samm rakendusele juurdepääsu võimaldamisel hõlmab Ingressi seadistamist. Ingress peab teadma, kuidas teenust leida, seejärel leida kaunad ja suunata liiklus neisse. Ingress leiab vajaliku teenuse nime ja avatud pordi järgi.

Sissepääsu ja teenuse kirjelduses peavad vastama kaks parameetrit:

  1. servicePort in Ingress peab vastama parameetrile port teenistuses;
  2. serviceName in Ingress peab vastama väljale name teeninduses.

Järgmine diagramm võtab kokku pordiühendused:

1) Nagu te juba teate, kuulab Service teatud port:

Visuaalne juhend Kubernetese tõrkeotsinguks

2) Ingressil on parameeter nimega servicePort:

Visuaalne juhend Kubernetese tõrkeotsinguks

3) See parameeter (servicePort) peab alati ühtima port teenuse määratluses:

Visuaalne juhend Kubernetese tõrkeotsinguks

4) Kui Service'is on määratud port 80, siis on see vajalik servicePort oli samuti võrdne 80-ga:

Visuaalne juhend Kubernetese tõrkeotsinguks

Praktikas peate tähelepanu pöörama järgmistele ridadele:

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

Kuidas kontrollida, kas Ingress töötab?

Meetodit saate kasutada koos kubectl port-forward, kuid teenuse asemel peate looma ühenduse sissepääsukontrolleriga.

Esmalt peate Ingressi kontrolleriga välja selgitama podi nime:

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

Otsige üles sisendmoodul (see võib asuda teises nimeruumis) ja käivitage käsk describepordi numbrite leidmiseks:

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

Lõpuks ühendage podiga:

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

Nüüd iga kord, kui saadate päringu oma arvuti pordile 3000, edastatakse see sisendkontrolleriga pesa porti 80. Minnes juurde http://localhost:3000, peaksite nägema rakenduse loodud lehte.

Sadamate kokkuvõte

Tuletame veel kord meelde, millised pordid ja sildid peavad ühtima:

  1. Teenuse definitsiooni valija peab ühtima kausta sildiga;
  2. targetPort definitsioonis Teenus peab vastama containerPort konteiner kauna sees;
  3. port definitsioonis võib teenus olla ükskõik milline. Erinevad teenused võivad kasutada sama porti, kuna neil on erinevad IP-aadressid;
  4. servicePort Sissepääs peab ühtima port teenuse määratluses;
  5. Teenuse nimi peab vastama väljale serviceName Ingressis.

Kahjuks ei piisa YAML-i konfiguratsiooni õigesti struktureerimise teadmisest.

Mis juhtub, kui asjad lähevad valesti?

Pod ei pruugi käivituda või jookseb kokku.

3 sammu Kubernetesi rakendusprobleemide diagnoosimiseks

Enne juurutuse silumise alustamist peate Kubernetesi toimimisest hästi aru saama.

Kuna igal K8s allalaaditud rakendusel on kolm komponenti, tuleks neid siluda kindlas järjekorras, alustades päris alt.

  1. Kõigepealt peate veenduma, et kaunad töötavad, seejärel...
  2. Kontrollige, kas teenus tagab liikluse kaunadele ja seejärel...
  3. Kontrollige, kas Ingress on õigesti konfigureeritud.

Visuaalne esitus:

1) Probleeme tuleks hakata otsima päris põhjast. Esmalt kontrollige, kas kaunadel on olekud Ready и Running:

Visuaalne juhend Kubernetese tõrkeotsinguks

2) Kui kaunad on valmis (Ready), peaksite välja selgitama, kas teenus jaotab liiklust kaustade vahel:

Visuaalne juhend Kubernetese tõrkeotsinguks

3) Lõpuks peate analüüsima seost teenuse ja Ingressi vahel:

Visuaalne juhend Kubernetese tõrkeotsinguks

1. Kaunade diagnostika

Enamikul juhtudel on probleem seotud kaunaga. Veenduge, et kaunad oleksid loetletud kui Ready и Running. Seda saate kontrollida käsuga:

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

Ülaltoodud käsuväljundis on viimane kausta loendis Running и Readykahe teise puhul see aga ei kehti.

Kuidas aru saada, mis valesti läks?

Kaunade diagnoosimiseks on neli kasulikku käsku:

  1. kubectl logs <имя pod'а> võimaldab kaunas konteineritest palke välja võtta;
  2. kubectl describe pod <имя pod'а> võimaldab vaadata podiga seotud sündmuste loendit;
  3. kubectl get pod <имя pod'а> võimaldab hankida Kubernetesesse salvestatud podi YAML-i konfiguratsiooni;
  4. kubectl exec -ti <имя pod'а> bash võimaldab käivitada interaktiivse käsukesta ühes pod konteineritest

Millise peaksite valima?

Fakt on see, et universaalset käsku pole olemas. Kasutada tuleks nende kombinatsiooni.

Tüüpilised taskuprobleemid

Podrikaid on kahte peamist tüüpi: käivitusvead ja käitusvead.

Käivitusvead:

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

Käitusaja vead:

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

Mõned vead on levinumad kui teised. Siin on mõned levinumad vead ja nende parandamine.

ImagePullBackOff

See tõrge ilmneb siis, kui Kubernetes ei saa ühe kaustakonteinerite jaoks pilti hankida. Siin on kolm kõige levinumat põhjust.

  1. Pildi nimi on vale – näiteks tegite selles vea või pilti pole olemas;
  2. Pildi jaoks määrati olematu silt;
  3. Pilt on salvestatud privaatses registris ja Kubernetesil pole sellele juurdepääsu luba.

Kaht esimest põhjust on lihtne kõrvaldada – lihtsalt paranda pildi nimi ja silt. Viimase puhul peate sisestama suletud registri volikirjad Secret ja lisama sellele lingid kaustades. Kubernetese dokumentatsioonis näide on olemas kuidas seda teha saab.

Crash Loop Back Off

Kubenetes viskab vea CrashLoopBackOff, kui konteiner ei saa käivituda. See juhtub tavaliselt siis, kui:

  1. Rakenduses on viga, mis takistab selle käivitamist;
  2. Konteiner valesti konfigureeritud;
  3. Elavsuse test on liiga palju kordi ebaõnnestunud.

Selle rikke põhjuse väljaselgitamiseks peate proovima konteinerist palkide juurde pääseda. Kui logidele on raske juurde pääseda, kuna konteiner taaskäivitub liiga kiiresti, võite kasutada järgmist käsku:

kubectl logs <pod-name> --previous

See kuvab konteineri eelmise kehastuse veateateid.

RunContainerError

See tõrge ilmneb siis, kui konteiner ei käivitu. See vastab hetkele enne rakenduse käivitamist. Selle põhjuseks on tavaliselt valed sätted, näiteks:

  • püüdes ühendada olematu köide, näiteks ConfigMap või Secrets;
  • katse ühendada kirjutuskaitstud köide lugemiseks-kirjutamiseks.

Meeskond sobib hästi selliste vigade analüüsimiseks kubectl describe pod <pod-name>.

Kaunad on ootel olekus

Pärast loomist jääb kauna olekusse Pending.

Miks see juhtub?

Siin on võimalikud põhjused (eeldan, et ajakava töötab hästi):

  1. Klastris pole podi käitamiseks piisavalt ressursse, nagu töötlemisvõimsus ja mälu.
  2. Objekt installitakse vastavasse nimeruumi ResourceQuota ja podi loomine põhjustab nimeruumi kvoodist suuremat piiri.
  3. Pod on seotud ootel PersistentVolumeClaim.

Sel juhul on soovitatav kasutada käsku kubectl describe ja kontrollige jaotist Events:

kubectl describe pod <pod name>

Vigade korral, mis on seotud ResourceQuotas, on soovitatav vaadata klastri logisid käsu abil

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

Kaunad pole valmis

Kui pod on loetletud kui Running, kuid ei ole olekus Ready, tähendab selle valmisoleku kontrollimist (valmidussond) ebaõnnestub.

Kui see juhtub, ei ühendu pod teenusega ja liiklus sellele ei voola. Valmisoleku testi ebaõnnestumise põhjuseks on rakenduses esinevad probleemid. Sel juhul peate vea leidmiseks jaotist analüüsima Events käsu väljundis kubectl describe.

2. Teeninduse diagnostika

Kui kaunad on loetletud kui Running и Ready, kuid rakendus ei vasta ikka veel, peaksite kontrollima teenuse seadeid.

Teenused vastutavad liikluse suunamise eest kaunadele sõltuvalt nende siltidest. Seetõttu peate esimese asjana kontrollima, kui palju kaunasid teenusega töötab. Selleks saate kontrollida teenuse lõpp-punkte:

kubectl describe service <service-name> | grep Endpoints

Lõpp-punkt on vormi väärtuste paar <IP-адрес:порт>, ja väljundis peab olema vähemalt üks selline paar (st vähemalt üks pod töötab teenusega).

Kui lõik Endpoins tühi, on võimalikud kaks võimalust:

  1. õige sildiga kaunasid pole (vihje: kontrolli, kas nimeruum on õigesti valitud);
  2. Selektoris on viga teenusesiltides.

Kui näete lõpp-punktide loendit, kuid siiski ei pääse rakendusele juurde, on tõenäoline süüdlane viga targetPort teenuse kirjelduses.

Kuidas teenuse funktsionaalsust kontrollida?

Sõltumata teenuse tüübist saate kasutada käsku kubectl port-forward sellega ühenduse loomiseks:

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

Siin:

  • <service-name> — teenuse nimi;
  • 3000 on port, mille avate arvutis;
  • 80 - port teeninduspoolel.

3. Sissepääsu diagnostika

Kui olete siiani lugenud, siis:

  • kaunad on loetletud kui Running и Ready;
  • teenus jaotab liiklust edukalt kaunade vahel.

Siiski ei pääse te endiselt rakendusse.

See tähendab, et Ingressi kontroller pole tõenäoliselt õigesti konfigureeritud. Kuna Ingressi kontroller on klastri kolmanda osapoole komponent, on selle tüübist sõltuvalt erinevad silumismeetodid.

Kuid enne kui hakkate Ingressi konfigureerimiseks kasutama spetsiaalseid tööriistu, saate teha midagi väga lihtsat. Ingress kasutab serviceName и servicePort teenusega ühenduse loomiseks. Peate kontrollima, kas need on õigesti konfigureeritud. Seda saate teha käsuga:

kubectl describe ingress <ingress-name>

Kui veerg Backend tühi, on konfiguratsioonivea tõenäosus suur. Kui taustaprogrammid on paigas, kuid rakendus pole ikka veel juurdepääsetav, võib probleem olla seotud järgmisega:

  • Juurdepääsetavusseadete sisenemine avalikust Internetist;
  • klastri juurdepääsetavuse seaded avalikust Internetist.

Saate tuvastada infrastruktuuriga seotud probleemid, kui loote ühenduse otse sisestuspuldiga. Selleks leidke esmalt sissepääsukontrolleri pood (see võib asuda teises nimeruumis):

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

Kasutage käsku describepordi määramiseks:

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

Lõpuks ühendage podiga:

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

Nüüd suunatakse kõik arvuti pordi 3000 taotlused ümber pesa 80. porti.

Kas see nüüd töötab?

  • Kui jah, siis on probleem infrastruktuuris. Tuleb täpselt välja selgitada, kuidas liiklus klastrisse suunatakse.
  • Kui ei, siis on probleem Ingressi kontrolleris.

Kui te ei saa Ingressi kontrollerit tööle, peate selle siluma.

Ingressi kontrollereid on palju erinevaid. Kõige populaarsemad on Nginx, HAProxy, Traefik jne. (lisateavet olemasolevate lahenduste kohta vt meie ülevaade - u. tõlge.) Peaksite lugema tõrkeotsingu juhendit vastava kontrolleri dokumentatsioonis. Kuna Ingress Nginx on kõige populaarsem Ingressi kontroller, oleme lisanud artiklisse mõned näpunäited sellega seotud probleemide lahendamiseks.

Ingressi Nginxi kontrolleri silumine

Ingress-nginxi projektil on ametnik kubectli pistikprogramm. Meeskond kubectl ingress-nginx saab kasutada:

  • logide, taustaprogrammide, sertifikaatide jms analüüs;
  • ühendused Ingressiga;
  • praeguse konfiguratsiooni uurimine.

Järgmised kolm käsku aitavad teid selles:

  • kubectl ingress-nginx lint — kontrollid nginx.conf;
  • kubectl ingress-nginx backend — uurib taustaprogrammi (sarnaselt kubectl describe ingress <ingress-name>);
  • kubectl ingress-nginx logs — kontrollib logisid.

Pange tähele, et mõnel juhul peate võib-olla määrama lipu abil sisendkontrolleri õige nimeruumi --namespace <name>.

Kokkuvõte

Kubernetese tõrkeotsing võib olla keeruline, kui te ei tea, kust alustada. Peaksite alati probleemile lähenema alt üles: alustage kaunadest ja liikuge seejärel teenuse ja Ingressi juurde. Selles artiklis kirjeldatud silumistehnikaid saab rakendada ka muudele objektidele, näiteks:

  • idle Jobs ja CronJobs;
  • StatefulSets ja DaemonSets.

Avaldan oma tänu Gergely Risko, Daniel Weibel и Charles Christyraj väärtuslike kommentaaride ja täienduste eest.

PS tõlkijalt

Loe ka meie blogist:

Allikas: www.habr.com

Lisa kommentaar