Debugowanie i logi w Kubernetes

Debugowanie i logi w Kubernetes

Błędy mogą powodować przestoje, spowolnić rozwój i prowadzić do frustracji zespołu, a co gorsza szefa. W tym miejscu właśnie pojawia się debugowanie. Jest ono procesem identyfikacji i naprawy błędów w oprogramowaniu. Podczas pracy z Kubernetes debugowanie może być nieco trudne. Wspomniana platforma do zarządzania kontenerów jest bardzo złożona i posiada całą masę funkcji. Dlatego w tym właśnie miejscu z pomocą przychodzą dzienniki lub jeżeli wolisz logi. To właśnie w logach są zapisywane wszystkie zdarzenia, jakie mają miejsce w systemie. Analizując takie, możesz uzyskać wgląd w to, co dzieje się w klastrze Kubernetes i łatwiej diagnozować błędy.

Jeżeli zajmujesz się administracją systemową, to wszystko, o czym do tej pory napisałem, wykonujesz na co dzień. Debugowanie Kubernetesa wygląda praktycznie tak samo jak debugowanie systemu. Jednak trudność, o której wspomniałem, wynika z elementów składowych Kubernetesa. Czyli prościej pisząc, nie dość, że musisz sprawdzać, jak działa twój serwer, na którym masz uruchomiony klaster, to jeszcze musisz monitorować samego Kubernetesa. To jest główna trudność z nim związana, ponieważ nawarstwiają się czynności, jakie musimy wykonać.

W tym materiale chcę przyjrzeć się typowym błędom, które występują w Kubernetes, oraz sposobom ich diagnozowania. Zajmiemy się także logami i sposobami uzyskiwania do nich dostępu za pomocą narzędzia kubectl. Po przeczytaniu tego poradnika powinieneś rozumieć, jak diagnozować i naprawiać błędy, czyli debugowanie powinno być już dla Ciebie proste.

 

Dołącz do Wyzwania "Opanuj Kontenery"!

Do 30 czerwca możesz dołączyć do wyzwania "Opanuj Kontenery". Możesz wziąć udział w pojedynczych kursach, bądź skorzystać z pakietów "Razem taniej". Do odebrania dodatkowo dwa kursy za darmo z kodem "Opanujkontenery2024"!

Chcesz dołączyć do szkolenia! Zapisy na stronie: https://asdevops.pl/kontenery

 

 

Typowe błędy w Kubernetes

Tak jak wspomniałem, Kubernetes nie jest narzędziem odpornym na błędy. Istnieje pewna lista tak zwanych typowych błędów, z jakimi użytkownicy najczęściej się spotkają. W związku z tym, że komunikaty wyświetlają się w języku angielskim, to przedstawię je właśnie w tym języku. Oto lista najczęściej spotykanych błędów:

Pod scheduling failures: Jak zapewne wiesz, pody są to najmniejsze możliwe do wdrożenia typy w Kubernetesie. Składają się z co najmniej jednego kontenera, który współużytkuje te same zasoby sieciowe i magazynowe. Awarie tego typu występują w sytuacji, gdy Kubernetes nie może zaplanować, poda w węźle z powodu ograniczeń zasobów, niedostępności węzła lub innych problemów.

W celu rozpoznania problemu powinniśmy skorzystać z opcji describe polecenia kubectl. Na przykład:

kubectl describe pod <nazwa-poda>

Gdy użyjesz wskazanego polecenia, wyświetlisz szczegółowe informacje o określonym podzie. Dla nas są istotne wypisane wszystkie zdarzenia, jakie wystąpiły w trakcie powstawania i działania poda. Jeśli wystąpił błąd Pod scheduling failures, sekcja zdarzeń będzie zawierała o tym informacje i przyczynach jego wystąpienia. Wspomniany błąd wystąpi, gdy otrzymamy mniej więcej komunikat typu, pod jest w stanie oczekiwania z powodu niewystarczającej ilości procesora lub pamięci.  Mniej więcej po angielsku powinno brzmieć to tak: pod is in a Pending state due to Insufficient cpu or memory.

Container image pull errors: elementem składowym Kubernetesa są obrazy. Zawierają one kod, biblioteki i zależności potrzebne do uruchomienia aplikacji. Natomiast błędy tego typu mogą wystąpić, gdy Kubernetes nie może pobrać wymaganego obrazu z rejestru kontenerów lub gdy występują problemy z samym rejestrem.

Tak samo, jak w poprzednim przypadku korzystamy z funkcji describe polecenia kubectl:

kubectl describe pod <nazwa-poda>

