Vaizdinis „Kubernetes“ trikčių šalinimo vadovas

Pastaba. vert.: Šis straipsnis yra viešai paskelbtos projekto medžiagos dalis mokytis8s, mokyti įmones ir individualius administratorius dirbti su Kubernetes. Joje Daniele Polencic, projektų vadovė, dalijasi vaizdinėmis instrukcijomis, kokių veiksmų imtis iškilus bendroms programoms, veikiančioms K8s klasteryje, problemų.

Vaizdinis „Kubernetes“ trikčių šalinimo vadovas

TL;DR: čia yra diagrama, kuri padės derinti diegimą Kubernetes:

Vaizdinis „Kubernetes“ trikčių šalinimo vadovas

Struktūrinė schema klasterio klaidoms rasti ir taisyti. Originalą (anglų kalba) galima rasti adresu PDF и kaip paveikslas.

Diegiant programą Kubernetes, paprastai reikia apibrėžti tris komponentus:

  • diegimo - tai savotiškas programos, vadinamos ankštimis, kopijų kūrimo receptas;
  • tarnyba — vidinis apkrovos balansavimo įrenginys, paskirstantis srautą tarp modulių;
  • Įėjimas — aprašymas, kaip srautas iš išorinio pasaulio pateks į Paslaugą.

Štai trumpa grafinė santrauka:

1) „Kubernetes“ programos gauna srautą iš išorinio pasaulio per du apkrovos balansavimo sluoksnius: vidinį ir išorinį.

Vaizdinis „Kubernetes“ trikčių šalinimo vadovas

2) Vidinis balansuotojas vadinamas Service, išorinis - Ingress.

Vaizdinis „Kubernetes“ trikčių šalinimo vadovas

3) Diegiant sukuriami podeliai ir jie stebimi (jie nekuriami rankiniu būdu).

Vaizdinis „Kubernetes“ trikčių šalinimo vadovas

Tarkime, kad norite įdiegti paprastą programą a la Sveikas pasaulis. YAML konfigūracija atrodys taip:

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

Apibrėžimas yra gana ilgas ir lengva susipainioti, kaip komponentai yra susiję vienas su kitu.

Pavyzdžiui:

  • Kada naudoti 80 prievadą, o kada – 8080?
  • Ar turėčiau sukurti naują prievadą kiekvienai paslaugai, kad jos neprieštarautų?
  • Ar etikečių pavadinimai svarbūs? Ar jie visur turi būti vienodi?

Prieš sutelkdami dėmesį į derinimą, prisiminkime, kaip šie trys komponentai yra susiję vienas su kitu. Pradėkime nuo diegimo ir aptarnavimo.

Diegimo ir aptarnavimo ryšys

Nustebsite, bet diegimas ir paslaugos niekaip nesusiję. Vietoj to, paslauga nukreipia tiesiai į Pods, apeinant diegimą.

Taigi mus domina, kaip ankštys ir paslaugos yra tarpusavyje susijusios. Trys dalykai, kuriuos reikia atsiminti:

  1. parinkiklis (selector) „Service“ turi atitikti bent vieną „Pod“ etiketę.
  2. targetPort turi atitikti containerPort talpyklos viduje.
  3. port Paslauga gali būti bet kokia. Skirtingos paslaugos gali naudoti tą patį prievadą, nes turi skirtingus IP adresus.

Toliau pateiktoje diagramoje visa tai, kas išdėstyta pirmiau, pavaizduota grafine forma:

1) Įsivaizduokite, kad paslauga nukreipia srautą į tam tikrą grupę:

Vaizdinis „Kubernetes“ trikčių šalinimo vadovas

2) Kurdami podą, turite nurodyti containerPort kiekvienam konteineriui ankštyse:

Vaizdinis „Kubernetes“ trikčių šalinimo vadovas

3) Kurdami paslaugą turite nurodyti port и targetPort. Bet kuris iš jų naudojamas prijungti prie konteinerio?

Vaizdinis „Kubernetes“ trikčių šalinimo vadovas

4) Per targetPort. Turi sutapti containerPort.

Vaizdinis „Kubernetes“ trikčių šalinimo vadovas

5) Tarkime, konteineryje atidarytas prievadas 3000. Tada vertė targetPort turėtų būti tas pats.

Vaizdinis „Kubernetes“ trikčių šalinimo vadovas

YAML faile etiketės ir ports / targetPort turi atitikti:

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

Ką jau kalbėti apie etiketę track: canary skilties Diegimas viršuje? Ar turėtų atitikti?

Ši etiketė priklauso nuo diegimo ir jos nenaudoja paslauga nukreipdama srautą. Kitaip tariant, jį galima pašalinti arba priskirti kitą reikšmę.

Ką daryti su selektoriumi matchLabels?

Jis visada turi atitikti „Pod“ etiketes, nes jį Deployment naudoja podiams sekti.

Tarkime, kad atlikote teisingus pakeitimus. Kaip juos patikrinti?

Galite patikrinti ankšties etiketę naudodami šią komandą:

kubectl get pods --show-labels

Arba, jei ankštys priklauso kelioms programoms:

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

kur any-name=my-app yra etiketė any-name: my-app.

Ar liko kokių nors sunkumų?

Galite prisijungti prie lizdo! Norėdami tai padaryti, turite naudoti komandą port-forward kubectl. Tai leidžia prisijungti prie paslaugos ir patikrinti ryšį.

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

Здесь:

  • service/<service name> - paslaugos pavadinimas; mūsų atveju taip yra my-service;
  • 3000 yra prievadas, kurį reikia atidaryti kompiuteryje;
  • 80 - lauke nurodytas prievadas port paslaugą.

Jei ryšys buvo užmegztas, nustatymai yra teisingi.

Jei nepavyksta prisijungti, kilo problemų dėl etikečių arba nesutampa prievadai.

Paslaugos ir įėjimo ryšys

Kitas žingsnis suteikiant prieigą prie programos yra „Ingress“ nustatymas. „Ingress“ turi žinoti, kaip rasti paslaugą, tada rasti rinkinius ir nukreipti srautą į juos. Ingress suranda reikiamą paslaugą pagal pavadinimą ir atidarytą prievadą.

Ingress and Service aprašyme turi atitikti du parametrai:

  1. servicePort in Ingress turi atitikti parametrą port tarnyboje;
  2. serviceName Ingress turi atitikti lauką name tarnyboje.

Šioje diagramoje apibendrinamos prievadų jungtys:

1) Kaip jau žinote, tarnyba klauso tam tikro port:

Vaizdinis „Kubernetes“ trikčių šalinimo vadovas

2) Ingress turi parametrą, vadinamą servicePort:

Vaizdinis „Kubernetes“ trikčių šalinimo vadovas

3) Šis parametras (servicePort) visada turi atitikti port Paslaugos apibrėžime:

Vaizdinis „Kubernetes“ trikčių šalinimo vadovas

4) Jei Paslaugoje nurodytas 80 prievadas, tai būtina servicePort taip pat buvo lygus 80:

Vaizdinis „Kubernetes“ trikčių šalinimo vadovas

Praktiškai turite atkreipti dėmesį į šias eilutes:

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

Kaip patikrinti, ar veikia Ingress?

Galite naudoti metodą su kubectl port-forward, bet vietoj paslaugos reikia prisijungti prie Ingress valdiklio.

Pirmiausia turite sužinoti „pod“ pavadinimą naudodami „Ingress“ valdiklį:

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

Raskite įvedimo bloką (jis gali būti kitoje vardų erdvėje) ir paleiskite komandą describeNorėdami sužinoti prievadų numerius:

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

Galiausiai prijunkite prie lizdo:

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

Dabar kiekvieną kartą, kai siunčiate užklausą į savo kompiuterio 3000 prievadą, ji bus persiųsta į 80 prievadą su Ingress valdikliu. Eidamas į http://localhost:3000, turėtumėte matyti programos sugeneruotą puslapį.

Uostų santrauka

Dar kartą prisiminkime, kurie prievadai ir etiketės turi atitikti:

  1. Paslaugos apibrėžimo parinkiklis turi atitikti ankšties etiketę;
  2. targetPort apibrėžime Paslauga turi atitikti containerPort konteineris ankšties viduje;
  3. port apibrėžime Paslauga gali būti bet kas. Skirtingos tarnybos gali naudoti tą patį prievadą, nes turi skirtingus IP adresus;
  4. servicePort Įėjimas turi atitikti port Paslaugos apibrėžime;
  5. Paslaugos pavadinimas turi atitikti lauką serviceName Ingresse.

Deja, nepakanka žinoti, kaip tinkamai struktūrizuoti YAML konfigūraciją.

Kas nutinka, kai viskas klostosi ne taip?

Ankštis gali neįsijungti arba sugesti.

3 žingsniai, kaip diagnozuoti programos problemas „Kubernetes“.

Prieš pradėdami derinti diegimą, turite gerai suprasti, kaip veikia „Kubernetes“.

Kadangi kiekvieną K8s atsisiųstą programą sudaro trys komponentai, jie turėtų būti derinami tam tikra tvarka, pradedant nuo pat apačios.

  1. Pirmiausia turite įsitikinti, kad ankštys veikia, tada...
  2. Patikrinkite, ar paslauga tiekia srautą į ankštis, tada...
  3. Patikrinkite, ar „Ingress“ sukonfigūruotas teisingai.

Vizualus vaizdavimas:

1) Turėtumėte pradėti ieškoti problemų nuo pat apačios. Pirmiausia patikrinkite, ar ankštys turi būsenas Ready и Running:

Vaizdinis „Kubernetes“ trikčių šalinimo vadovas

2) Jei ankštys yra paruoštos (Ready), turėtumėte išsiaiškinti, ar paslauga paskirsto srautą tarp blokų:

Vaizdinis „Kubernetes“ trikčių šalinimo vadovas

3) Galiausiai turite išanalizuoti ryšį tarp paslaugos ir „Ingress“:

Vaizdinis „Kubernetes“ trikčių šalinimo vadovas

1. Ankščių diagnostika

Daugeliu atvejų problema yra susijusi su ankštimi. Įsitikinkite, kad ankštys nurodytos kaip Ready и Running. Tai galite patikrinti naudodami komandą:

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

Aukščiau pateiktoje komandos išvestyje paskutinis blokas yra nurodytas kaip Running и Readytačiau kitų dviejų atveju taip nėra.

Kaip suprasti, kas nutiko?

Yra keturios naudingos ankščių diagnozavimo komandos:

  1. kubectl logs <имя pod'а> leidžia ištraukti rąstus iš konteinerių ankštyje;
  2. kubectl describe pod <имя pod'а> leidžia peržiūrėti įvykių, susijusių su podeliu, sąrašą;
  3. kubectl get pod <имя pod'а> leidžia gauti Kubernetes saugomos podėlio YAML konfigūraciją;
  4. kubectl exec -ti <имя pod'а> bash leidžia paleisti interaktyvų komandų apvalkalą viename iš pod konteinerių

Kurį pasirinkti?

Faktas yra tas, kad nėra universalios komandos. Reikėtų naudoti jų derinį.

Tipiškos ankšties problemos

Yra du pagrindiniai pod klaidų tipai: paleidimo klaidos ir vykdymo klaidos.

Paleidimo klaidos:

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

Vykdymo laiko klaidos:

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

Kai kurios klaidos yra dažnesnės nei kitos. Štai keletas dažniausiai pasitaikančių klaidų ir kaip jas ištaisyti.

ImagePullBackOff

Ši klaida atsiranda, kai „Kubernetes“ negali gauti vieno iš talpyklos konteinerių vaizdo. Štai trys dažniausiai pasitaikančios priežastys:

  1. Vaizdo pavadinimas neteisingas – pavyzdžiui, jame suklydote arba vaizdas neegzistuoja;
  2. Vaizdui buvo nurodyta neegzistuojanti žyma;
  3. Vaizdas saugomas privačiame registre ir Kubernetes neturi leidimo prie jo prieiti.

Pirmąsias dvi priežastis lengva pašalinti – tiesiog pataisykite vaizdo pavadinimą ir žymą. Pastarojo atveju turite įvesti slaptus uždarojo registro kredencialus ir pridėti nuorodas į jį ankštyse. Kubernetes dokumentacijoje yra pavyzdys kaip tai galima padaryti.

„Crash Loop Back Off“.

Kubenetes meta klaidą CrashLoopBackOff, jei konteineris negali paleisti. Paprastai tai atsitinka, kai:

  1. Programoje yra klaida, kuri neleidžia jai paleisti;
  2. Konteineris sukonfigūruotas neteisingai;
  3. Gyvumo testas per daug kartų nepavyko.

Turite pabandyti patekti į rąstus iš konteinerio, kad išsiaiškintumėte jo gedimo priežastį. Jei sunku pasiekti žurnalus, nes konteineris per greitai paleidžiamas iš naujo, galite naudoti šią komandą:

kubectl logs <pod-name> --previous

Rodomi klaidų pranešimai iš ankstesnio konteinerio įsikūnijimo.

RunContainerError

Ši klaida įvyksta, kai konteinerio nepavyksta paleisti. Tai atitinka momentą prieš programos paleidimą. Paprastai tai sukelia neteisingi nustatymai, pavyzdžiui:

  • bandymas prijungti neegzistuojantį tomą, pvz., ConfigMap arba Secrets;
  • bandymas prijungti tik skaitomą tomą kaip skaitymą ir rašymą.

Komanda puikiai tinka tokioms klaidoms analizuoti kubectl describe pod <pod-name>.

Ankštys yra laukiančios būsenos

Sukūrus ankštį, ji lieka tokioje būsenoje Pending.

Kodėl tai vyksta?

Štai galimos priežastys (manau, kad planuoklis veikia gerai):

  1. Klasteris neturi pakankamai išteklių, pvz., apdorojimo galios ir atminties, kad galėtų paleisti bloką.
  2. Objektas įdiegtas atitinkamoje vardų erdvėje ResourceQuota o sukūrus grupę vardų erdvė viršys kvotą.
  3. Pod yra susietas su Laukiama PersistentVolumeClaim.

Tokiu atveju rekomenduojama naudoti komandą kubectl describe ir patikrinkite skyrių Events:

kubectl describe pod <pod name>

Esant klaidų, susijusių su ResourceQuotas, rekomenduojama peržiūrėti klasterio žurnalus naudojant komandą

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

Ankštys nėra paruoštos

Jei ankštis nurodyta kaip Running, bet nėra būsenos Ready, reiškia jo parengties patikrinimą (parengties zondas) nepavyksta.

Kai taip nutinka, podas neprisijungia prie paslaugos ir į jį neplūsta srautas. Parengties testo nesėkmę sukelia programos problemos. Tokiu atveju, norėdami rasti klaidą, turite išanalizuoti skyrių Events komandos išvestyje kubectl describe.

2. Serviso diagnostika

Jei ankštys išvardytos kaip Running и Ready, bet vis tiek nėra atsakymo iš programos, turėtumėte patikrinti paslaugos nustatymus.

Paslaugos yra atsakingos už srauto nukreipimą į ankštis, atsižvelgiant į jų etiketes. Todėl pirmas dalykas, kurį turite padaryti, yra patikrinti, kiek ankščių veikia su paslauga. Norėdami tai padaryti, galite patikrinti paslaugos galinius taškus:

kubectl describe service <service-name> | grep Endpoints

Galutinis taškas yra formos verčių pora <IP-адрес:порт>, ir išvestyje turi būti bent viena tokia pora (tai yra, bent viena grupė veikia su paslauga).

Jei skyrius Endpoins tuščias, galimi du variantai:

  1. nėra ankšties su teisinga etikete (patarimas: patikrinkite, ar vardų sritis pasirinkta teisingai);
  2. Parinkiklio paslaugų etiketėse yra klaida.

Jei matote galinių taškų sąrašą, bet vis tiek negalite pasiekti programos, įvyko klaida targetPort paslaugos aprašyme.

Kaip patikrinti paslaugos funkcionalumą?

Nepriklausomai nuo paslaugos tipo, galite naudoti komandą kubectl port-forward prisijungti prie jo:

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

Здесь:

  • <service-name> - paslaugos pavadinimas;
  • 3000 yra prievadas, kurį atidarote kompiuteryje;
  • 80 – prievadas aptarnavimo pusėje.

3. Patekimo diagnostika

Jei perskaitėte iki šiol, tada:

  • ankštys išvardytos kaip Running и Ready;
  • paslauga sėkmingai paskirsto srautą tarp blokų.

Tačiau vis tiek negalite pasiekti programos.

Tai reiškia, kad Ingress valdiklis greičiausiai nėra tinkamai sukonfigūruotas. Kadangi Ingress valdiklis yra trečiosios šalies komponentas klasteryje, yra skirtingi derinimo metodai, atsižvelgiant į jo tipą.

Tačiau prieš naudodami specialius įrankius Ingress konfigūravimui galite padaryti ką nors labai paprasto. Ingress naudojimas serviceName и servicePort prisijungti prie paslaugos. Turite patikrinti, ar jie tinkamai sukonfigūruoti. Tai galite padaryti naudodami komandą:

kubectl describe ingress <ingress-name>

Jei stulpelis Backend tuščias, yra didelė konfigūracijos klaidos tikimybė. Jei užpakalinės programos yra, bet programa vis tiek nepasiekiama, problema gali būti susijusi su:

  • Įėjimas prieinamumo parametrai iš viešojo interneto;
  • klasterio pasiekiamumo nustatymus iš viešojo interneto.

Galite nustatyti infrastruktūros problemas tiesiogiai prisijungę prie „Ingress pod“. Norėdami tai padaryti, pirmiausia suraskite įėjimo valdiklio bloką (jis gali būti kitoje vardų srityje):

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

Naudokite komandą describeprievadui nustatyti:

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

Galiausiai prijunkite prie lizdo:

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

Dabar visos užklausos dėl kompiuterio 3000 prievado bus nukreiptos į 80 prievadą.

Ar tai dabar veikia?

  • Jei taip, problema susijusi su infrastruktūra. Būtina tiksliai išsiaiškinti, kaip srautas nukreipiamas į klasterį.
  • Jei ne, tada problema yra Ingress valdiklyje.

Jei negalite priversti Ingress valdiklio veikti, turėsite jį derinti.

Yra daugybė Ingress valdiklių rūšių. Populiariausi yra Nginx, HAProxy, Traefik ir kt. (daugiau informacijos apie esamus sprendimus žr mūsų apžvalga - apytiksliai vertimas.) Turėtumėte žiūrėti trikčių šalinimo vadovą atitinkamoje valdiklio dokumentacijoje. Nes Ingress Nginx yra populiariausias Ingress valdiklis, į straipsnį įtraukėme keletą patarimų, kaip išspręsti su juo susijusias problemas.

Ingress Nginx valdiklio derinimas

Ingress-nginx projektas turi oficialų kubectl įskiepis. Komanda kubectl ingress-nginx gali būti naudojamas:

  • žurnalų, užpakalinių sistemų, sertifikatų ir kt. analizė;
  • jungtys su Ingress;
  • studijuoja dabartinę konfigūraciją.

Šios trys komandos padės tai padaryti:

  • kubectl ingress-nginx lint - patikrinimai nginx.conf;
  • kubectl ingress-nginx backend - tyrinėja užpakalinę dalį (panašiai kaip kubectl describe ingress <ingress-name>);
  • kubectl ingress-nginx logs — tikrina žurnalus.

Atminkite, kad kai kuriais atvejais gali tekti nurodyti teisingą Ingress valdiklio vardų sritį naudojant vėliavėlę --namespace <name>.

Santrauka

„Kubernetes“ trikčių šalinimas gali būti sudėtingas, jei nežinote, nuo ko pradėti. Visada turėtumėte spręsti problemą iš apačios į viršų: pradėkite nuo ankščių, o tada pereikite prie paslaugos ir „Ingress“. Šiame straipsnyje aprašyti derinimo būdai gali būti taikomi kitiems objektams, pavyzdžiui:

  • tuščiosios eigos darbai ir CronJobs;
  • StatefulSets ir DaemonSets.

Reiškiu savo dėkingumą Gergely Risko, Danielis Veibelis и Charlesas Christyraj už vertingus komentarus ir papildymus.

PS iš vertėjo

Taip pat skaitykite mūsų tinklaraštyje:

Šaltinis: www.habr.com

Добавить комментарий