Debugowanie kontenerów w 10 minut - Docker/Podman (film, 10m)
W dzisiejszym wpisie Jakub 'unknow' Mrugalski z UW-TEAM.org zabiera nas w podróż przez proces debugowania kontenerów Dockera, szczególnie tych, które są odziedziczone od poprzednich pracowników bez dokumentacji. Automatyzacja konteneryzacji jest kluczowa w wielu projektach, ale co się dzieje, gdy napotykamy błędy w kontenerze, nad którym nie mamy pełnej kontroli? Jakub przedstawia krok po kroku, jak poradzić sobie w takich sytuacjach. Wideo zaczyna się od przykładu kontenera o nazwie 'wywrotka', który ma specjalnie zaprogramowane błędy, aby pokazać różne problemy, jakie mogą wystąpić podczas korzystania z kontenerów bez dokumentacji.
Pierwszy krok w debugowaniu, jak podkreśla Jakub, to uruchomienie kontenera i sprawdzenie jego logów, co pomaga zidentyfikować pierwotny problem. W tym przypadku, wystąpił błąd braku pliku konfiguracyjnego, co zostało szybko zauważone w logach kontenera. Jakub pokazuje również, jak wykorzystać polecenie 'docker inspect', aby znaleźć ścieżki do logów, co może być pomocne w bardziej złożonych przypadkach. Z kolei za pomocą polecenia grep możemy przeszukać logi i ustalić, co tak naprawdę mogło pójść nie tak w kodzie.
Kiedy frontowe błędy są zidentyfikowane, Jakub przechodzi do dalszego analizowania kontenera, pokazując, jak ważne jest zrozumienie jego struktury i komend. Zmieniając elementy w poleceniach, udaje mu się dotrzeć do kluczowych składników kontenera, takich jak pliki startowe. W sposób przemyślany, Jakub uczy nas, jak korzystać z BusyBoxa, aby uruchomić komendy systemowe, które mogą pomóc w badaniu zawartości kontenera. Ostatecznie, udaje mu się wyeliminować problem związany z brakiem pliku konfiguracyjnego, tworząc odpowiednią konfigurację systemową, dzięki czemu kontener zaczyna działać poprawnie.
Oprócz kroków do rozwiązania problemu, Jakub nawiązuje także do bardziej zaawansowanych technik, takich jak eksportowanie kontenerów i obrazów do plików TAR, co pozwala na ich późniejsze odzyskanie w przypadku awarii. Wszelkie te czynności podkreślają znaczenie umiejętności debugowania w codziennym związku z kontenerami. Daje to możliwość nauczenia się, jak skutecznie radzić sobie z podobnymi problemami bez pełnej dokumentacji, która, jak wiemy, nie zawsze jest dostępna w dynamicznym świecie IT.
Na koniec, warto zwrócić uwagę, że wideo Jakuba zdobyło już 7884 wyświetleń i 453 polubień w chwili pisania tego artykułu, co potwierdza jego użyteczność dla osób z branży IT. Z pewnością, umiejętności zdobyte podczas jego prezentacji mogą przynieść korzyści wielu osobom zajmującym się konteneryzacją. Jeżeli ta tematyka Cię interesuje, Jakub poleca swoją Akademię Debugowania Linuxa, gdzie można zgłębić więcej praktycznych zagadnień
Toggle timeline summary
-
Wprowadzenie do pracy z Dockerem i konteneryzacją.
-
Debugowanie własnych kontenerów jest prostsze niż radzenie sobie z odziedziczonymi.
-
Wyzwania pojawiają się, gdy odziedziczysz kontener bez dokumentacji.
-
Możesz napotkać błędy podczas próby uruchomienia odziedziczonego kontenera.
-
Przedstawienie workflow do debugowania problemów z kontenerami.
-
Przygotowano kontener testowy o nazwie 'wywrotka' w celach demonstracyjnych.
-
Aby uruchomić kontener, potrzebny jest konkretny rozkaz.
-
Sukces zależy od tego, czy kontener wyświetla 'sukces'.
-
Kontener nie może być modyfikowany; można jedynie dostosować parametry startowe.
-
Demonstracja poleceń terminala do uruchamiania kontenerów Docker.
-
Uruchamianie polecenia Docker w celu uruchomienia kontenera o nazwie 'analiza'.
-
Początkowe błędy związane z brakującymi plikami konfiguracyjnymi.
-
Inspekcja logów ujawnia stałe problemy z brakującą konfiguracją.
-
Badanie, czy 'busybox' ma dostępne niezbędne polecenia.
-
Wyświetlenie katalogu głównego pokazuje, że 'starter.sh' jest niespodziewanie obecny.
-
Wyjaśnienie obsługi błędów i warunkowych kontroli w skrypcie startowym.
-
Zamontowanie woluminu do Dockera w celu zdefiniowania punktów wejścia.
-
Skuteczne rozwiązanie zadania kontenera przez utworzenie niezbędnych katalogów.
-
Użycie 'docker export' do zapisania kontenera, uchwycenie jego stanu.
-
Badanie warstw obrazu, które zawierają różne stany systemu plików.
-
Dostęp do 'starter.sh' w katalogu warstwy obrazu.
-
Promowanie kursu umiejętności debugowania w systemie Linux dla praktycznej wiedzy.
Transcription
Jest szansa, że na co dzień pracujesz z kontenerami Dockera, Podmana albo jakiejkolwiek innej technologii związanej z konteneryzacją. Jeżeli samodzielnie budujesz kontenery, to oczywiście ich debugowanie jest trochę prostszą sprawą. Problem zaczyna się wtedy, gdy odziedziczyłeś po kimś kontener. Niech to będzie po pracowniku, który już tu nie pracuje. Mało tego, nie ma do niego dokumentacji, nie ma źródeł, jest tylko obraz. Ten obraz trzeba uruchomić, ale nawet jeżeli go uruchomisz, to on się wysypuje, wrzuca jakimiś błędami. Nikt nie wie o co chodzi. Jak teraz zabrać się do debugowania takiego problemu? Chcę Ci pokazać taki prosty workflow, który możesz zastosować po to, aby dowiedzieć się, co siedzi w środku takiego kontenera. Ja na potrzeby testu i na potrzeby tego filmu przygotowałem kontener, który nazywa się wywrotka. On powstał po to, aby się przewracać, czyli rzucać błędami na ekran. I nie daję Ci do niego źródeł celowo, po to, abyś te źródła samodzielnie mógł wydobyć. Aby uruchomić ten kontener, wystarczy wykonać to polecenie, które widzisz na ekranie. I jeżeli nie chcesz spoilerować sobie zabawy, to zatrzymaj film w tym miejscu, spróbuj ten kontener samodzielnie naprawić i dopiero potem przejść dalej. Teraz, co uznajemy za sukces? Sukces jest wtedy, gdy ten kontener wyrzuci na ekran właśnie słowo sukces. I jeżeli tak się stanie, to znaczy, że Ci się udało. Ważna rzecz, kontenera nie można modyfikować, nie można do niego do środka nic doinstalować. I jedyna rzecz, którą możesz robić, to przekazywać mu odpowiednie parametry startowe. Ale jakie parametry? I to jest właśnie treścią zadania. Przejdźmy do terminala, pokażę Ci, jak się do tego zabrać. Zakładam, że znasz podstawę obsługi Dockera i wymowę go zainstalowanego w systemie. Dla pewności wydaję polecenie docker.ps. Wszystko działa dobrze. Sprawdzimy, czy są jakieś jeszcze martwe kontenery. Minus A. Niczego tu nie ma, jest to czysta instalacja Dockera. W takim razie uruchamiam mojego Dockera. Docker run, minus IT, czyli interaktywny z alokacją terminala. Nadaję mu nazwę, na przykład analiza. A następnie podaję unknown przez wywrotka. I to powinno wystarczyć. Enter. Obraz zaczyna się ściągać. Chwilę czekamy, aż się zakończy i widzimy od razu error. Brak pliku konfiguracyjnego. To nie jest błąd Dockera, tylko błąd tego obrazu. Czyli coś w środku poszło nie tak. Pytanie już mi co? Sprawdzimy sobie tutaj, czy ten kontener działa. Nie. Czy jest na liście zakończonych? Tak. A nowy wywrotka zakończony? Zwróćcie tylko uwagę na jedną rzecz. W kolumnie command mamy tutaj entry point. Zostawione na . . . Nie wiadomo co to jest. Warto byłoby zobaczyć o co tutaj chodzi. No i oczywiście tu jest nazwa kontenera, analiza. Sprawdzimy sobie w takim razie jeszcze logi. Logi i analizy. No jest dokładnie to co było na ekranie, czyli brak pliku konfiguracyjnego. Taka mała sztuczka jeszcze tutaj może Ci się przydać. Możemy sobie zrobić inspect na analizie. I grepnąć po słowie log. Wtedy dostaniemy ścieżkę do logów w formacie JSON. I tam jest trochę więcej informacji. Jeżeli będziesz kiedykolwiek analizować jakąś bardziej złożoną aplikację, to Ci się może przydać. Dlaczego? Bo tam są znaczniki czasu. O której godzinie dokładnie dany błąd wystąpił. Godzina, minuta, sekunda, strefa czasowa i inne takie rzeczy. Ale dobra. To nam nic nie dało. W takim razie możemy sobie tutaj grepnąć po czymś innym. Zobaczymy jaki jest tutaj entry point. Czyli daję sobie grep entry. No i tu widzimy, że muszę jeszcze kilka linii wyprintować. No i tutaj mamy entry point. Dużo kropek i slashe na końcu starter.sh Co to znaczy? To coś, co jest tylko zaciemnianiem. Tak dużo razy dajesz polecenie idź do góry, idź do góry, idź do góry, że wyjdziesz do ruta. No i okazuje się, że ten plik po prostu jest w rucie. Teraz sobie go ściągnę. Kategorię kluczowasową załowę tutaj o nazwie tmp. A następnie docker.cp. Czyli kopiowanie pliku z wnętrza kontenera. Nazwa kontenera. Analiza. Dwukropek i tu jest ścieżka do pliku. Jest to oczywiście slash. I tu dajemy starter.sh. No i gdzie to ma skopiować? Nikt mi to skopiuje do wnętrza mojego katalogu tmp. Enter. Nie ma takiego pliku jak starter.sh. To ciekawe, bo przecież jest zdefiniowany jako entry point. Coś się nie zgadza. Podejdźmy do tego inaczej. Uruchomię tymczasową instancję mojego kontenera. Czyli docker.run. Minus it, tak jak było wcześniej. I na koniec oczywiście nazwa naszego obrazu. Czyli anno ułamane przez wywrotka. I to powinno nam wygenerować dokładnie taki sam error jak wcześniej. Zgadza się. I teraz jedna taka sztuczka. Można czasami zdefiniować tu polecenie do uruchomienia. Czyli binbash. Podaj mi powłokę. No to nie działa. Dlaczego? Ten binbash może być uruchomiony tylko wtedy, jeżeli ktoś w docker.file użył polecenia cmd do uruchomienia. Jeżeli ma uruchomionego entry pointa, to jest to ścieżka do binarki, która ma się uruchomić. Czyli binbash. Daję Enter. I co się okazuje, nie działa. Dlaczego? No bo nie ma takiego pliku. Nie ma na dysku pliku binbash. Przecież nie jest powiedziane, że ktoś tworzył obraz z pełnej dystrybucji linuxowej. Może to być bardzo zaoptymalizowana dystrybucja. Może jest w takim razie binsh. Czasami, jeżeli korzystam z dystrybucji alpine, może być binash. Sprawdzimy czy jest. Już nie ma. Mogę spróbować odpalić jakąś binarkę dostępną niemal w każdej dystrybucji linuxa, czyli np. ls do listowania plików, ale tego też nie ma. To jest bardzo obcięty kontener pod względem zawartości. No to co możemy zrobić? Sprawdzić, czy jest coś takiego jak multi-exec binary o nazwie busybox. Busybox to jest taka paczka, która zbiera w sobie różne inne polecenia i okazuje się, że tak jest zainstalowane. Czy jest tu ls? Jest ls. To co daje już na końcu, będzie parametrem startowym do tego co jest entry pointem. I w ten sposób wylistowałem zawartość głównego katalogu. Zobacz co tu jest ciekawego. Starter.sh. Przecież go nie było wcześniej. Coś jest na rzeczy. Możemy sobie go podglądać za pomocą polecenia cat. Też użyję busyboxa tak jak wcześniej, ale tutaj dam sobie cat i ścieżka, czyli slash starter.sh. No i zobaczymy jak on wygląda. Co ciekawego tu jest na początku? Widzimy, że tutaj jest jakaś dziwna powłoka, dalej mamy funkcję fail, która wyświetla napis error, a następnie to co podano jako parametr i tajemnicze RM$0. Co to jest ten $0? $0 to jest ten skryt, który właśnie wykonujemy, czyli w przypadku wystąpienia jakiegokolwiek błędu plik startowy jest usuwany. Dlatego nie było go w obrazie. Dalej mamy sprawdzenie, czy istnieje coś takiego, co jest zdefiniowane w zmiennej CFG. A w CFG jest ścieżka app.config. Czy w ogóle katalog app istnieje? No nie istnieje. Wypadałoby go załować. Tylko są jakieś inne katalogi. Wynik działania 2 plus 2 razy 2, czyli 6. To jest kolejność wykonywania działań, ważne. I teraz widzimy tu wczytanie naszego configa z tego pliku, czyli musi on na pewno istnieć. I następnie jest sprawdzenie, czy jest tam w ogóle zmienna version. Jeżeli nie ma, no to wrzucamy, bo nie wiadomo, jaka wersja oprogramowania. A następnie porównujemy sobie, tutaj jest jakieś porównanie, ne not equal, czyli jeżeli wersja nie jest równa temu, co wychodzi z fixa, to zakończ całość, w przeciwnym wypadku jest sukces. To założymy sobie katalog app. Następnie wrzucimy do niego plik o nazwie config i zdefiniujemy tam zmienną o nazwie version o wartości 6. Teraz tylko trzeba to podmontować do dockera, czyli to polecenie, co było wcześniej. I zdefiniuję zamiast entry pointa minus v, czyli podpięcie wolumenu. I z aktualnego katalogu, czyli zmienna $ to będzie pwd, ten katalog app podmontuje sobie do wnętrza dockera, do ścieżki oczywiście slash app. Sprawdzam teraz, co się dzieje. Sukces. Dokładnie o to chodziło. Udało nam się rozwiązać zadanie. Oczywiście jest to jedno z poprawnych rozwiązań. Nie najlepsze, nie jedyne, tylko jedno z wielu. Ale możemy zrobić jeszcze inną rzecz. Jeżeli mamy dostęp do busyboxa, to zamiast tego kata i innych rzeczy możemy tutaj dać nazwę powłoki. Na przykład bash, o ile akurat busybox został skompilowany z obsługą basha. Sprawdźmy to. Bash, enter, applet not found. No to pewnie jest A-S-H, enter, działa. I teraz jesteśmy w środku kontenera. LSA nie ma, ale możemy tak naprawdę wylistować pliki za pomocą na przykład tabulatora. Dwa razy tab, no i mamy tutaj listę poleceń, plików. Możemy też podać ścieżkę slash, dwa razy tab, no i mamy w zasadzie LSA. Tutaj widzimy, że brakuje nam tego startowego pliku, bo został usunięty. Możemy wejść sobie do binarek i zrobić link symboliczny, czyli LN minus S, symbolik, i podmontować sobie busyboxa. Tu mamy busybox i nazwa polecenia LS. Od tego momentu działa nam LS. LS minus AL, niech tu będzie. O, literówka. I mamy jak najbardziej działającego LSA. W ten sposób możemy dobrać się do wielu innych poleceń systemowych. Sprawdzimy teraz tutaj. Tak, nasz starter istnieje i możemy sobie go przeglądać, jeżeli jest nam to potrzebne. Kolejna umiejętność, która może Ci się przydać, to eksportowanie już uruchomionego albo zabitego kontenera do pliku, czyli docker export, a następnie nazwa naszego kontenera, czyli mamy tu analiza. I przekierowujemy to oczywiście do pliku zewnętrznego z dostrzeżeniem kropka tar. Enter. I gotowe, wyeksportowany. Sprawdzimy sobie, ile on tam zajmuje. On zajmuje dokładnie tyle, ile nasz kontener, czyli 9.3 MB. I teraz jak wejść do środka? Możemy go zdekompensować, ale najprościej MC i do środka sobie wchodzimy po prostu klawiszem Enter. I tak możemy grzebać, ale zwróć uwagę, to nam w niczym nie pomoże, dlatego, że to już jest zabity kontener, który już zdążył usunąć plik startowy. Nie ma tu starter SH. Możemy więc zrobić coś innego. Usuwam ten plik z analizą i eksportuję teraz nie kontener, a obraz. Zwróć uwagę na inne polecenie. Zamiast eksportu jest save, a teraz nazwa nie kontenera, a nazwa obrazu. Gdzie zapisać go? Do pliku analiza2.tar a teraz nazwa naszego obrazu to będzie unknow, łamane przez wywrotka. I tu oczywiście po dwukropku dajemy sobie taga. Niech to będzie latest, bo tylko taki tu istnieje, więc wpiszę sobie go. Dwukropek, latest, Enter. I powstał nam ten plik. Sprawdzimy, ile on teraz zajmuje. Zajmuje dokładnie tyle samo, co uruchomiony kontener. Ja to MC, wchodzę do środka i tu jest zaskoczenie. Tu są warstwy tak zwane. Nie znajdziemy tu gołych plików, tylko w tych katalogach mamy tutaj konkretne warstwy. Warstwa tam pierwsza, druga, trzecia. Musimy pogrzebać w tym i zobaczyć, co w środku tych warstw się znajduje. Założę tymczasowy katalog. Nazwę jeden na przykład. Wezmę sobie tego Layera1 i po prostu wejdę do niego Enterem. A! Trafiony, zatopiony. Tu jest Start LSH. Mogę sobie tutaj klawiszem F3 podglądnąć i widzę dokładnie to, co chciałem. Więc w ten sposób możesz dobierać się do files systemu Twoich obrazów i też kontenerów w zależności od tego, czy użyjesz Save czy Export. Jeśli czujesz, że tego rodzaju umiejętności mogą przydać Ci się w codziennej pracy, to rzuć okiem na moje pokolenie. Akademia Debugowania Linuxa. Znajdziesz tam wiele godzin poradników związanych z debugowaniem problemów z siecią, z DNS-ami, z certyfikatami, z kontenerami. W zasadzie ze wszystkim, co możecie spotkać w systemie operacyjnym Linux. Linka masz pod filmem, więc kliknij i zobacz agendę. A przy okazji znajdziesz tam dodatkowe lekcje pokazowe. Napisy stworzone przez społeczność Amara.org