Pozn. přek.: Tento článek je součástí volně dostupných materiálů projektu , školícího práci s Kubernetes pro firmy a jednotlivé administrátory. Daniele Polencic, vedoucí projektu, zde sdílí jasný návod, jaké kroky je třeba učinit v případě vzniku obecných problémů s aplikacemi běžícími v klastru K8s.

TL;DR: zde je diagram, který vám pomůže odladit deployment v Kubernetes:
Bloková schéma pro vyhledání a opravu chyb v klastru. V originále (v angličtině) je k dispozici v a .
Při nasazení aplikace v Kubernetes je obvykle nutné definovat tři komponenty:
- Nasazení — to je jakýsi recept na vytváření kopií aplikace, nazývaných pod’y;
- Služba — interní load balancer, který rozděluje dopravu mezi pod’y;
- Ingress — popis toho, jak bude doprava proudit z vnějšího světa k Service.
Zde je krátké grafické shrnutí:
1) V Kubernetes aplikace přijímají dopravu z vnějšího světa prostřednictvím dvou vrstev load balancerů: interního a externího.

2) Vnitřní load balancer se nazývá Service, externí – Ingress.

3) Deployment vytváří pod’y a sleduje je (nejsou vytvářeny ručně).

Předpokládejme, že chcete nasadit jednoduchou aplikaci a la Hello World. YAML konfigurace pro ni bude vypadat následovně:
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: /Definice je poměrně dlouhá a snadno se v tom ztratit, jak jsou komponenty navzájem propojeny.
Například:
- Kdy používat port 80 a kdy 8080?
- Měl by se vytvářet nový port pro každou službu, aby nedocházelo ke konfliktu?
- Mají názvy labelů nějaký význam? Měly by být všude stejné?
Než se zaměříme na odladění, připomeňme si, jak jsou tři komponenty propojeny. Začněme s Deployment a Service.
Propojení Deployment a Service
Možná vás to překvapí, ale Deploymenty a Servicey nejsou nijak propojeny. Místo toho Service přímo odkazuje na pod’y mimo Deployment.
Takže nás zajímá, jak spolu souvisejí Pod'y a Service'y. Je třeba mít na paměti tři věci:
- Selector (
selector) u Service musí odpovídat alespoň jednomu labelu Pod'u. -
targetPortmusí odpovídatcontainerPortkontejneru uvnitř Pod'u. -
portService může mít různá nastavení. Různé služby mohou používat stejný port, protože mají různé IP adresy.
Následující schéma zobrazuje vše výše uvedené graficky:
1) Představme si, že služba směruje provoz do určitého podu:

2) Při vytváření podu je nutné zadat containerPort pro každý kontejner v podech:

3) Při vytváření služby je třeba uvést port a targetPort. Ale kterým z nich se připojujete k kontejneru?

4) Přes targetPort. Musí odpovídat containerPort.

5) Předpokládejme, že je v kontejneru otevřen port 3000. Pak musí být hodnota targetPort stejná.

V YAML souboru musí být labely a ports / targetPort shodné:
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 co se týká labelu track: canary v horní části sekce Deployment? Musí být stejný?
Tento label se vztahuje k nasazení a služba jej nepoužívá k směrování provozu. Jinými slovy, lze jej odstranit nebo přiřadit jinou hodnotu.
A co selektor matchLabels?
Musí vždy odpovídat labelům Pod'u, neboť ho Deployment používá ke sledování podů.
Předpokládejme, že jste provedli správné úpravy. Jak je zkontrolovat?
Labely podů můžete zkontrolovat následujícím příkazem:
kubectl get pods --show-labelsNebo pokud patří pod'y k více aplikacím:
kubectl get pods --selector any-name=my-app --show-labels Kde any-name=my-app — to je label any-name: my-app.
Stále jsou problémy?
Můžete se připojit k pod'u! K tomu použijte příkaz port-forward v kubectl. Umožňuje připojit se k službě a zkontrolovat spojení.
kubectl port-forward service/ 3000:80Zde:
-
service/— název služby; v našem případě je tomy-service; - 3000 — port, který je třeba otevřít na počítači;
- 80 — port uvedený v poli
portslužby.
Pokud se podařilo navázat spojení, znamená to, že nastavení je správné.
Pokud se spojení nepodařilo navázat, znamená to, že je problém s etikety nebo porty se neshodují.
Spojení Service a Ingress
Dalším krokem k zajištění přístupu k aplikaci je nastavení Ingressu. Ingress musí vědět, jak najít službu, poté najít pody a nasměrovat k nim provoz. Ingress najde požadovanou službu podle názvu a otevřeného portu.
Ve specifikaci Ingressu a Service musí být shodné dva parametry:
-
servicePortv Ingressu by se měl shodovat s parametremportv Service; -
serviceNamev Ingressu by mělo odpovídat polinamev Service.
Následující schéma shrnuje propojení portů:
1) Jak již víte, služba naslouchá na určitém port:

