Poznámka. přel.: Tento článek je součástí materiálů projektu publikovaných ve veřejné doméně učit se8s, školící společnosti a jednotlivé administrátory pro práci s Kubernetes. Daniele Polencic, projektový manažer, v něm sdílí vizuální pokyny, jaké kroky podniknout v případě obecných problémů s aplikacemi běžícími na clusteru K8s.
TL;DR: zde je diagram, který vám pomůže ladit nasazení v Kubernetes:
Vývojový diagram pro hledání a opravu chyb v clusteru. Originál (v angličtině) je k dispozici na PDF и jako obrázek.
Při nasazování aplikace do Kubernetes jsou obvykle tři komponenty, které musíte definovat:
Rozvinutí - jedná se o jakýsi recept na vytváření kopií aplikace, nazývané pody;
Servis — interní load balancer, který rozděluje provoz mezi moduly;
Ingress — popis toho, jak se provoz dostane z vnějšího světa ke službě.
Zde je rychlé grafické shrnutí:
1) V Kubernetes přijímají aplikace provoz z vnějšího světa prostřednictvím dvou vrstev load balancerů: interní a externí.
2) Vnitřní balancer se nazývá Service, externí se nazývá Ingress.
3) Deployment vytváří moduly a monitoruje je (nevytvářejí se ručně).
Řekněme, že chcete nasadit jednoduchou aplikaci a la Ahoj světe. Konfigurace YAML pro něj bude vypadat takto:
A co štítek track: canary v horní části sekce Nasazení? Mělo by se to shodovat?
Tento štítek je specifický pro nasazení a služba jej nepoužívá ke směrování provozu. Jinými slovy, může být odstraněn nebo přiřazena jiná hodnota.
A co volič matchLabels?
Vždy se musí shodovat se štítky podu, protože ho používá Deployment ke sledování modulů.
Předpokládejme, že jste provedli správné úpravy. Jak je zkontrolovat?
Štítek pod můžete zkontrolovat pomocí následujícího příkazu:
kubectl get pods --show-labels
Nebo pokud moduly patří k několika aplikacím:
kubectl get pods --selector any-name=my-app --show-labels
Kde any-name=my-app je štítek any-name: my-app.
Zůstaly nějaké potíže?
Můžete se připojit k modulu! Chcete-li to provést, musíte použít příkaz port-forward v kubectl. Umožňuje vám připojit se ke službě a zkontrolovat připojení.
service/<service name> - Název služby; v našem případě je my-service;
3000 je port, který je třeba otevřít v počítači;
80 - port zadaný v poli port servis.
Pokud bylo spojení navázáno, pak jsou nastavení správná.
Pokud se připojení nezdaří, je problém se štítky nebo se porty neshodují.
Vztah mezi Service a Ingress
Dalším krokem při poskytování přístupu k aplikaci je nastavení Ingress. Ingress potřebuje vědět, jak najít službu, pak najít pody a nasměrovat na ně provoz. Ingress vyhledá požadovanou službu podle názvu a otevřeného portu.
V popisu Ingress a Service se musí shodovat dva parametry:
servicePort v Ingress musí odpovídat parametru port ve službě;
serviceName v Ingress musí odpovídat poli name ve službě.
Následující diagram shrnuje připojení portů:
1) Jak již víte, služba poslouchá určité port:
2) Ingress má parametr nazvaný servicePort:
3) Tento parametr (servicePort) se musí vždy shodovat port v definici služby:
4) Je-li ve službě Service uveden port 80, je to nutné servicePort se také rovnalo 80:
V praxi je třeba věnovat pozornost následujícím řádkům:
Nyní pokaždé, když odešlete požadavek na port 3000 na vašem počítači, bude předán na port 80 modulu s řadičem Ingress. Tím, že půjdete do http://localhost:3000, měli byste vidět stránku vygenerovanou aplikací.
Shrnutí portů
Ještě jednou si připomeňme, které porty a štítky se musí shodovat:
Selektor v definici služby musí odpovídat štítku podu;
targetPort v definici Služba se musí shodovat containerPort nádoba uvnitř pouzdra;
port v definici Služba může být cokoliv. Různé služby mohou používat stejný port, protože mají různé IP adresy;
servicePort Vstup musí odpovídat port v definici Služby;
Název služby musí odpovídat poli serviceName ve společnosti Ingress.
Bohužel nestačí vědět, jak správně strukturovat konfiguraci YAML.
Co se stane, když se věci pokazí?
Modul se nemusí spustit nebo se může zřítit.
3 kroky k diagnostice problémů s aplikacemi v Kubernetes
Než začnete ladit své nasazení, musíte dobře rozumět tomu, jak Kubernetes funguje.
Protože každá aplikace stažená v K8s má tři součásti, měly by být laděny v určitém pořadí, počínaje úplně zdola.
Nejprve se musíte ujistit, že lusky fungují, pak...
Zkontrolujte, zda služba dodává provoz do modulů, a poté...
Zkontrolujte, zda je Ingress správně nakonfigurován.
Vizuální reprezentace:
1) Měli byste začít hledat problémy od samého dna. Nejprve zkontrolujte, zda pody mají stavy Ready и Running:
2) Pokud jsou lusky připraveny (Ready), měli byste zjistit, zda služba rozděluje provoz mezi moduly:
3) Nakonec musíte analyzovat spojení mezi službou a Ingress:
1. Diagnostika lusků
Ve většině případů problém souvisí s pod. Ujistěte se, že pody jsou uvedeny jako Ready и Running. Můžete to 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
Ve výše uvedeném výstupu příkazu je poslední modul uveden jako Running и Ready, to však není případ zbylých dvou.
Jak pochopit, co se pokazilo?
Existují čtyři užitečné příkazy pro diagnostiku modulů:
kubectl logs <имя pod'а> umožňuje extrahovat polena z kontejnerů v podu;
kubectl describe pod <имя pod'а> umožňuje zobrazit seznam událostí spojených s pod;
kubectl get pod <имя pod'а> umožňuje získat konfiguraci YAML pod uloženého v Kubernetes;
kubectl exec -ti <имя pod'а> bash umožňuje spustit interaktivní příkazový shell v jednom z kontejnerů pod
Kterou byste si měli vybrat?
Faktem je, že neexistuje žádný univerzální příkaz. Měla by být použita jejich kombinace.
Typické problémy s pod
Existují dva hlavní typy chyb pod: chyby při spuštění a chyby za běhu.
Chyby při spouštění:
ImagePullBackoff
ImageInspectError
ErrImagePull
ErrImageNeverPull
RegistryUnavailable
InvalidImageName
Runtime chyby:
CrashLoopBackOff
RunContainerError
KillContainerError
VerifyNonRootError
RunInitContainerError
CreatePodSandboxError
ConfigPodSandboxError
KillPodSandboxError
SetupNetworkError
TeardownNetworkError
Některé chyby jsou častější než jiné. Zde jsou některé z nejčastějších chyb a jak je opravit.
ImagePullBackOff
K této chybě dochází, když Kubernetes nemůže získat obrázek pro jeden z kontejnerů pod. Zde jsou tři nejčastější důvody:
Název obrázku je nesprávný – například jste se v něm spletli nebo obrázek neexistuje;
Pro obrázek byla zadána neexistující značka;
Obrázek je uložen v soukromém registru a Kubernetes nemá oprávnění k němu přistupovat.
První dva důvody lze snadno odstranit – stačí opravit název obrázku a značku. V případě druhého je třeba zadat přihlašovací údaje pro uzavřený registr do Tajemství a přidat na něj odkazy v pods. V dokumentaci Kubernetes existuje příklad jak se to dá udělat.
Crash Loop Back Off
Kubenetes vyvolá chybu CrashLoopBackOff, pokud kontejner nelze spustit. K tomu obvykle dochází, když:
Musíte se pokusit dostat k protokolům z kontejneru, abyste zjistili důvod jeho selhání. Pokud je obtížné získat přístup k protokolům, protože se kontejner restartuje příliš rychle, můžete použít následující příkaz:
kubectl logs <pod-name> --previous
Zobrazuje chybové zprávy z předchozí inkarnace kontejneru.
RunContainerError
K této chybě dochází, když se kontejner nespustí. Odpovídá okamžiku před spuštěním aplikace. Obvykle je to způsobeno nesprávným nastavením, například:
pokus o připojení neexistujícího svazku, jako je ConfigMap nebo Secrets;
pokus o připojení svazku pouze pro čtení jako čtení i zápis.
Tým je vhodný pro analýzu takových chyb kubectl describe pod <pod-name>.
Moduly jsou ve stavu Nevyřízeno
Po vytvoření zůstává modul ve stavu Pending.
Proč se to děje?
Zde jsou možné důvody (předpokládám, že plánovač funguje dobře):
Cluster nemá dostatek prostředků, jako je výpočetní výkon a paměť, ke spuštění modulu.
Objekt je nainstalován v příslušném jmenném prostoru ResourceQuota a vytvoření podu způsobí, že jmenný prostor překročí kvótu.
Pod je vázán na Nevyřízeno PersistentVolumeClaim.
V tomto případě se doporučuje použít příkaz kubectl describe a zkontrolujte sekci Events:
kubectl describe pod <pod name>
V případě chyb souvisejících s ResourceQuotas, doporučuje se zobrazit protokoly clusteru pomocí příkazu
kubectl get events --sort-by=.metadata.creationTimestamp
Pody nejsou připraveny
Pokud je pod uveden jako Running, ale není ve stavu Ready, znamená kontrolu jeho připravenosti (sonda připravenosti) selže.
Když k tomu dojde, modul se nepřipojí ke službě a neproudí k němu žádný provoz. Selhání testu připravenosti je způsobeno problémy v aplikaci. V tomto případě, abyste našli chybu, musíte analyzovat sekci Events ve výstupu příkazu kubectl describe.
2. Servisní diagnostika
Pokud jsou pody uvedeny jako Running и Ready, ale aplikace stále neodpovídá, měli byste zkontrolovat nastavení služby.
Služby jsou zodpovědné za směrování provozu do podů v závislosti na jejich štítcích. Proto první věc, kterou musíte udělat, je zkontrolovat, kolik modulů pracuje se službou. Chcete-li to provést, můžete zkontrolovat koncové body ve službě:
kubectl describe service <service-name> | grep Endpoints
Koncový bod je dvojice hodnot formuláře <IP-адрес:порт>, a alespoň jeden takový pár musí být přítomen na výstupu (tj. alespoň jeden modul pracuje se službou).
Pokud oddíl Endpoins prázdné, jsou možné dvě možnosti:
neexistují žádné pody se správným štítkem (nápověda: zkontrolujte, zda je jmenný prostor vybrán správně);
Ve selektoru je chyba ve štítcích služeb.
Pokud vidíte seznam koncových bodů, ale stále nemáte přístup k aplikaci, pak je pravděpodobným viníkem chyba v targetPort v popisu služby.
Jak zkontrolovat funkčnost služby?
Bez ohledu na typ služby můžete příkaz použít kubectl port-forward připojit se k němu:
To znamená, že řadič Ingress s největší pravděpodobností není správně nakonfigurován. Vzhledem k tomu, že řadič Ingress je komponenta třetí strany v clusteru, existují různé metody ladění v závislosti na jeho typu.
Než se však uchýlíte k použití speciálních nástrojů pro konfiguraci Ingress, můžete udělat něco velmi jednoduchého. Ingress používá serviceName и servicePort pro připojení ke službě. Musíte zkontrolovat, zda jsou správně nakonfigurovány. Můžete to udělat pomocí příkazu:
kubectl describe ingress <ingress-name>
Pokud sloupec Backend prázdné, existuje vysoká pravděpodobnost chyby konfigurace. Pokud jsou backendy na svém místě, ale aplikace stále není přístupná, problém může souviset s:
nastavení přístupnosti Ingress z veřejného internetu;
nastavení přístupnosti clusteru z veřejného internetu.
Problémy s infrastrukturou můžete identifikovat přímým připojením k modulu Ingress. Chcete-li to provést, nejprve najděte modul Ingress Controller (může být v jiném jmenném prostoru):
Nyní budou všechny požadavky na port 3000 v počítači přesměrovány na port 80 modulu.
Funguje to teď?
Pokud ano, pak je problém s infrastrukturou. Je potřeba přesně zjistit, jak je provoz do clusteru směrován.
Pokud ne, problém je v řadiči Ingress.
Pokud se vám nepodaří zprovoznit Ingress controller, budete ho muset odladit.
Existuje mnoho druhů ovladačů Ingress. Nejoblíbenější jsou Nginx, HAProxy, Traefik atd. (Další informace o stávajících řešeních viz naše recenze - Cca. překlad.) Měli byste se podívat na průvodce odstraňováním problémů v příslušné dokumentaci ovladače. Protože Ingress Nginx je nejpopulárnější Ingress controller, do článku jsme zahrnuli několik tipů, jak vyřešit problémy s ním související.
Ladění řadiče Ingress Nginx
Projekt Ingress-nginx má úředníka plugin pro kubectl. tým kubectl ingress-nginx lze použít pro:
Všimněte si, že v některých případech může být nutné zadat správný jmenný prostor pro Ingress controller pomocí příznaku --namespace <name>.
Shrnutí
Odstraňování problémů s Kubernetes může být náročné, pokud nevíte, kde začít. Vždy byste měli k problému přistupovat zdola nahoru: začněte s pody a poté přejděte ke službě a Ingress. Techniky ladění popsané v tomto článku lze použít na jiné objekty, například: