Wizualny przewodnik po rozwiązywaniu problemów z Kubernetesem
Notatka. przeł.: Ten artykuł jest częścią materiałów projektu opublikowanych w domenie publicznej ucz się8s, firmy szkoleniowe i indywidualni administratorzy do pracy z Kubernetesem. W nim Daniele Polencic, kierownik projektu, dzieli się wizualnymi instrukcjami, jakie kroki należy podjąć w przypadku ogólnych problemów z aplikacjami działającymi na klastrze K8s.
TL; DR: oto diagram, który pomoże Ci debugować wdrożenie w Kubernetes:
Schemat blokowy wyszukiwania i naprawiania błędów w klastrze. Oryginał (w języku angielskim) jest dostępny pod adresem PDF и jako zdjęcie.
Podczas wdrażania aplikacji w Kubernetes zazwyczaj należy zdefiniować trzy komponenty:
Rozlokowanie - jest to swego rodzaju przepis na tworzenie kopii aplikacji, zwanych podami;
Usługi — wewnętrzny moduł równoważenia obciążenia rozdzielający ruch pomiędzy podami;
Ingres — opis sposobu, w jaki ruch ze świata zewnętrznego będzie kierowany do Usługi.
Oto krótkie podsumowanie graficzne:
1) W Kubernetesie aplikacje odbierają ruch ze świata zewnętrznego poprzez dwie warstwy modułów równoważenia obciążenia: wewnętrzną i zewnętrzną.
2) Wewnętrzny balanser nazywa się Service, zewnętrzny nazywa się Ingress.
3) Wdrożenie tworzy pody i monitoruje je (nie są one tworzone ręcznie).
Załóżmy, że chcesz wdrożyć prostą aplikację a la Witaj świecie. Konfiguracja YAML będzie wyglądać następująco:
Definicja jest dość długa i łatwo się pomylić, jeśli chodzi o wzajemne powiązania komponentów.
Na przykład:
Kiedy należy używać portu 80, a kiedy 8080?
Czy powinienem utworzyć nowy port dla każdej usługi, aby nie powodowały konfliktów?
Czy nazwy etykiet mają znaczenie? Czy wszędzie powinny być takie same?
Zanim skupimy się na debugowaniu, pamiętajmy, jak te trzy komponenty są ze sobą powiązane. Zacznijmy od wdrożenia i serwisu.
Związek między wdrożeniem a usługą
Będziesz zaskoczony, ale wdrożenie i serwis nie są ze sobą w żaden sposób powiązane. Zamiast tego usługa wskazuje bezpośrednio Pody, pomijając wdrożenie.
Dlatego jesteśmy zainteresowani tym, jak Pody i Usługi są ze sobą powiązane. Trzy rzeczy do zapamiętania:
Selektor (selector) dla usługi musi odpowiadać co najmniej jednej etykiecie Poda.
targetPort musi pasować containerPort pojemnik wewnątrz kapsuły.
port Usługa może być dowolna. Różne usługi mogą korzystać z tego samego portu, ponieważ mają różne adresy IP.
Poniższy diagram przedstawia wszystkie powyższe w formie graficznej:
1) Wyobraź sobie, że usługa kieruje ruch do określonego poda:
2) Tworząc pod, musisz określić containerPort dla każdego pojemnika w strąkach:
3) Tworząc usługę, musisz określić port и targetPort. Ale który służy do podłączenia do kontenera?
4) Przez targetPort. To musi pasować containerPort.
5) Załóżmy, że w kontenerze jest otwarty port 3000. Następnie wartość targetPort powinno być takie samo.
W pliku YAML etykiety i ports / targetPort musi pasować:
A co z etykietą track: canary na górze sekcji Wdrożenie? Czy powinno pasować?
Ta etykieta jest specyficzna dla wdrożenia i nie jest używana przez usługę do kierowania ruchu. Inaczej mówiąc, można go usunąć lub przypisać mu inną wartość.
A co z selektorem matchLabels?
Musi zawsze pasować do etykiet kapsuły, ponieważ jest używany przez Deployment do śledzenia podów.
Załóżmy, że dokonałeś poprawnych zmian. Jak je sprawdzić?
Możesz sprawdzić etykietę kapsuły za pomocą następującego polecenia:
kubectl get pods --show-labels
Lub, jeśli pody należą do kilku aplikacji:
kubectl get pods --selector any-name=my-app --show-labels
Где any-name=my-app jest etykietą any-name: my-app.
Czy pozostały jakieś trudności?
Można połączyć się z kapsułą! Aby to zrobić, musisz użyć polecenia port-forward w kubectl. Umożliwia połączenie się z usługą i sprawdzenie połączenia.
service/<service name> - Nazwa serwisu; w naszym przypadku tak my-service;
3000 to port, który należy otworzyć na komputerze;
80 - port określony w polu port praca.
Jeśli połączenie zostało nawiązane, ustawienia są prawidłowe.
Jeśli połączenie nie powiedzie się, oznacza to problem z etykietami lub porty nie pasują.
Związek między usługą a wejściem
Kolejnym krokiem w zapewnieniu dostępu do aplikacji jest skonfigurowanie Ingress. Ingress musi wiedzieć, jak znaleźć usługę, a następnie znaleźć pody i skierować do nich ruch. Ingress wyszukuje wymaganą usługę według nazwy i otwartego portu.
W opisie Ingress i Service muszą zgadzać się dwa parametry:
servicePort w Ingress musi odpowiadać parametrowi port czynny;
serviceName w Ingress musi pasować do pola name czynny.
Poniższy diagram podsumowuje połączenia portów:
1) Jak już wiesz, Serwis słucha pewnych port:
2) Ingress ma parametr o nazwie servicePort:
3) Ten parametr (servicePort) musi zawsze pasować port w definicji Usługi:
4) Jeśli w serwisie określono port 80, jest to konieczne servicePort było również równe 80:
W praktyce należy zwrócić uwagę na następujące linie:
Teraz za każdym razem, gdy wysyłasz żądanie do portu 3000 na swoim komputerze, zostanie ono przekazane do portu 80 kapsuły z kontrolerem Ingress. Idąc http://localhost:3000, powinieneś zobaczyć stronę wygenerowaną przez aplikację.
Podsumowanie portów
Przypomnijmy jeszcze raz, które porty i etykiety muszą pasować:
Selektor w definicji usługi musi odpowiadać etykiecie poda;
targetPort w definicji Usługa musi być zgodna containerPort pojemnik wewnątrz kapsuły;
port w definicji Usługa może być czymkolwiek. Różne usługi mogą korzystać z tego samego portu, ponieważ mają różne adresy IP;
servicePort Ingres musi się zgadzać port w definicji Usługi;
Nazwa usługi musi być zgodna z polem serviceName w Ingressie.
Niestety, nie wystarczy wiedzieć, jak poprawnie ustrukturyzować konfigurację YAML.
Co się stanie, gdy coś pójdzie nie tak?
Pod może się nie uruchomić lub może ulec awarii.
3 kroki do diagnozowania problemów z aplikacjami w Kubernetesie
Zanim zaczniesz debugować wdrożenie, musisz dobrze zrozumieć, jak działa Kubernetes.
Ponieważ każda aplikacja pobrana w K8s ma trzy komponenty, należy je debugować w określonej kolejności, zaczynając od samego dołu.
Najpierw trzeba się upewnić, że kapsuły działają, a potem...
Sprawdź, czy usługa dostarcza ruch do podów, a następnie...
Sprawdź, czy Ingress jest poprawnie skonfigurowany.
Reprezentacja wizualna:
1) Należy zacząć szukać problemów od samego dołu. Najpierw sprawdź, czy pody mają statusy Ready и Running:
2) Jeśli strąki są gotowe (Ready), warto dowiedzieć się, czy usługa dystrybuuje ruch pomiędzy podami:
3) Na koniec musisz przeanalizować połączenie między usługą a Ingressem:
1. Diagnostyka strąków
W większości przypadków problem dotyczy kapsuły. Upewnij się, że kapsuły są wymienione jako Ready и Running. Możesz to sprawdzić za pomocą polecenia:
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
W wynikach powyższego polecenia ostatni zasobnik jest wymieniony jako Running и Readynie dotyczy to jednak dwóch pozostałych.
Jak zrozumieć, co poszło nie tak?
Istnieją cztery przydatne polecenia do diagnozowania zasobników:
kubectl logs <имя pod'а> umożliwia wyodrębnienie logów z kontenerów w pod;
kubectl describe pod <имя pod'а> umożliwia przeglądanie listy zdarzeń powiązanych z podem;
kubectl get pod <имя pod'а> pozwala uzyskać konfigurację YAML poda przechowywanego w Kubernetesie;
kubectl exec -ti <имя pod'а> bash umożliwia uruchomienie interaktywnej powłoki poleceń w jednym z kontenerów pod
Który wybrać?
Faktem jest, że nie ma uniwersalnego polecenia. Należy zastosować ich kombinację.
Typowe problemy z kapsułą
Istnieją dwa główne typy błędów podów: błędy uruchamiania i błędy czasu wykonywania.
Błędy uruchamiania:
ImagePullBackoff
ImageInspectError
ErrImagePull
ErrImageNeverPull
RegistryUnavailable
InvalidImageName
Błędy wykonania:
CrashLoopBackOff
RunContainerError
KillContainerError
VerifyNonRootError
RunInitContainerError
CreatePodSandboxError
ConfigPodSandboxError
KillPodSandboxError
SetupNetworkError
TeardownNetworkError
Niektóre błędy występują częściej niż inne. Oto niektóre z najczęstszych błędów i sposoby ich naprawienia.
ObrazPullBackOff
Ten błąd występuje, gdy Kubernetes nie może uzyskać obrazu dla jednego z kontenerów podów. Oto trzy najczęstsze przyczyny takiego stanu rzeczy:
Nazwa obrazu jest niepoprawna - na przykład popełniłeś w niej błąd lub obraz nie istnieje;
Dla obrazu określono nieistniejący tag;
Obraz jest przechowywany w prywatnym rejestrze i Kubernetes nie ma uprawnień dostępu do niego.
Pierwsze dwa powody są łatwe do wyeliminowania – wystarczy poprawić nazwę obrazu i tag. W tym drugim przypadku należy wprowadzić dane uwierzytelniające zamknięty rejestr w Secret i dodać do niego linki w podach. W dokumentacji Kubernetesa jest przykład jak można to zrobić.
Wycofanie pętli awarii
Kubenetes zgłasza błąd CrashLoopBackOff, jeśli kontener nie może zostać uruchomiony. Zwykle dzieje się tak, gdy:
W aplikacji występuje błąd uniemożliwiający jej uruchomienie;
Musisz spróbować dostać się do logów z kontenera, żeby poznać przyczynę jego niepowodzenia. Jeśli dostęp do logów jest utrudniony ze względu na zbyt szybkie ponowne uruchomienie kontenera, możesz użyć następującego polecenia:
kubectl logs <pod-name> --previous
Wyświetla komunikaty o błędach z poprzedniego wcielenia kontenera.
Błąd RunContainer
Ten błąd występuje, gdy nie można uruchomić kontenera. Odpowiada momentowi przed uruchomieniem aplikacji. Zwykle jest to spowodowane nieprawidłowymi ustawieniami, na przykład:
próba zamontowania nieistniejącego woluminu, takiego jak ConfigMap lub Secrets;
próba zamontowania woluminu tylko do odczytu w trybie odczytu i zapisu.
Zespół świetnie nadaje się do analizy takich błędów kubectl describe pod <pod-name>.
Pody mają stan Oczekujące
Po utworzeniu kapsuła pozostaje w tym stanie Pending.
Dlaczego tak się dzieje?
Oto możliwe przyczyny (zakładam, że harmonogram działa poprawnie):
Klaster nie ma wystarczających zasobów, takich jak moc obliczeniowa i pamięć, aby uruchomić zasobnik.
Obiekt jest instalowany w odpowiedniej przestrzeni nazw ResourceQuota a utworzenie poda spowoduje, że przestrzeń nazw przekroczy limit.
Pod jest powiązany z oczekującym PersistentVolumeClaim.
W takim przypadku zaleca się użycie polecenia kubectl describe i sprawdź sekcję Events:
kubectl describe pod <pod name>
W przypadku błędów dot ResourceQuotas, zaleca się przeglądanie dzienników klastra za pomocą polecenia
kubectl get events --sort-by=.metadata.creationTimestamp
Pody nie są gotowe
Jeśli kapsuła jest wymieniona jako Running, ale nie jest w stanie Ready, oznacza sprawdzenie jego gotowości (sonda gotowości) kończy się niepowodzeniem.
W takiej sytuacji kapsuła nie łączy się z usługą i nie przepływa do niej żaden ruch. Niepowodzenie testu gotowości jest spowodowane problemami w aplikacji. W takim przypadku, aby znaleźć błąd, musisz przeanalizować sekcję Events w wynikach polecenia kubectl describe.
2. Diagnostyka serwisowa
Jeśli strąki są wymienione jako Running и Ready, ale nadal nie ma odpowiedzi ze strony aplikacji, powinieneś sprawdzić ustawienia usługi.
Usługi są odpowiedzialne za kierowanie ruchu do podów w zależności od ich etykiet. Dlatego pierwszą rzeczą, którą musisz zrobić, to sprawdzić, ile podów współpracuje z usługą. W tym celu możesz sprawdzić punkty końcowe w usłudze:
kubectl describe service <service-name> | grep Endpoints
Endpoint to para wartości formularza <IP-адрес:порт>i co najmniej jedna taka para musi być obecna na wyjściu (tzn. co najmniej jeden pod współpracuje z usługą).
Jeśli sekcja Endpoins pusty, możliwe są dwie opcje:
nie ma podów z odpowiednią etykietą (podpowiedź: sprawdź, czy przestrzeń nazw została wybrana poprawnie);
W selektorze występuje błąd w etykietach usług.
Jeśli widzisz listę punktów końcowych, ale nadal nie możesz uzyskać dostępu do aplikacji, prawdopodobnym winowajcą jest błąd targetPort w opisie usługi.
Jak sprawdzić funkcjonalność usługi?
Niezależnie od rodzaju usługi możesz skorzystać z polecenia kubectl port-forward aby się z nim połączyć:
Jednak nadal nie możesz uzyskać dostępu do aplikacji.
Oznacza to, że kontroler Ingress najprawdopodobniej nie jest poprawnie skonfigurowany. Ponieważ kontroler ruchu przychodzącego jest komponentem innej firmy w klastrze, istnieją różne metody debugowania w zależności od jego typu.
Zanim jednak skorzystasz ze specjalnych narzędzi do konfiguracji Ingress, możesz zrobić coś bardzo prostego. Ingres wykorzystuje serviceName и servicePort aby połączyć się z usługą. Musisz sprawdzić, czy są one poprawnie skonfigurowane. Można to zrobić za pomocą polecenia:
kubectl describe ingress <ingress-name>
Jeśli kolumna Backend pusty, istnieje duże prawdopodobieństwo błędu konfiguracji. Jeśli backendy są już zainstalowane, ale aplikacja nadal jest niedostępna, problem może być związany z:
Ustawienia dostępności ruchu przychodzącego z publicznego Internetu;
ustawienia dostępności klastra z publicznego Internetu.
Możesz zidentyfikować problemy z infrastrukturą, łącząc się bezpośrednio z modułem Ingress. Aby to zrobić, najpierw znajdź moduł Ingress Controller (może znajdować się w innej przestrzeni nazw):
Teraz wszystkie żądania kierowane do portu 3000 na komputerze będą przekierowywane do portu 80 kapsuły.
Czy to działa teraz?
Jeśli tak, to problem leży w infrastrukturze. Konieczne jest dokładne sprawdzenie, w jaki sposób ruch kierowany jest do klastra.
Jeśli nie, problem dotyczy kontrolera Ingress.
Jeśli nie możesz uruchomić kontrolera Ingress, będziesz musiał go zdebugować.
Istnieje wiele odmian kontrolerów Ingress. Najpopularniejsze to Nginx, HAProxy, Traefik itp. (więcej informacji o istniejących rozwiązaniach zob nasza recenzja - około. tłumacz.) Należy zapoznać się z instrukcją rozwiązywania problemów w odpowiedniej dokumentacji sterownika. Ponieważ Wejdź do Nginxa to najpopularniejszy kontroler Ingress, w artykule zamieściliśmy kilka wskazówek, jak rozwiązać problemy z nim związane.
Debugowanie kontrolera Ingress Nginx
Projekt Ingress-nginx ma oficjalnego przedstawiciela wtyczka do kubectl. Zespół kubectl ingress-nginx może być stosowany do:
Pamiętaj, że w niektórych przypadkach może być konieczne określenie poprawnej przestrzeni nazw dla kontrolera Ingress za pomocą flagi --namespace <name>.
Streszczenie
Rozwiązywanie problemów z Kubernetesem może być trudne, jeśli nie wiesz, od czego zacząć. Zawsze należy podejść do problemu od dołu do góry: zacząć od podów, a następnie przejść do usługi i Ingress. Techniki debugowania opisane w tym artykule można zastosować do innych obiektów, takich jak: