Vizualni vodič za rješavanje problema s Kubernetesom

Bilješka. prev.: Ovaj je članak dio materijala projekta objavljenih u javnoj domeni learnk8s, obuka tvrtki i pojedinačnih administratora za rad s Kubernetesom. U njemu Daniele Polenčić, voditelj projekta, dijeli vizualne upute o tome koje korake poduzeti u slučaju općih problema s aplikacijama koje rade na K8s klasteru.

Vizualni vodič za rješavanje problema s Kubernetesom

TL;DR: ovdje je dijagram koji će vam pomoći u otklanjanju pogrešaka implementacije u Kubernetesu:

Vizualni vodič za rješavanje problema s Kubernetesom

Dijagram toka za pronalaženje i popravljanje grešaka u klasteru. Izvornik (na engleskom) dostupan je na PDF и kao slika.

Prilikom postavljanja aplikacije na Kubernetes, obično postoje tri komponente koje trebate definirati:

  • razvoj - ovo je neka vrsta recepta za stvaranje kopija aplikacije, nazvanih pods;
  • Servis — unutarnji balanser opterećenja koji raspodjeljuje promet između grupa;
  • Ulaz — opis načina na koji će promet doći iz vanjskog svijeta do usluge.

Evo kratkog grafičkog sažetka:

1) U Kubernetesu aplikacije primaju promet iz vanjskog svijeta kroz dva sloja balansera opterećenja: unutarnji i vanjski.

Vizualni vodič za rješavanje problema s Kubernetesom

2) Unutarnji balanser zove se usluga, vanjski se zove ulaz.

Vizualni vodič za rješavanje problema s Kubernetesom

3) Implementacija stvara podove i nadzire ih (ne stvaraju se ručno).

Vizualni vodič za rješavanje problema s Kubernetesom

Recimo da želite implementirati jednostavnu aplikaciju a la Pozdrav svijete. YAML konfiguracija za njega će izgledati ovako:

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

Definicija je prilično dugačka i lako se zbuniti oko međusobnog odnosa komponenti.

Na primjer:

  • Kada biste trebali koristiti priključak 80, a kada 8080?
  • Trebam li stvoriti novi priključak za svaku uslugu kako ne bi došlo do sukoba?
  • Jesu li nazivi etiketa važni? Trebaju li svugdje biti isti?

Prije nego što se usredotočimo na otklanjanje pogrešaka, sjetimo se kako su tri komponente povezane jedna s drugom. Počnimo s implementacijom i servisom.

Odnos između implementacije i usluge

Iznenadit ćete se, ali implementacija i usluga nisu ni na koji način povezani. Umjesto toga, Usluga usmjerava izravno na Pods, zaobilazeći Deployment.

Stoga nas zanima kako su Podovi i Usluge međusobno povezani. Tri stvari koje treba zapamtiti:

  1. Selektor (selector) za uslugu mora odgovarati barem jednoj pod oznaci.
  2. targetPort mora odgovarati sa containerPort spremnik unutar Pod.
  3. port Usluga može biti bilo što. Različite usluge mogu koristiti isti port jer imaju različite IP adrese.

Sljedeći dijagram predstavlja sve gore navedeno u grafičkom obliku:

1) Zamislite da usluga usmjerava promet na određenu pod:

Vizualni vodič za rješavanje problema s Kubernetesom

2) Kada kreirate pod, morate navesti containerPort za svaki spremnik u mahunama:

Vizualni vodič za rješavanje problema s Kubernetesom

3) Prilikom kreiranja usluge morate navesti port и targetPort. Ali koji se koristi za spajanje na spremnik?

Vizualni vodič za rješavanje problema s Kubernetesom

4) Putem targetPort. Mora odgovarati containerPort.

Vizualni vodič za rješavanje problema s Kubernetesom

5) Recimo da je u spremniku otvoren port 3000. Zatim vrijednost targetPort treba biti isti.

Vizualni vodič za rješavanje problema s Kubernetesom

U YAML datoteci, oznake i ports / targetPort moraju odgovarati:

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

Što je s etiketom track: canary na vrhu odjeljka Implementacija? Treba li odgovarati?

Ova je oznaka specifična za implementaciju i usluga je ne koristi za usmjeravanje prometa. Drugim riječima, može se ukloniti ili mu se može dodijeliti druga vrijednost.

Što je sa izbornikom matchLabels?

Uvijek mora odgovarati oznakama Poda, budući da ga Deployment koristi za praćenje mahuna.

Pretpostavimo da ste ispravno uredili. Kako ih provjeriti?

Oznaku mahuna možete provjeriti sljedećom naredbom:

kubectl get pods --show-labels

Ili, ako mahune pripadaju nekoliko aplikacija:

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

gdje any-name=my-app je oznaka any-name: my-app.

Jesu li ostale poteškoće?

Možete se spojiti na pod! Da biste to učinili, morate koristiti naredbu port-forward u kubectl. Omogućuje vam povezivanje s uslugom i provjeru veze.

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

ovdje:

  • service/<service name> — naziv usluge; u našem slučaju jest my-service;
  • 3000 je port koji treba otvoriti na računalu;
  • 80 - port naveden u polju port servis.

Ako je veza uspostavljena, tada su postavke ispravne.

Ako veza ne uspije, postoji problem s oznakama ili se priključci ne podudaraju.

Odnos između usluge i ulaza

Sljedeći korak u pružanju pristupa aplikaciji uključuje postavljanje Ingressa. Ingress treba znati kako pronaći uslugu, zatim pronaći podove i usmjeriti promet na njih. Ingress pronalazi potrebnu uslugu prema nazivu i otvorenom portu.

U opisu ulaza i usluge moraju se podudarati dva parametra:

  1. servicePort in Ingress mora odgovarati parametru port u službi;
  2. serviceName in Ingress mora odgovarati polju name u službi.

Sljedeći dijagram sažima priključke priključaka:

1) Kao što već znate, usluga sluša određene port:

Vizualni vodič za rješavanje problema s Kubernetesom

2) Ingress ima parametar tzv servicePort:

Vizualni vodič za rješavanje problema s Kubernetesom

3) Ovaj parametar (servicePort) moraju uvijek odgovarati port u definiciji usluge:

Vizualni vodič za rješavanje problema s Kubernetesom

4) Ako je port 80 naveden u servisu, tada je potrebno da servicePort također je bio jednak 80:

Vizualni vodič za rješavanje problema s Kubernetesom

U praksi morate obratiti pozornost na sljedeće retke:

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

Kako provjeriti radi li Ingress?

Možete koristiti metodu sa kubectl port-forward, no umjesto usluge potrebno je spojiti se na Ingress kontroler.

Prvo morate saznati naziv mahune s Ingress kontrolerom:

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

Pronađite Ingress pod (može biti u drugom prostoru naziva) i pokrenite naredbu describeda saznate brojeve priključaka:

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

Na kraju se povežite s modulom:

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

Sada svaki put kada pošaljete zahtjev na port 3000 na vašem računalu, on će biti proslijeđen na port 80 modula s Ingress kontrolerom. Odlaskom na http://localhost:3000, trebali biste vidjeti stranicu koju je generirala aplikacija.

Sažetak luka

Prisjetimo se još jednom koji portovi i oznake moraju odgovarati:

  1. Selektor u definiciji usluge mora odgovarati oznaci modula;
  2. targetPort u definiciji Usluga mora odgovarati containerPort spremnik unutar mahune;
  3. port u definiciji Usluga može biti bilo što. Različite usluge mogu koristiti isti port jer imaju različite IP adrese;
  4. servicePort Ulaz mora odgovarati port u definiciji usluge;
  5. Naziv usluge mora odgovarati polju serviceName u Ingressu.

Nažalost, nije dovoljno znati pravilno strukturirati YAML konfiguraciju.

Što se događa kada stvari krenu po zlu?

Podloga se možda neće pokrenuti ili se može srušiti.

3 koraka za dijagnosticiranje problema s aplikacijom u Kubernetesu

Prije nego počnete otklanjati pogreške svoje implementacije, morate dobro razumjeti kako Kubernetes funkcionira.

Budući da svaka aplikacija preuzeta u K8s ima tri komponente, treba ih otklanjati određenim redoslijedom, počevši od samog dna.

  1. Najprije se morate uvjeriti da kapsule rade, a zatim...
  2. Provjerite opskrbljuje li usluga promet jedinicama, a zatim...
  3. Provjerite je li Ingress ispravno konfiguriran.

Vizualni prikaz:

1) Trebali biste početi tražiti probleme od samog dna. Prvo provjerite imaju li mahune statuse Ready и Running:

Vizualni vodič za rješavanje problema s Kubernetesom

2) Ako su mahune spremne (Ready), trebali biste saznati distribuira li usluga promet između grupa:

Vizualni vodič za rješavanje problema s Kubernetesom

3) Konačno, trebate analizirati vezu između usluge i Ingressa:

Vizualni vodič za rješavanje problema s Kubernetesom

1. Dijagnostika mahuna

U većini slučajeva problem je povezan s mahunom. Provjerite jesu li mahune navedene kao Ready и Running. To možete provjeriti pomoću naredbe:

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

U gornjem izlazu naredbe, posljednja mahuna navedena je kao Running и Ready, međutim, to nije slučaj za druga dva.

Kako razumjeti što je pošlo po zlu?

Postoje četiri korisne naredbe za dijagnosticiranje mahuna:

  1. kubectl logs <имя pod'а> omogućuje izvlačenje trupaca iz spremnika u mahuni;
  2. kubectl describe pod <имя pod'а> omogućuje pregled popisa događaja povezanih s modulom;
  3. kubectl get pod <имя pod'а> omogućuje vam da dobijete YAML konfiguraciju modula pohranjenog u Kubernetesu;
  4. kubectl exec -ti <имя pod'а> bash omogućuje pokretanje interaktivne naredbene ljuske u jednom od kontejnera pod-a

Koju odabrati?

Činjenica je da ne postoji univerzalna zapovijed. Treba koristiti kombinaciju ovih.

Tipični problemi s mahunama

Postoje dvije glavne vrste pogrešaka pod: pogreške pri pokretanju i pogreške tijekom izvođenja.

Pogreške pri pokretanju:

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

Pogreške u izvođenju:

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

Neke su pogreške češće od drugih. Ovdje su neke od najčešćih pogrešaka i kako ih popraviti.

ImagePullBackOff

Ova se pogreška pojavljuje kada Kubernetes ne može dobiti sliku za jedan od kontejnera pod-a. Evo tri najčešća razloga za to:

  1. Naziv slike nije točan - na primjer, pogriješili ste u njemu ili slika ne postoji;
  2. Za sliku je navedena nepostojeća oznaka;
  3. Slika je pohranjena u privatnom registru i Kubernetes nema dozvolu za pristup.

Prva dva razloga je lako ukloniti - samo ispravite naziv slike i oznaku. U slučaju potonjeg, trebate unijeti vjerodajnice za zatvoreni registar u Secret i dodati poveznice na njega u pods. U Kubernetes dokumentaciji postoji primjer kako se to može učiniti.

Crash Loop Back Off

Kubenetes javlja pogrešku CrashLoopBackOff, ako se spremnik ne može pokrenuti. To se obično događa kada:

  1. Postoji greška u aplikaciji koja sprječava njeno pokretanje;
  2. kontejner neispravno konfiguriran;
  3. Test živosti pao je previše puta.

Morate pokušati doći do zapisa iz spremnika kako biste saznali razlog njegovog kvara. Ako je teško pristupiti zapisima jer se spremnik prebrzo ponovno pokreće, možete koristiti sljedeću naredbu:

kubectl logs <pod-name> --previous

Prikazuje poruke o pogreškama iz prethodne inkarnacije spremnika.

RunContainerError

Ova se pogreška javlja kada se spremnik ne uspije pokrenuti. Odgovara trenutku prije pokretanja aplikacije. Obično je uzrokovano netočnim postavkama, na primjer:

  • pokušaj montiranja nepostojećeg volumena kao što je ConfigMap ili Secrets;
  • pokušaj montiranja volumena samo za čitanje kao čitanje-pisanje.

Tim je prikladan za analizu takvih pogrešaka kubectl describe pod <pod-name>.

Mahune su u stanju čekanja

Jednom stvorena mahuna ostaje u stanju Pending.

Zašto se to događa?

Evo mogućih razloga (pretpostavljam da planer radi dobro):

  1. Klaster nema dovoljno resursa, poput procesorske snage i memorije, za pokretanje modula.
  2. Objekt je instaliran u odgovarajućem imenskom prostoru ResourceQuota a stvaranje pod će uzrokovati da imenski prostor pređe kvotu.
  3. Pod je vezan za Na čekanju PersistentVolumeClaim.

U ovom slučaju preporuča se koristiti naredbu kubectl describe i provjerite odjeljak Events:

kubectl describe pod <pod name>

U slučaju grešaka vezanih uz ResourceQuotas, preporučuje se pregled zapisnika klastera pomoću naredbe

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

Mahune nisu spremne

Ako je mahuna navedena kao Running, ali nije u stanju Ready, znači provjeriti njegovu spremnost (sonda spremnosti) ne uspijeva.

Kada se to dogodi, modul se ne povezuje s uslugom i prema njemu nema prometa. Neuspjeh testa spremnosti uzrokovan je problemima u aplikaciji. U ovom slučaju, da biste pronašli pogrešku, morate analizirati odjeljak Events u izlazu naredbe kubectl describe.

2. Servisna dijagnostika

Ako su mahune navedene kao Running и Ready, ali još uvijek nema odgovora aplikacije, trebali biste provjeriti postavke usluge.

Usluge su odgovorne za usmjeravanje prometa prema podovima ovisno o njihovim oznakama. Stoga prvo što trebate učiniti je provjeriti koliko podova radi s uslugom. Da biste to učinili, možete provjeriti krajnje točke u usluzi:

kubectl describe service <service-name> | grep Endpoints

Krajnja točka je par vrijednosti obrasca <IP-адрес:порт>, a barem jedan takav par mora biti prisutan u izlazu (odnosno, barem jedan modul radi s uslugom).

Ako odjeljak Endpoins prazno, moguće su dvije opcije:

  1. nema mahuna s ispravnom oznakom (savjet: provjerite je li prostor imena ispravno odabran);
  2. Postoji pogreška u servisnim oznakama u selektoru.

Ako vidite popis krajnjih točaka, ali i dalje ne možete pristupiti aplikaciji, tada je vjerojatni krivac greška u targetPort u opisu usluge.

Kako provjeriti funkcionalnost usluge?

Bez obzira na vrstu usluge, možete koristiti naredbu kubectl port-forward za povezivanje s njim:

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

ovdje:

  • <service-name> — naziv usluge;
  • 3000 je port koji otvarate na računalu;
  • 80 - priključak na servisnoj strani.

3. Ingress dijagnostika

Ako ste pročitali dovde, onda:

  • mahune su navedene kao Running и Ready;
  • usluga uspješno distribuira promet među pods.

Međutim, i dalje ne možete pristupiti aplikaciji.

To znači da Ingress kontroler najvjerojatnije nije ispravno konfiguriran. Budući da je Ingress kontroler komponenta treće strane u klasteru, postoje različite metode otklanjanja pogrešaka ovisno o njegovoj vrsti.

Ali prije nego što pribjegnete korištenju posebnih alata za konfiguriranje Ingressa, možete učiniti nešto vrlo jednostavno. Ingress koristi serviceName и servicePort za spajanje na uslugu. Morate provjeriti jesu li ispravno konfigurirani. To možete učiniti pomoću naredbe:

kubectl describe ingress <ingress-name>

Ako stupac Backend prazno, postoji velika vjerojatnost konfiguracijske pogreške. Ako su pozadine postavljene, ali aplikacija i dalje nije dostupna, problem može biti povezan s:

  • Ingress postavke pristupačnosti s javnog interneta;
  • postavke pristupačnosti klastera s javnog interneta.

Možete identificirati probleme s infrastrukturom izravnim povezivanjem s Ingress modulom. Da biste to učinili, prvo pronađite modul Ingress Controller (može biti u drugom prostoru imena):

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

Koristite naredbu describeza postavljanje porta:

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

Na kraju se povežite s modulom:

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

Sada će svi zahtjevi prema portu 3000 na računalu biti preusmjereni na port 80 modula.

Radi li sada?

  • Ako da, onda je problem u infrastrukturi. Potrebno je točno saznati kako se promet usmjerava prema klasteru.
  • Ako nije, onda je problem u Ingress kontroleru.

Ako ne možete natjerati Ingress kontroler da radi, morat ćete ga otkloniti.

Postoji mnogo varijanti Ingress kontrolera. Najpopularniji su Nginx, HAProxy, Traefik itd. (za više informacija o postojećim rješenjima pogledajte naša recenzija - cca. prev.) Trebali biste pogledati vodič za rješavanje problema u odgovarajućoj dokumentaciji kontrolera. Jer Ingress Nginx je najpopularniji Ingress kontroler, u članak smo uključili nekoliko savjeta za rješavanje problema povezanih s njim.

Otklanjanje pogrešaka Ingress Nginx kontrolera

Projekt Ingress-nginx ima službenog dodatak za kubectl. Tim kubectl ingress-nginx može se koristiti za:

  • analiza dnevnika, pozadina, certifikata itd.;
  • veze s Ingressom;
  • proučavanje trenutne konfiguracije.

U tome će vam pomoći sljedeće tri naredbe:

  • kubectl ingress-nginx lint - provjere nginx.conf;
  • kubectl ingress-nginx backend — istražuje pozadinu (slično kao kubectl describe ingress <ingress-name>);
  • kubectl ingress-nginx logs — provjerava dnevnike.

Imajte na umu da ćete u nekim slučajevima možda trebati navesti točan imenski prostor za Ingress kontroler pomoću oznake --namespace <name>.

Rezime

Rješavanje problema s Kubernetesom može biti izazovno ako ne znate odakle započeti. Uvijek biste trebali pristupiti problemu odozdo prema gore: početi s podovima, a zatim prijeći na uslugu i Ingress. Tehnike otklanjanja pogrešaka opisane u ovom članku mogu se primijeniti na druge objekte, kao što su:

  • neaktivni poslovi i cronposlovi;
  • StatefulSets i DaemonSets.

Izražavam svoju zahvalnost Gergely Risko, Daniel Weibel и Charles Christyraj za vrijedne komentare i dopune.

PS od prevoditelja

Pročitajte i na našem blogu:

Izvor: www.habr.com

Dodajte komentar