2) Ingress má parametr, nazývaný servicePort:

3) Tento parametr (servicePort) musí být vždy shodný s port v definici Service:

4) Pokud je v Service nastaven port 80, pak je nutné, aby servicePort také byl roven 80:

V praxi je třeba věnovat pozornost následujícím řádkům:
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: /Jak ověřit, zda Ingress funguje?
Můžete použít metodu s kubectl port-forward, ale místo služby se musíte připojit k Ingress controlleru.
Nejprve je potřeba zjistit název podu s Ingress controllerem:
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 Najděte pod Ingress (může patřit do jiného jmenného prostoru) a proveďte příkaz popis, abyste zjistili čísla portů:
kubectl describe pod nginx-ingress-controller-6fc5bcc
--namespace kube-system
| grep Ports
Ports: 80/TCP, 443/TCP, 18080/TCPNakonec se připojte k podu:
kubectl port-forward nginx-ingress-controller-6fc5bcc 3000:80 --namespace kube-systemNyní, kdykoliv odešlete požadavek na port 3000 na počítači, bude přesměrován na port 80 podu s Ingress controllerem. Pokud přejdete na , měli byste vidět stránku vytvořenou aplikací.
Shrnutí portů
Pojďme si ještě jednou připomenout, které porty a etikety by měly být shodné:
- Selektor v definici Service by měl odpovídat etiketě podu;
-
targetPortv definici Service by se měl shodovat scontainerPortkontejnery uvnitř podu; -
portV definici služby může být jakákoliv. Různé služby mohou používat stejný port, protože mají různé IP adresy; -
servicePortIngress musí odpovídatportv definici služby; - Název služby musí odpovídat poli
serviceNamev Ingressu.
Bohužel nestačí vědět, jak správně strukturovat YAML konfiguraci.
Co se stane, když něco jde špatně?
Možná, že pod se nespouští nebo se zastavuje.
3 kroky k diagnostice problémů s aplikacemi v Kubernetes
Než začnete ladit deployment, je třeba mít dobrou představu o tom, jak Kubernetes funguje.
Vzhledem k tomu, že v každé aplikaci nasazené v K8s jsou tři komponenty, je důležité je ladit v určitém pořadí, začínaje nejnižší vrstvou.
- Nejprve je třeba se ujistit, že pody pracují, poté…
- Zkontrolujte, zda služba dodává provoz podům, a pak…
- Zkontrolujte, zda je Ingress správně nakonfigurován.
Grafické znázornění:
1) Hledání problémů by mělo začínat od spodní části. Nejprve zkontrolujte, zda mají pody stavy Ready a Dokončeno:

2) Pokud jsou pody připraveny (Ready), je třeba zjistit, zda služba správně směruje provoz mezi pody:

3) Nakonec je třeba analyzovat spojení mezi službou a Ingress.