W identyczny sposób jak poprzednio zostaną wyświetlone szczegółowe informacje, dotyczące poda. Natomiast to, co nas będzie interesowało, znajduje się na samym dole wyświetlanego wyniku. Jeżeli podowi nie uda się pobrać obrazu, z którego ma stworzyć kontener, to w sekcji zdarzeń wyświetlony będzie komunikat typu: nie można znaleźć obrazu kontenera lub wystąpił błąd uwierzytelniania. W języku angielskim może brzmieć to tak: the container image could not be found or that there was an authentication error. W tej sytuacji pod będzie w stanie oczekiwania, czyli Waiting.

Service connection failures: usługi są używane do udostępniania zasobników w sieci. Zapewniają stabilny adres IP i nazwę DNS dla podów, umożliwiając łączenie się z nimi innym usługom. Awarie połączenia usługi mogą wystąpić, gdy Kubernetes nie może nawiązać połączenia między usługami lub gdy występują problemy z konfiguracją sieci.

W tym wypadku postępujemy identycznie, czyli korzystamy z funkcji describe polecenia kubectl:

kubectl describe pod <nazwa-poda>

Przechodzimy na sam dół otrzymanego wyniku polecenia i gdy zostanie wyświetlony komunikat typu pod, jest w stanie niepowodzenia lub CrashLoopBackOff z powodu błędu połączenia oznaczać to będzie o problemach związanych z połączeniem. Komunikat w języku angielskim powinien być wypisany w następujący sposób pod is in a Failed or CrashLoopBackOff state due to a connection error.

Powyżej zaprezentowałem trzy najczęściej występujące problemy z Kubernetesem. Istnieje bardzo duża szansa, że w trakcie używania napotkasz się z którymś z wymienionych lub nawet z nimi wszystkimi. Pamiętajcie, niezależnie od poziomu waszej wiedzy oraz umiejętności popełnienie błędu jest czymś normalnym. Nie powinno to nikogo dziwić, jednak jak negatywne wydaje się samo popełnienie błędu, to pozytywne postrzegana jest umiejętność naprawy. Dlatego pamiętaj, że jeżeli chodzi o debugowanie i sprawdzenie, gdy coś nie działa funkcja describe Kubernetesa, jest nieodzowną pomocą.

Logi w Kubernetes

Logi czy też, jeżeli wolisz dzienniki w Kubernetesie tak jak i w systemach operacyjnych są cennym elementem do przeprowadzenia wszelkiego rodzaju diagnostyki w celu rozwiązania problemów. Są one przechowywane w dwóch miejscach: wewnątrz kontenera oraz w klastrze. Dzienniki kontenera zawierają informacje o aplikacji działającej w kontenerze, podczas gdy dzienniki klastra zawierają informacje o samych komponentach Kubernetes.

W celu uzyskania dostępu do dzienników korzystamy z polecenia:

kubectl logs …

Aby pobrać logi kontenera, powinniśmy skorzystać z polecenia:

kubectl logs <nazwa-pod> <nazwa-kontenera-w-podzie>

Natomiast aby uzyskać dostęp do dzienników klastra, pierwsze co należy wyświetlić to jego przestrzenie nazw:

kubectl get namespaces
NAME            STATUS   AGE
default         Active   49d
kube-node-lease   Active   49d
kube-public     Active   49d
kube-system     Active   49d

Korzystam z minikube i takimi przestrzeniami nazw dysponujemy domyślnie. Jak zapewne wiesz, automatycznie wszystkie pody są dodawane do przestrzeni określonej jako default (domyślna). Natomiast pozostałe są to przestrzenie nazw klastra. W celu wydobycia logów z poda z danej przestrzeni nazw, a tym samym z klastra, powinniśmy wyświetlić ponownie listę podów, ale z określonej przez nas przestrzeni nazw. Robimy to w następujący sposób:

kubectl get pods --namespace=kube-system
NAME                               READY   STATUS    RESTARTS   AGE
coredns-565d847f94-t5sv8           1/1   Running   8 (57m ago)   49d
etcd-minikube                      1/1   Running   8 (57m ago)   49d
kube-apiserver-minikube            1/1   Running   8 (57m ago)   49d
kube-controller-manager-minikube   1/1   Running   8 (57m ago)   49d
kube-proxy-pl6gp                   1/1   Running   8 (57m ago)   49d
kube-scheduler-minikube            1/1   Running   8 (57m ago)   49d
storage-provisioner                1/1   Running   13 (56m ago)   49d

W tym wypadku wyświetliłem wszystkie dostępne pody znajdujące się w określonej przestrzeni nazw. Teraz, aby wyciągnąć logi, z określonego poda, korzystam z polecenia:

kubectl logs kube-scheduler-minikube --namespace=kube-system

W podobny sposób jesteśmy w stanie, uzyskać opis poda we wskazanej przestrzeni nazw:

kubectl describe pod kube-scheduler-minikube --namespace=kube-system

Na końcu dopowiem, aby skrócić objętościowo polecenie, możesz skorzystać ze skróconej formy opcji –namespace, czyli -n:

kubectl logs kube-scheduler-minikube -n kube-system
kubectl describe pod kube-scheduler-minikube -n kube-system

W ten oto sposób dowiedziałeś się jak możesz uzyskać dostęp, do logów poda i klastra.

Różne typy dzienników

Tak jak mogłeś zauważyć z poprzedniego paragrafu, w Kubernetes dostępnych jest kilka różnych typów dzienników. Dzięki nim ułatwiamy diagnozowanie i rozwiązywanie problemów w klastrze. Możemy je podzielić na trzy kategorie:

  • dzienniki kontenerów;
  • dzienniki węzłów;
  • dzienniki na poziomie klastra.

Dzienniki kontenerów to logi generowane przez aplikacje działające w kontenerach poda. Zawierają one informacje o tym, co dzieje się w kontenerze, jak na przykład zdarzenia aplikacji, błędy i ostrzeżenia. Sposób na dostanie się do tych logów poznałeś w poprzednim paragrafie.

Dzienniki węzłów to logi generowane przez węzły w klastrze Kubernetes. Te dzienniki zawierają informacje o zdarzeniach systemowych występujących w każdym węźle jak na przykład wykorzystanie zasobów, łączność sieciowa i użycie dysku. Dostęp do dzienników węzła można uzyskać za pośrednictwem systemu operacyjnego węzła za pomocą narzędzi takich jak journalctl lub syslog. Tym zajmiemy się w dalszej części materiału.

Dzienniki na poziomie klastra to dzienniki generowane przez same komponenty Kubernetes. Te dzienniki zawierają informacje o systemie Kubernetes, takie jak żądania serwera interfejsu API, zdarzenia menedżera kontrolera i zdarzenia harmonogramu. Dostęp do dzienników na poziomie klastra można uzyskać za pomocą polecenia kubectl logs z odpowiednimi flagami. Wykonywaliśmy to w poprzednim paragrafie.

Dostęp do dzienników węzłów

Aby uzyskać dostęp do dzienników węzła, powinieneś użyć narzędzi systemu operacyjnego w samym węźle. Dlatego co robimy jako pierwsze, to logujemy się do naszego węzła. W związku z tym, że korzystam z minikube, loguję się za pomocą polecenia:

minikube ssh

W celu wyświetlenia logów powinienem wprowadzić polecenie w następujący sposób:

journalctl -u kubelet
Hint: You are currently not seeing messages from other users and the system.
     Users in the 'systemd-journal' group can see all messages. Pass -q to
     turn off this notice.
No journal files were opened due to insufficient permissions.

Logi są dostępne tylko z poziomu administratora, dlatego muszę do tego celu skorzystać z sudo:

sudo journalctl -u kubelet

Spowoduje to wyświetlenie dzienników usługi kubelet w węźle.

Użycie kubectl do rozwiązywania problemów z różnymi typami błędów

Choć ten paragraf może być pewnego rodzaju powtórką, to jednak postanowiłem go napisać w celu ułatwienia szukania. W tym miejscu chcę przytoczyć jawną sytuację i gdy ona wystąpi wskazać polecenie, dzięki któremu będziemy w stanie odnaleźć informacje, czym zdarzenie zostało spowodowane.

Pod scheduling failures

Jeżeli pojawi się komunikat o błędzie, taki jak 0/1 nodes are available: 1 node(s) had taints that the pod didn’t tolerate, w celu weryfikacji błędu powinieneś skorzystać z polecenia:

kubectl describe pod <nazwa-poda>

W ten sposób otrzymasz więcej informacji, dlaczego pod nie uruchomił się.

Container image pull errors

Jeżeli pojawi się komunikat o błędzie, taki jak: Failed to pull image „nginx” from docker.io/nginx:latest: image pull failed for docker.io/nginx:latest, this error message will show up when we try to run a container, powinieneś skorzystać z polecenia:

kubectl logs <nazwa-poda> <nazwa-kontenera>

Dzięki temu wyświetlisz logi kontenera znajdującego się w danym podzie.

Service connection failures

Jeżeli pojawi się komunikat o błędzie, taki jak connection refused, na początku powinieneś użyć polecenia:

kubectl get services

Dzięki temu wyświetlą się wszystkie usługi w klastrze. Następnie powinieneś skorzystać:

kubectl describe service <nazwa-serwisu>

Tak otrzymasz szczegółowe informacje o usłudze i o Endpointach.

Architektura Kubernetesa a logi

Na końcu chciałbym napisać o dość ważnym zagadnieniu, jakim jest ogólne rozumienie Kubernetesa. Wiem, że pod tytułowym słowem architektura może się kryć wiele. Dlatego pisząc prościej, aby skutecznie reagować na pojawiające się błędy i problemy w Kubernetes, musimy go dobrze rozumieć, a dokładniej musimy wiedzieć, w jaki sposób jego komponenty współpracują ze sobą. Poniżej przedstawiam niektóre z narzędzi czy też możliwości, z jakich powinniśmy korzystać, aby wspomóc rozwiązywanie problemów przez co lepiej go zrozumieć.

Użyj etykiet i adnotacji

Dzięki nim pomagasz w samej organizacji zasobów poprzez dostarczanie dodatkowych informacji na ich temat. W ramach przykładu:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: example-app
  labels:
    app: example
    env: production
  annotations:
    description: To jest przykład użycia etykiet i adnotacji
spec:
  replicas: 3
  selector:
    matchLabels:
      app: example
      env: production
  template:
    metadata:
      labels:
        app: example
        env: production
      annotations:
        version: "1.0.0"
    spec:
      containers:
      - name: example-container
        image: example-image:latest
        ports:
        - containerPort: 8080

Monitoruj klaster / klastry

Monitorowanie może pomóc wykryć błędy, zanim staną się one krytyczne. Możesz użyć narzędzi takich jak Zabbix, Prometheus lub Grafana do monitorowania metryk, takich jak użycie procesora i pamięci, a także metryki specyficzne dla uruchomionej aplikacji.

Aktualizacje klastra

Aktualizowanie klastra Kubernetes może pomóc uniknąć znanych problemów i luk w zabezpieczeniach. Pamiętaj o regularnym aktualizowaniu klastra do najnowszej stabilnej wersji.

Przetestuj swoją aplikację

Testowanie aplikacji w środowisku deweloperskim przed wdrożeniem jej w środowisku produkcyjnym może pomóc w zidentyfikowaniu błędów i problemów. Może to pomóc w uniknięciu przestojów lub innych problemów w środowisku produkcyjnym.

Użyj rejestrowania i śledzenia

Rejestrowanie i śledzenie może pomóc w diagnozowaniu błędów, dostarczając szczegółowych informacji o tym, co się stało w aplikacji. Korzystając z narzędzi takich jak Fluentd lub Jaeger, możesz zbierać i analizować dzienniki i ślady, aby identyfikować błędy i rozwiązywać problemy.

Dzięki wdrożeniu tych zasad oraz wspomnianych powyżej rozwiązań wykrywanie i rozwiązywanie błędów będzie znacznie łatwiejsze.

Podsumowanie – debugowanie i logi w Kubernetes

Niestety w przypadku debugowanie i naprawy błędów nie istnieje złoty środek. Z tego materiału dowiedziałeś się jakie są najczęstsze błędy, z którymi borykają się użytkownicy Kubernetesa. Powinieneś wiedzieć, w jaki sposób uzyskać więcej informacji o powstałym problemie. Niestety, nie da się przewidzieć wszystkiego. Jednak dzięki przeanalizowaniu tego samouczka powinieneś wiedzieć w jaki sposób pozyskać niezbędne informacje, aby naprawić zaistniały problem. Mam nadzieję, że debugowanie w Kubernetes będzie już dla Ciebie proste i zrozumiałe.

Chcesz wiedzieć więcej na temat konteneryzacji? Przeczytaj nasze artykuły, a także weź udział w kursach!

Dołącz Do Wyzwania "Opanuj Kontenery"!

Do 30 czerwca możesz dołączyć do wyzwania "Opanuj Kontenery". Możesz wziąć udział w pojedynczych kursach, bądź skorzystać z pakietów "Razem taniej". Do odebrania dodatkowo dwa kursy za darmo z kodem "Opanujkontenery2024"!

Chcesz dołączyć do szkolenia! Zapisy na stronie: https://asdevops.pl/kontenery

 
 

Dołącz do wakacyjnego wyzwania "Opanuj Kontenery"!

X