Vizuelni vodič za rešavanje problema u Kubernetesu
Bilješka. transl.: Ovaj članak je dio projektnih materijala objavljenih u javnom vlasništvu learnk8s, kompanije za obuku i individualne administratore za rad sa Kubernetesom. U njemu Daniele Polenčić, projekt menadžer, dijeli vizualne upute o tome koje korake poduzeti u slučaju općih problema s aplikacijama koje rade na klasteru K8s.
TL;DR: evo dijagrama koji će vam pomoći da otklonite greške pri postavljanju u Kubernetes:
Dijagram toka za pronalaženje i popravljanje grešaka u klasteru. Original (na engleskom) je dostupan na adresi PDF и kao slika.
Kada postavljate aplikaciju na Kubernetes, obično postoje tri komponente koje trebate definirati:
razvoj - ovo je vrsta recepta za kreiranje kopija aplikacije, koja se zove pods;
usluga — interni balansator opterećenja koji distribuira promet među podovima;
Ulaz — opis načina na koji će saobraćaj stići iz vanjskog svijeta do Servisa.
Evo kratkog grafičkog sažetka:
1) U Kubernetesu, aplikacije primaju promet iz vanjskog svijeta kroz dva sloja balansera opterećenja: interni i eksterni.
2) Interni balanser se zove Service, eksterni se zove Ingress.
3) Deployment kreira podove i nadgleda ih (ne kreiraju se ručno).
Recimo da želite da implementirate jednostavnu aplikaciju a la Hello World. YAML konfiguracija za to će izgledati ovako:
Definicija je prilično duga i lako se zbuniti oko toga kako su komponente međusobno povezane.
Na primjer:
Kada treba koristiti port 80, a kada 8080?
Da li trebam kreirati novi port za svaku uslugu kako se ne bi sukobljavali?
Da li su nazivi etiketa bitni? Da li bi svuda trebalo da budu isti?
Prije nego što se fokusiramo na otklanjanje grešaka, sjetimo se kako su tri komponente povezane jedna s drugom. Počnimo sa 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, Service upućuje direktno na Podove, zaobilazeći Deployment.
Stoga nas zanima kako su podovi i usluge međusobno povezani. Tri stvari koje treba zapamtiti:
Selektor (selector) za uslugu mora odgovarati barem jednoj pod naljepnici.
targetPort mora odgovarati containerPort kontejner unutar Pod.
port Usluga može biti bilo šta. 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đeni pod:
2) Kada kreirate pod, morate navesti containerPort za svaki kontejner u mahunama:
3) Prilikom kreiranja usluge morate navesti port и targetPort. Ali koji se koristi za povezivanje s kontejnerom?
4) Via targetPort. Mora da se poklapa containerPort.
5) Recimo da je u kontejneru otvoren port 3000. Zatim vrijednost targetPort trebao bi biti isti.
U YAML datoteci, oznake i ports / targetPort mora odgovarati:
Šta je sa etiketom track: canary na vrhu odjeljka Deployment? Treba li se podudarati?
Ova oznaka je specifična za implementaciju i usluga je ne koristi za usmjeravanje prometa. Drugim riječima, može se ukloniti ili dodijeliti drugačiju vrijednost.
Šta je sa selektorom matchLabels?
Uvijek mora odgovarati naljepnicama Poda, budući da ga Deployment koristi za praćenje podova.
Pretpostavimo da ste napravili ispravne izmjene. Kako ih provjeriti?
Oznaku pod 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
Gde any-name=my-app je oznaka any-name: my-app.
Da li su ostale poteškoće?
Možete se povezati na pod! Da biste to učinili, trebate koristiti naredbu port-forward u kubectl. Omogućava vam da se povežete na uslugu i provjerite vezu.
service/<service name> — naziv usluge; u našem slučaju jeste my-service;
3000 je port koji treba otvoriti na računaru;
80 - port naveden u polju port usluga.
Ako je veza uspostavljena, onda su postavke ispravne.
Ako veza ne uspije, postoji problem s oznakama ili se portovi ne poklapaju.
Odnos između usluge i ingressa
Sljedeći korak u pružanju pristupa aplikaciji uključuje postavljanje Ingressa. Ingress mora znati kako pronaći uslugu, zatim pronaći podove i usmjeriti promet na njih. Ingress pronalazi potrebnu uslugu po imenu i otvorenom portu.
U opisu ulaza i usluge dva parametra moraju se podudarati:
servicePort in Ingress mora odgovarati parametru port u službi;
serviceName in Ingress mora odgovarati polju name u servisu.
Sljedeći dijagram sumira veze portova:
1) Kao što već znate, Servis sluša određene port:
2) Ingress ima parametar koji se zove servicePort:
3) Ovaj parametar (servicePort) mora uvijek odgovarati port u definiciji usluge:
4) Ako je port 80 naveden u Servisu, onda je to neophodno servicePort je takođe bilo jednako 80:
U praksi morate obratiti pažnju na sljedeće redove:
Sada svaki put kada pošaljete zahtjev na port 3000 na vašem računaru, on će biti proslijeđen na port 80 pod sa Ingress kontrolerom. Odlaskom na http://localhost:3000, trebali biste vidjeti stranicu koju je generirala aplikacija.
Sažetak portova
Prisjetimo se još jednom koji portovi i oznake moraju odgovarati:
Selektor u definiciji usluge mora odgovarati oznaci pod;
targetPort u definiciji Usluga mora odgovarati containerPort kontejner unutar mahune;
port u definiciji Usluga može biti bilo šta. Različite usluge mogu koristiti isti port jer imaju različite IP adrese;
servicePort Ulaz se mora podudarati port u definiciji usluge;
Ime usluge mora odgovarati polju serviceName u Ingress.
Nažalost, nije dovoljno znati kako pravilno strukturirati YAML konfiguraciju.
Šta se dešava kada stvari krenu po zlu?
Pod se možda neće pokrenuti ili se može srušiti.
3 koraka za dijagnosticiranje problema sa aplikacijama u Kubernetesu
Prije nego što počnete s otklanjanjem grešaka u svojoj implementaciji, morate dobro razumjeti kako Kubernetes funkcionira.
Pošto svaka aplikacija preuzeta u K8s ima tri komponente, trebalo bi ih otkloniti određenim redoslijedom, počevši od samog dna.
Prvo morate biti sigurni da kapsule rade, a zatim...
Provjerite da li servis obezbjeđuje promet do podova, a zatim...
Provjerite je li Ingress ispravno konfiguriran.
Vizuelni prikaz:
1) Trebali biste početi tražiti probleme od samog dna. Prvo provjerite da li podovi imaju statuse Ready и Running:
2) Ako su mahune spremne (Ready), trebali biste saznati da li usluga distribuira promet između podova:
3) Na kraju, potrebno je analizirati vezu između usluge i Ingressa:
1. Dijagnostika mahuna
U većini slučajeva problem je vezan za mahunu. Provjerite jesu li mahune navedene kao Ready и Running. Ovo 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 izlazu naredbe iznad, posljednji pod je naveden kao Running и Ready, međutim, to nije slučaj za druga dva.
Kako razumjeti šta je pošlo po zlu?
Postoje četiri korisne naredbe za dijagnosticiranje podova:
kubectl logs <имя pod'а> omogućava vam da izvučete trupce iz kontejnera u pod;
kubectl describe pod <имя pod'а> omogućava vam da vidite listu događaja povezanih sa modulom;
kubectl get pod <имя pod'а> omogućava vam da dobijete YAML konfiguraciju modula pohranjenog u Kubernetes;
kubectl exec -ti <имя pod'а> bash omogućava vam da pokrenete interaktivnu komandnu ljusku u jednom od pod kontejnera
Koju da odaberete?
Činjenica je da ne postoji univerzalna komanda. Trebalo bi koristiti kombinaciju ovih.
Tipični problemi s mahunama
Postoje dvije glavne vrste grešaka modula: greške pri pokretanju i greške u toku izvođenja.
Greške pri pokretanju:
ImagePullBackoff
ImageInspectError
ErrImagePull
ErrImageNeverPull
RegistryUnavailable
InvalidImageName
Greške u toku rada:
CrashLoopBackOff
RunContainerError
KillContainerError
VerifyNonRootError
RunInitContainerError
CreatePodSandboxError
ConfigPodSandboxError
KillPodSandboxError
SetupNetworkError
TeardownNetworkError
Neke greške su češće od drugih. Evo nekih od najčešćih grešaka i kako ih popraviti.
ImagePullBackOff
Ova greška se javlja kada Kubernetes ne može dobiti sliku za jedan od pod kontejnera. Evo tri najčešća razloga za to:
Naziv slike je netačan - na primjer, pogriješili ste u njoj ili slika ne postoji;
Za sliku je specificirana nepostojeća oznaka;
Slika je pohranjena u privatnom registru i Kubernetes nema dozvolu da joj pristupi.
Prva dva razloga je lako eliminisati - samo ispravite naziv i oznaku slike. U slučaju potonjeg, potrebno je da unesete vjerodajnice za zatvoreni registar u Secret i dodate veze do njega u podovima. U Kubernetes dokumentaciji postoji primjer kako se to može uraditi.
Crash Loop Back Off
Kubenetes daje grešku CrashLoopBackOff, ako se kontejner ne može pokrenuti. Ovo se obično dešava kada:
Postoji greška u aplikaciji koja sprečava njeno pokretanje;
Morate pokušati doći do dnevnika iz kontejnera kako biste saznali razlog njegovog neuspjeha. Ako je teško pristupiti evidenciji jer se kontejner prebrzo ponovo pokreće, možete koristiti sljedeću naredbu:
kubectl logs <pod-name> --previous
Prikazuje poruke o grešci iz prethodne inkarnacije kontejnera.
RunContainerError
Ova greška se javlja kada se kontejner ne pokrene. Odgovara trenutku prije pokretanja aplikacije. Obično je uzrokovana pogrešnim postavkama, na primjer:
pokušaj montiranja nepostojećeg volumena kao što je ConfigMap ili Secrets;
pokušajte montirati volumen samo za čitanje kao čitanje-pisanje.
Tim je vrlo pogodan za analizu takvih grešaka kubectl describe pod <pod-name>.
Podovi su u stanju čekanja
Jednom kreirana, mahuna ostaje u stanju Pending.
Zašto se to događa?
Evo mogućih razloga (pretpostavljam da planer radi dobro):
Klaster nema dovoljno resursa, kao što su procesorska snaga i memorija, za pokretanje modula.
Objekt je instaliran u odgovarajućem imenskom prostoru ResourceQuota a kreiranje pod-a će uzrokovati da prostor imena pređe kvotu.
Pod je vezan za Na čekanju PersistentVolumeClaim.
U tom slučaju preporučuje se korištenje naredbe kubectl describe i provjerite odjeljak Events:
kubectl describe pod <pod name>
U slučaju grešaka u vezi sa ResourceQuotas, preporučuje se pregled evidencije klastera pomoću naredbe
kubectl get events --sort-by=.metadata.creationTimestamp
Mahune nisu spremne
Ako je pod naveden kao Running, ali nije u stanju Ready, znači provjeru njegove spremnosti (sonda spremnosti) ne uspijeva.
Kada se to dogodi, pod se ne povezuje sa uslugom i nema saobraćaja do njega. Neuspjeh testa spremnosti uzrokovan je problemima u aplikaciji. U ovom slučaju, da biste pronašli grešku, morate analizirati odjeljak Events u izlazu komande kubectl describe.
2. Servisna dijagnostika
Ako su mahune navedene kao Running и Ready, ali još uvijek nema odgovora iz aplikacije, trebali biste provjeriti postavke usluge.
Usluge su odgovorne za usmjeravanje prometa na podove ovisno o njihovim oznakama. Stoga, prva stvar koju trebate učiniti je provjeriti koliko podova radi s uslugom. Da biste to učinili, možete provjeriti krajnje tačke u servisu:
kubectl describe service <service-name> | grep Endpoints
Krajnja tačka je par vrijednosti forme <IP-адрес:порт>, a najmanje jedan takav par mora biti prisutan u izlazu (odnosno, barem jedan pod radi s uslugom).
Ako odjeljak Endpoins prazno, moguće su dvije opcije:
nema podova sa ispravnom oznakom (savet: proverite da li je imenski prostor pravilno izabran);
Došlo je do greške u servisnim oznakama u biraču.
Ako vidite listu krajnjih tačaka, ali i dalje ne možete pristupiti aplikaciji, onda je vjerovatni krivac greška u targetPort u opisu usluge.
Kako provjeriti funkcionalnost servisa?
Bez obzira na vrstu usluge, možete koristiti naredbu kubectl port-forward da se povežete na njega:
Međutim, još uvijek ne možete pristupiti aplikaciji.
To znači da Ingress kontroler najvjerovatnije nije ispravno konfiguriran. Pošto je Ingress kontroler komponenta treće strane u klasteru, postoje različite metode otklanjanja grešaka u zavisnosti od njegovog tipa.
Ali prije nego što pribjegnete korištenju posebnih alata za konfiguriranje Ingress-a, možete učiniti nešto vrlo jednostavno. Ingress uses serviceName и servicePort da se povežete na servis. Morate provjeriti jesu li ispravno konfigurirani. To možete učiniti pomoću naredbe:
kubectl describe ingress <ingress-name>
Ako kolona Backend prazno, postoji velika vjerovatnoća greške u konfiguraciji. Ako su backendovi na svom mjestu, ali aplikacija još uvijek nije dostupna, onda problem može biti povezan sa:
Postavke pristupačnosti ulaza s javnog Interneta;
postavke pristupačnosti klastera sa javnog Interneta.
Možete identifikovati probleme sa infrastrukturom tako što ćete se direktno povezati na Ingress pod. Da biste to učinili, prvo pronađite modul Ingress Controller (može biti u drugom imenskom prostoru):
Sada će svi zahtjevi za portom 3000 na računaru biti preusmjereni na port 80 modula.
Radi li sada?
Ako da, onda je problem u infrastrukturi. Potrebno je saznati kako se tačno promet usmjerava na klaster.
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. prevod) Trebali biste pogledati vodič za rješavanje problema u relevantnoj dokumentaciji kontrolera. Zbog Ingress Nginx je najpopularniji Ingress kontroler, u članak smo uključili nekoliko savjeta za rješavanje problema povezanih s njim.
Otklanjanje grešaka na Ingress Nginx kontroleru
Ingress-nginx projekat ima zvaničnika dodatak za kubectl. Tim kubectl ingress-nginx može se koristiti za:
Imajte na umu da ćete u nekim slučajevima možda morati navesti ispravan prostor imena za Ingress kontroler koristeći zastavicu --namespace <name>.
Rezime
Rješavanje problema s Kubernetesom može biti izazovno ako ne znate odakle početi. Problemu uvijek treba pristupiti odozdo prema gore: počnite sa podovima, a zatim prijeđite na uslugu i Ingress. Tehnike otklanjanja grešaka opisane u ovom članku mogu se primijeniti na druge objekte, kao što su: