Vizuálny sprievodca riešením problémov s Kubernetes

Poznámka. preklad.: Tento článok je súčasťou projektových materiálov publikovaných vo verejnej doméne learnk8s, školiace spoločnosti a jednotlivých správcov na prácu s Kubernetes. Daniele Polencic, projektový manažér, v ňom zdieľa vizuálne pokyny, aké kroky podniknúť v prípade všeobecných problémov s aplikáciami bežiacimi na klastri K8s.

Vizuálny sprievodca riešením problémov s Kubernetes

TL;DR: Tu je diagram, ktorý vám pomôže ladiť nasadenie v Kubernetes:

Vizuálny sprievodca riešením problémov s Kubernetes

Vývojový diagram na nájdenie a opravu chýb v klastri. Originál (v angličtine) je dostupný na PDF и ako obrázok.

Pri nasadzovaní aplikácie do Kubernetes zvyčajne musíte definovať tri komponenty:

  • rozvinutie - ide o akýsi recept na vytváranie kópií aplikácie, nazývaných pody;
  • Služba sa — interný vyrovnávač zaťaženia, ktorý rozdeľuje prevádzku medzi moduly;
  • Ingress — popis toho, ako sa návštevnosť dostane z vonkajšieho sveta do Služby.

Tu je rýchle grafické zhrnutie:

1) V Kubernetes aplikácie prijímajú návštevnosť z vonkajšieho sveta prostredníctvom dvoch vrstiev vyrovnávačov záťaže: internej a externej.

Vizuálny sprievodca riešením problémov s Kubernetes

2) Interný balancer sa nazýva Service, externý sa nazýva Ingress.

Vizuálny sprievodca riešením problémov s Kubernetes

3) Nasadenie vytvára moduly a monitoruje ich (nevytvárajú sa ručne).

Vizuálny sprievodca riešením problémov s Kubernetes

Povedzme, že chcete nasadiť jednoduchú aplikáciu a la Ahoj svet. Konfigurácia YAML bude vyzerať takto:

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

Definícia je pomerne dlhá a je ľahké sa zmiasť o tom, ako komponenty navzájom súvisia.

napríklad:

  • Kedy by ste mali použiť port 80 a kedy by ste mali použiť 8080?
  • Mám vytvoriť nový port pre každú službu, aby neboli v konflikte?
  • Záleží na názvoch štítkov? Mali by byť všade rovnaké?

Skôr než sa zameriame na ladenie, pripomeňme si, ako spolu tieto tri zložky súvisia. Začnime s nasadením a servisom.

Vzťah medzi nasadením a službou

Budete prekvapení, ale Deployment a Service nie sú nijako prepojené. Namiesto toho služba ukazuje priamo na moduly, čím obchádza nasadenie.

Preto nás zaujíma, ako spolu moduly a služby súvisia. Tri veci na zapamätanie:

  1. Selektor (selector) pre službu musí zodpovedať aspoň jednému štítku pod.
  2. targetPort sa musí zhodovať containerPort kontajner vo vnútri pod.
  3. port Služba môže byť čokoľvek. Rôzne služby môžu používať rovnaký port, pretože majú rôzne adresy IP.

Nasledujúci diagram znázorňuje všetky vyššie uvedené v grafickej forme:

1) Predstavte si, že služba smeruje návštevnosť do určitého modulu:

Vizuálny sprievodca riešením problémov s Kubernetes

2) Pri vytváraní podu musíte špecifikovať containerPort pre každú nádobu v strukoch:

Vizuálny sprievodca riešením problémov s Kubernetes

3) Pri vytváraní služby musíte špecifikovať port и targetPort. Ktorý sa však používa na pripojenie ku kontajneru?

Vizuálny sprievodca riešením problémov s Kubernetes

4) Cez targetPort. Musí sa zhodovať containerPort.

Vizuálny sprievodca riešením problémov s Kubernetes

5) Povedzme, že v kontajneri je otvorený port 3000. Potom hodnota targetPort by mala byť rovnaká.

Vizuálny sprievodca riešením problémov s Kubernetes

V súbore YAML, štítky a ports / targetPort sa musí zhodovať:

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

A čo štítok track: canary v hornej časti sekcie Nasadenie? Mala by sa zhodovať?

Toto označenie je špecifické pre nasadenie a služba ho nepoužíva na smerovanie prevádzky. Inými slovami, možno ho odstrániť alebo mu priradiť inú hodnotu.

Čo sa týka selektora matchLabels?

Vždy sa musí zhodovať so štítkami podu, pretože ho používa Deployment na sledovanie modulov.

Predpokladajme, že ste vykonali správne úpravy. Ako ich skontrolovať?

Štítok pod môžete skontrolovať pomocou nasledujúceho príkazu:

kubectl get pods --show-labels

Alebo, ak moduly patria do niekoľkých aplikácií:

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

kde any-name=my-app je štítok any-name: my-app.

Zostali nejaké ťažkosti?

Môžete sa pripojiť k modulu! Ak to chcete urobiť, musíte použiť príkaz port-forward v kubectl. Umožňuje vám pripojiť sa k službe a skontrolovať pripojenie.

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

tu:

  • service/<service name> — názov služby; v našom prípade je my-service;
  • 3000 je port, ktorý je potrebné otvoriť na počítači;
  • 80 - port uvedený v poli port služby.

Ak bolo pripojenie vytvorené, nastavenia sú správne.

Ak sa pripojenie nepodarí, vyskytol sa problém so štítkami alebo sa porty nezhodujú.

Vzťah medzi Service a Ingress

Ďalším krokom pri poskytovaní prístupu k aplikácii je nastavenie Ingress. Ingress potrebuje vedieť, ako nájsť službu, potom nájsť moduly a nasmerovať na ne návštevnosť. Ingress nájde požadovanú službu podľa názvu a otvoreného portu.

V popise Ingress a Service sa musia zhodovať dva parametre:

  1. servicePort v Ingress sa musí zhodovať s parametrom port v prevádzke;
  2. serviceName v Ingress sa musí zhodovať s poľom name v prevádzke.

Nasledujúci diagram sumarizuje pripojenia portov:

1) Ako už viete, služba počúva určité port:

Vizuálny sprievodca riešením problémov s Kubernetes

2) Ingress má parameter s názvom servicePort:

Vizuálny sprievodca riešením problémov s Kubernetes

3) Tento parameter (servicePort) sa musí vždy zhodovať port v definícii služby:

Vizuálny sprievodca riešením problémov s Kubernetes

4) Ak je v časti Služba špecifikovaný port 80, potom je potrebné servicePort sa tiež rovnalo 80:

Vizuálny sprievodca riešením problémov s Kubernetes

V praxi je potrebné venovať pozornosť nasledujúcim riadkom:

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

Ako skontrolovať, či Ingress beží?

Metódu môžete použiť s kubectl port-forward, ale namiesto služby sa musíte pripojiť k ovládaču Ingress.

Najprv musíte zistiť názov modulu pomocou ovládača Ingress:

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

Nájdite modul Ingress (môže byť v inom mennom priestore) a spustite príkaz describeak chcete zistiť čísla portov:

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

Nakoniec sa pripojte k modulu:

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

Teraz zakaždým, keď odošlete požiadavku na port 3000 na vašom počítači, bude presmerovaná na port 80 modulu s ovládačom Ingress. Tým, že pôjdete do http://localhost:3000, mali by ste vidieť stránku vygenerovanú aplikáciou.

Zhrnutie portov

Ešte raz si pripomeňme, ktoré porty a označenia sa musia zhodovať:

  1. Selektor v definícii služby sa musí zhodovať s menovkou modulu;
  2. targetPort v definícii Služba sa musí zhodovať containerPort nádoba vo vnútri puzdra;
  3. port v definícii Služba môže byť čokoľvek. Rôzne služby môžu používať rovnaký port, pretože majú rôzne adresy IP;
  4. servicePort Vstup sa musí zhodovať port v definícii Služby;
  5. Názov služby sa musí zhodovať s poľom serviceName v Ingress.