1. Diagnostika podů
Většinu času je problém spojen s pod. Ujistěte se, že pody jsou uvedeny jako Ready a Dokončeno. To lze zkontrolovat pomocí pří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 V výstupu příkazu výše je poslední pod uveden jako Dokončeno a Ready, nicméně pro dva ostatní to neplatí.
Jak zjistit, co je špatně?
Existují čtyři užitečné příkazy pro diagnostiku podů:
-
kubectl logsumožňuje získat logy z kontejnerů v podu; -
kubectl describe podumožňuje zobrazit seznam událostí souvisejících s podem; -
kubectl get podumožňuje získat YAML konfiguraci podu uloženou v Kubernetes; -
kubectl exec -ti bashumožňuje spustit interaktivní příkazový řádek v jednom z kontejnerů podu.
Který z nich vybrat?
Problém je v tom, že neexistuje univerzální příkaz. Je třeba použít jejich kombinaci.
Typické problémy podů
Existují dva hlavní typy chyb podů: chyby při spuštění (startup) a chyby během běhu (runtime).
Chyby spuštění:
-
ImagePullBackoff -
ImageInspectError -
ErrImagePull -
ErrImageNeverPull -
RegistryUnavailable -
NeplatnéJménoObrazu
Chyby běhu:
-
CrashLoopBackOff -
ChybaSpuštěníKontejneru -
ChybaZabitíKontejneru -
OvěřitChybuNeroot -
ChybaSpuštěníInitKontejneru -
ChybaVytvořeníPodSandboxu -
ChybaKonfiguracePodSandboxu -
ChybaZabitíPodSandboxu -
Některé chyby se vyskytují častěji než jiné. Zde je několik nejčastějších chyb a způsoby jejich odstranění. -
ImagePullBackOff
Tato chyba se objevuje, když Kubernetes nemůže získat obraz pro jeden z kontejnerů podu. Tady jsou tři nejčastější příčiny:
Nesprávně zadané jméno obrazu — například jste v něm udělali chybu, nebo obraz neexistuje;
Byl uveden neexistující tag pro obraz;
- Obraz je uložen v soukromém registru a Kubernetes nemá oprávnění k jeho přístupu.
- První dvě příčiny se snadno odstraní — stačí opravit jméno obrazu a tag. V případě poslední je třeba přidat údaje pro soukromý registr do Secret a přidat odkazy na něj do podů. V dokumentaci Kubernetes
- je příklad
jak to provést. , pokud se kontejner nemůže spustit. K tomu obvykle dochází, když:
CrashLoopBackOff
V aplikaci je chyba, která znemožňuje její spuštění; CrashLoopBackOffje špatně nakonfigurována
- Test životnosti selhal příliš mnohokrát.
- Kontejner ;
- kubectl logs --previous
Tento příkaz vrátí chybové zprávy z předchozí reinkarnace kontejneru.
Tato chyba nastává, když kontejner není schopen se spustit. Odpovídá to fázi před spuštěním aplikace. Obvykle je jejím důvodem nesprávná konfigurace, například:pokyn k připojení neexistujícího svazku, jako je ConfigMap nebo Secrets;
ChybaSpuštěníKontejneru
pokyn k připojení svazku typu pouze pro čtení jako pro zápis.
- K analýze podobných chyb je vhodný příkaz
- kubectl describe pod
Pody jsou ve stavu Pending Po vytvoření pod zůstává ve stavu.
Proč se to děje?
Zde jsou možné příčiny (předpokládám, že plánovač funguje správně): Pending.
V clusteru není dostatek zdrojů, jako je výpočetní výkon a paměť, pro spuštění podu.
V příslušném prostoru názvů je nastaven objekt
- ResourceQuota
- V odpovídajícím jmenném prostoru je nastavena objektová komponenta
ResourceQuotaVytvoření podu povede k překročení kvóty jmenného prostoru. - Pod je vázán na Pending
PersistentVolumeClaim.
V takovém případě se doporučuje použít příkaz kubectl describe a zkontrolovat sekci Události:
kubectl describe pod V případě chyb souvisejících s ResourceQuotas, doporučuje se prostudovat logy clusteru pomocí příkazu
kubectl get events --sort-by=.metadata.creationTimestampPody nejsou v stavu Ready
Pokud je pod označen jako Dokončeno, ale není ve stavu Ready, znamená to, že kontrola jeho připravenosti (readiness probe) neprobíhá úspěšně.
Když k tomu dojde, pod se nepřipojuje k službě a na něj neplyne žádný provoz. Selhání testu připravenosti je způsobeno problémy v aplikaci. V takovém případě je třeba analyzovat sekci Události ve výstupu příkazu kubectl describe.
2. Diagnostika služeb
Pokud jsou pody označeny jako Dokončeno a Ready, ale odpověď z aplikace stále není, je třeba zkontrolovat nastavení služby.
Služby zařizují směrování provozu k podům na základě jejich štítků. Proto je první věc, kterou je třeba udělat, zkontrolovat, kolik podů pracuje se službou. K tomu můžete zkontrolovat endpointy ve službě:
kubectl describe service | grep Endpoints Endpoint je dvojice hodnot typu <IP-адрес:порт>, a ve výstupu by měla být přítomna alespoň jedna taková dvojice (to znamená, že se se službou pracuje alespoň jeden pod).
Pokud je sekce Endpoints prázdná, mohou být dva možné scénáře:
- neexistuje žádný pod se správným štítkem (nápověda: zkontrolujte, zda je správně vybrán jmenný prostor);
- existuje chyba v štítcích služby v selektoru.
Pokud vidíte seznam endpointů, ale stále se nemůžete dostat k aplikaci, pravděpodobným viníkem je chyba v targetPort popisu služby.
Jak zkontrolovat funkčnost služby?
Bez ohledu na typ služby, můžete použít příkaz kubectl port-forward pro připojení k ní:
kubectl port-forward service/ 3000:80Zde:
-
<service-name>— název služby; - 3000 — port, který otvíráte na počítači;
- 80 — port na straně služby.
3. Diagnostika Ingress
Pokud jste dočetli až sem, tak:
- pody jsou označeny jako
DokončenoaReady; - služba úspěšně rozděluje provoz mezi pody.
Nicméně stále se nemůžete "dostat" k aplikaci.
To znamená, že pravděpodobně je špatně nastaven kontroler Ingress. Vzhledem k tomu, že kontroler Ingress je komponenta třetích stran v clusteru, existují různé metody ladění v závislosti na jeho typu.
Ale než se uchýlíte k pomoci speciálních nástrojů pro konfiguraci Ingressu, lze udělat něco velmi jednoduchého. Ingress používá serviceName a servicePort k připojení k službě. Je nutné zkontrolovat, zda jsou správně nastaveny. To lze provést pomocí příkazu:
kubectl describe ingress Pokud je sloupec Backend plánovali udělat na Linuxu. Backend interaguje s DB, načítá potřebný seznam privilegií a poté, v závislosti na tom, jaká privilegium má autorizovaný uživatel, poskytuje přístup k podepisování finančních dokumentů a jejich zasílání k realizaci, nebo generaci nějaké zprávy. prázdný, je vysoká pravděpodobnost chyby ve konfiguraci. Pokud jsou backendy na místě, ale k aplikaci stále není přístup, může být problém spojen s:
- nastavením dostupnosti Ingressu z veřejného internetu;
- nastavením dostupnosti clusteru z veřejného internetu.
Pro identifikaci problémů se strukturou se můžete přímo připojit k podu Ingressu. Nejprve najděte pod Ingress kontroléru (může být v jiném jmenném prostoru):
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žijte příkaz popis, abyste nastavili port:
kubectl describe pod nginx-ingress-controller-6fc5bcc --namespace kube-system | grep PortsNakonec se připojte k podu:
kubectl port-forward nginx-ingress-controller-6fc5bcc 3000:80 --namespace kube-systemNyní budou všechny požadavky na port 3000 na počítači přesměrovány na port 80 podu.
Funguje nyní?
- Pokud ano, je problém se strukturou. Je nutné zjistit, jak přesně je směrování provozu do clusteru realizováno.
- Pokud ne, je problém s kontrolérem Ingress.
Pokud se vám nedaří rozběhnout kontrolér Ingress, budete muset provést jeho debugování.
Existuje mnoho typů kontrolérů Ingress. Nejpopulárnější jsou Nginx, HAProxy, Traefik a další. (více o existujících řešeních viz — pozn. překl.) Měli byste se řídit příručkou pro odstraňování problémů v dokumentaci příslušného kontroléru. Vzhledem k tomu, že je nejpopulárnějším kontrolérem Ingress, zahrnuli jsme do článku několik rad pro řešení s ním souvisejících problémů.
Debugování kontroléru Ingress Nginx
Projekt Ingress-nginx má oficiální . Příkaz kubectl ingress-nginx můžete použít k:
- analýze logů, backendů, certifikátů atd.;
- připojení k Ingressu;
- zkoumání aktuální konfigurace.
Pomohou vám v tom následující tři příkazy:
-
kubectl ingress-nginx lint— kontrolujenginx.conf; -
kubectl ingress-nginx backend— zkoumá backend (analogicky skubectl describe ingress); -
kubectl ingress-nginx logs— kontroluje logy.
Upozorňujeme: v některých případech může být nutné uvést správný jmenný prostor pro kontrolér Ingress pomocí přepínače --namespace.
Shrnutí
Diagnostika v Kubernetes může být složitým úkolem, pokud nevíte, jak začít. K problému byste měli vždy přistupovat metodou „shora dolů“: začněte od pods a poté přejděte na servis a Ingress. Metody ladění popsané v článku lze aplikovat i na další objekty, jako jsou:
- nefunkční Joby a CronJoby;
- StatefulSety a DaemonSety.
Vyjadřuji díky , a za cenné připomínky a doplnění.
P.S. od překladatele
Přečtěte si také náš blog:
- «»;
- «»;
- «»;
- «».
Zdroj: habr.com