Bohužiaľ nestačí vedieť, ako správne štruktúrovať konfiguráciu YAML.

Čo sa stane, keď sa veci pokazia?

Modul sa nemusí spustiť alebo môže zlyhať.

3 kroky na diagnostiku problémov s aplikáciami v Kubernetes

Skôr ako začnete ladiť svoje nasadenie, musíte dobre porozumieť tomu, ako Kubernetes funguje.

Keďže každá aplikácia stiahnutá v K8s má tri komponenty, mali by sa ladiť v určitom poradí, počnúc úplne zdola.

  1. Najprv sa musíte uistiť, že struky fungujú, potom...
  2. Skontrolujte, či služba dodáva prenos do modulov, a potom...
  3. Skontrolujte, či je Ingress správne nakonfigurovaný.

Vizuálna reprezentácia:

1) Mali by ste začať hľadať problémy úplne zdola. Najprv skontrolujte, či moduly majú stavy Ready и Running:

Vizuálny sprievodca riešením problémov s Kubernetes

2) Ak sú struky pripravené (Ready), mali by ste zistiť, či služba distribuuje návštevnosť medzi moduly:

Vizuálny sprievodca riešením problémov s Kubernetes

3) Nakoniec musíte analyzovať spojenie medzi službou a Ingress:

Vizuálny sprievodca riešením problémov s Kubernetes

1. Diagnostika toboliek

Vo väčšine prípadov problém súvisí s modulom. Uistite sa, že struky sú uvedené ako Ready и Running. Môžete to skontrolovať pomocou príkazu:

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

Vo výstupe príkazu vyššie je posledný modul uvedený ako Running и Ready, to však nie je prípad ďalších dvoch.

Ako pochopiť, čo sa pokazilo?

Existujú štyri užitočné príkazy na diagnostiku modulov:

  1. kubectl logs <имя pod'а> umožňuje extrahovať polená z kontajnerov v pod;
  2. kubectl describe pod <имя pod'а> umožňuje zobraziť zoznam udalostí spojených s modulom;
  3. kubectl get pod <имя pod'а> umožňuje získať konfiguráciu YAML pod uloženú v Kubernetes;
  4. kubectl exec -ti <имя pod'а> bash umožňuje spustiť interaktívny príkazový shell v jednom z kontajnerov pod

Ktorý by ste si mali vybrať?

Faktom je, že univerzálny príkaz neexistuje. Mala by sa použiť ich kombinácia.

Typické problémy s pod

Existujú dva hlavné typy chýb pod: chyby pri spustení a chyby pri spustení.

Chyby pri spustení:

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

Chyby spustenia:

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

Niektoré chyby sú bežnejšie ako iné. Tu sú niektoré z najbežnejších chýb a ako ich opraviť.

ImagePullBackOff

Táto chyba sa vyskytuje, keď Kubernetes nedokáže získať obrázok pre jeden z kontajnerov pod. Tu sú tri najčastejšie dôvody:

  1. Názov obrázka je nesprávny – napríklad ste sa v ňom pomýlili alebo obrázok neexistuje;
  2. Pre obrázok bola zadaná neexistujúca značka;
  3. Obrázok je uložený v súkromnom registri a Kubernetes nemá povolenie na prístup k nemu.

Prvé dva dôvody sa dajú ľahko odstrániť – stačí opraviť názov obrázka a značku. V druhom prípade musíte zadať prihlasovacie údaje pre uzavretý register do tajomstva a pridať naň odkazy v pods. V dokumentácii Kubernetes existuje príklad ako sa to dá urobiť.

Crash Loop Back Off

Kubenetes vyhodí chybu CrashLoopBackOff, ak sa kontajner nedá spustiť. Zvyčajne sa to stane, keď:

  1. V aplikácii je chyba, ktorá bráni jej spusteniu;
  2. Kontajner nakonfigurovaný nesprávne;
  3. Test živosti zlyhal príliš veľakrát.

Musíte sa pokúsiť dostať k protokolom z kontajnera, aby ste zistili dôvod jeho zlyhania. Ak je ťažké získať prístup k protokolom, pretože kontajner sa reštartuje príliš rýchlo, môžete použiť nasledujúci príkaz:

kubectl logs <pod-name> --previous

Zobrazuje chybové hlásenia z predchádzajúcej inkarnácie kontajnera.

RunContainerError

Táto chyba sa vyskytuje, keď sa kontajner nespustí. Zodpovedá okamihu pred spustením aplikácie. Zvyčajne je to spôsobené nesprávnym nastavením, napríklad:

  • pokus o pripojenie neexistujúceho zväzku, ako je ConfigMap alebo Secrets;
  • pokus o pripojenie zväzku len na čítanie ako na čítanie a zápis.

Tým je vhodný na analýzu takýchto chýb kubectl describe pod <pod-name>.

Moduly sú v stave čakania

Po vytvorení lusk zostane v stave Pending.

Prečo sa to deje?

Tu sú možné dôvody (predpokladám, že plánovač funguje dobre):

  1. Klaster nemá dostatok prostriedkov, ako je výkon spracovania a pamäť, na spustenie modulu.
  2. Objekt je nainštalovaný v príslušnom mennom priestore ResourceQuota a vytvorenie pod spôsobí, že menný priestor prekročí kvótu.
  3. Pod je viazaný na Nevybavené PersistentVolumeClaim.

V tomto prípade sa odporúča použiť príkaz kubectl describe a skontrolujte sekciu Events:

kubectl describe pod <pod name>

V prípade chýb súvisiacich s ResourceQuotas, odporúča sa zobraziť protokoly klastra pomocou príkazu

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

Moduly nie sú pripravené

Ak je pod uvedený ako Running, ale nie je v stave Ready, znamená kontrolu jeho pripravenosti (sonda pripravenosti) zlyhá.

Keď sa to stane, modul sa nepripojí k službe a neplynie doň žiadna prevádzka. Zlyhanie testu pripravenosti je spôsobené problémami v aplikácii. V tomto prípade, aby ste našli chybu, musíte analyzovať sekciu Events vo výstupe príkazu kubectl describe.

2. Servisná diagnostika

Ak sú struky uvedené ako Running и Ready, ale aplikácia stále neodpovedá, mali by ste skontrolovať nastavenia služby.

Služby sú zodpovedné za smerovanie prevádzky do modulov v závislosti od ich štítkov. Preto prvá vec, ktorú musíte urobiť, je skontrolovať, koľko modulov spolupracuje so službou. Ak to chcete urobiť, môžete skontrolovať koncové body v službe:

kubectl describe service <service-name> | grep Endpoints

Koncový bod je dvojica hodnôt formulára <IP-адрес:порт>a aspoň jeden takýto pár musí byť prítomný vo výstupe (to znamená, že aspoň jeden modul pracuje so službou).

Ak oddiel Endpoins prázdne, sú možné dve možnosti:

  1. neexistujú žiadne pody so správnym štítkom (nápoveda: skontrolujte, či je správne vybratý menný priestor);
  2. V servisných štítkoch vo voliči je chyba.

Ak vidíte zoznam koncových bodov, ale stále nemáte prístup k aplikácii, pravdepodobným vinníkom je chyba v targetPort v popise služby.

Ako skontrolovať funkčnosť služby?

Príkaz môžete použiť bez ohľadu na typ služby kubectl port-forward pripojiť sa k nemu:

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

tu:

  • <service-name> — názov služby;
  • 3000 je port, ktorý otvoríte na počítači;
  • 80 - port na strane služby.

3. Diagnostika vstupu

Ak ste sa dočítali až sem, tak:

  • struky sú uvedené ako Running и Ready;
  • služba úspešne distribuuje návštevnosť medzi moduly.

K aplikácii sa však stále nemôžete dostať.

To znamená, že ovládač Ingress s najväčšou pravdepodobnosťou nie je správne nakonfigurovaný. Keďže kontrolér Ingress je komponent tretej strany v klastri, existujú rôzne metódy ladenia v závislosti od jeho typu.

Ale predtým, ako sa uchýlite k použitiu špeciálnych nástrojov na konfiguráciu Ingress, môžete urobiť niečo veľmi jednoduché. Ingress používa serviceName и servicePort pre pripojenie k službe. Musíte skontrolovať, či sú správne nakonfigurované. Môžete to urobiť pomocou príkazu:

kubectl describe ingress <ingress-name>

Ak stĺpec Backend prázdne, existuje vysoká pravdepodobnosť chyby konfigurácie. Ak sú backendy na svojom mieste, ale aplikácia stále nie je prístupná, problém môže súvisieť s:

  • nastavenia prístupnosti vstupu z verejného internetu;
  • nastavenia dostupnosti klastra z verejného internetu.

Problémy s infraštruktúrou môžete identifikovať priamym pripojením k modulu Ingress. Najprv nájdite modul Ingress Controller (môže byť v inom mennom priestore):

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

Použite príkaz describena nastavenie portu:

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

Nakoniec sa pripojte k modulu:

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

Teraz budú všetky požiadavky na port 3000 v počítači presmerované na port 80 modulu.

Funguje to teraz?

  • Ak áno, problém je v infraštruktúre. Je potrebné presne zistiť, ako je doprava smerovaná do klastra.
  • Ak nie, problém je v ovládači Ingress.

Ak nemôžete spustiť ovládač Ingress, budete ho musieť odladiť.

Existuje mnoho druhov ovládačov Ingress. Najpopulárnejšie sú Nginx, HAProxy, Traefik atď. (Ďalšie informácie o existujúcich riešeniach nájdete v časti naša recenzia - približne. preklad.) Mali by ste si prečítať návod na riešenie problémov v príslušnej dokumentácii ovládača. Pretože Ingress Nginx je najobľúbenejší kontrolér Ingress, do článku sme zahrnuli niekoľko tipov na riešenie problémov, ktoré s ním súvisia.

Ladenie ovládača Ingress Nginx

Projekt Ingress-nginx má oficiálneho plugin pre kubectl. Tím kubectl ingress-nginx môže byť použitý pre:

  • analýza protokolov, backendov, certifikátov atď.;
  • spojenie so spoločnosťou Ingress;
  • štúdium aktuálnej konfigurácie.

Nasledujúce tri príkazy vám s tým pomôžu:

  • kubectl ingress-nginx lint - kontroly nginx.conf;
  • kubectl ingress-nginx backend — preskúma backend (podobne ako kubectl describe ingress <ingress-name>);
  • kubectl ingress-nginx logs — kontroluje denníky.

Upozorňujeme, že v niektorých prípadoch možno budete musieť zadať správny priestor názvov pre kontrolér Ingress pomocou príznaku --namespace <name>.

Zhrnutie

Riešenie problémov s Kubernetes môže byť náročné, ak neviete, kde začať. Vždy by ste mali pristupovať k problému zdola nahor: začnite s modulmi a potom prejdite na službu a Ingress. Techniky ladenia opísané v tomto článku možno použiť na iné objekty, ako napríklad:

  • nečinné úlohy a CronJobs;
  • StatefulSets a DaemonSets.

vyjadrujem svoju vďačnosť Gergely Risko, Daniel Weibel и Charles Christyraj za cenné pripomienky a doplnenia.

PS od prekladateľa

Prečítajte si aj na našom blogu:

Zdroj: hab.com

Pridať komentár