Wyszukiwanie w witrynie

4 błędy początkującego w Dockerze, które spowodowały wyłączenie mojego homelabu — i jak naprawiłem każdy z nich


Zniszczenie własnego serwera wywołało przygnębiające uczucie, gdy nagle zobaczyłem, jak moja sieć przerywa działanie, a mój pulpit staje się ciemny. Hostuję samodzielnie za pomocą Dockera i było to niesamowicie proste. Jednak przy najmniejszym niedopatrzeniu możesz przypadkowo użyć kontenera jako broni przeciwko swojemu sprzętowi. Przekonałem się o tym na własnej skórze, gdy udusiłem swoje urządzenie nieograniczonymi limitami pamięci i niekontrolowanymi logami.

To tylko jeden z wielu błędów w Dockerze, które popełniłem przez lata. Oto te, których najbardziej żałuję i jak je naprawiłem.

Zignorowałem ograniczenia pamięci

Jedien pojemnik zjadł wszystko

Jestem przyzwyczajony do tego, że systemy operacyjne zarządzają wykorzystaniem pamięci. Na przykład, gdy otwieram kilka kart w przeglądarce, przeglądarka zamraża nieaktywne karty w tle, aby zwolnić RAM. Zakładałem, że Docker działa w ten sposób, ale się myliłem.

To było pewnego popołudnia, po tym jak mój serwer całkowicie się zatrzymał z powodu przekroczonego czasu połączeń SSH i nieodpowiadającego panelu sterowania, że nauczyłem się tej lekcji. Początkowo myślałem, że to awaria sprzętu, ale okazało się, że to pojedynczy kontener zużywający zbyt dużo pamięci.

Domyślnie Docker nie narzuca limitów pamięci na kontenery. Bez zgody, OOM killer systemu Linux kończy procesy w celu odzyskania pamięci, gdy systemowi kończy się RAM. Nawet ważne procesy mogą zostać zakończone.

Morderca OOM priorytetowo traktuje procesy według wyniku, który oblicza automatycznie, co oznacza, że twój najbardziej pamięciożerny kontener może przetrwać, podczas gdy mniejsza, ale krytyczna usługa zostanie zakończona zamiast niego.

Musisz rozpoznać problem, zanim się rozwinie, a uruchomienie poniższego polecenia pokazuje użycie pamięci w czasie rzeczywistym dla każdego kontenera:

docker stats

Jeśli pojawi się problem, staje się on natychmiast oczywisty. Możesz przystąpić do ustalania limitów dla najcięższych kontenerów, otwierając ich plik docker-compose.yml. Dla samodzielnego Docker Compose dodaj to w sekcji serwisu:

services: 
 your-service-name: 
 mem_limit: 512m

Oto nowoczesna składnia dla nowszej konfiguracji używającej Docker Swarm lub nowszej wersji Compose:

services: 
 your-service-name: 
 deploy: 
 resources: 
 limits: 
 memory: 512m

Dzienniki zapełniły mój dysk

Magazyn zniknął z dnia na dzień






Zawsze uważałem, że logi to kwestia zaplecza, która naprawdę ma znaczenie tylko w środowisku produkcyjnym. Nie sądziłem, że powinny wpływać na moją małą domową konfigurację serwera, która miała zaledwie kilka kontenerów. Było to błędne założenie, które kosztowało mnie znacznie więcej czasu na rozwiązywanie problemów, niż chciałbym przyznać.

Kiedy usługi zaczęły zawodzić, nie rozumiałem jak ani dlaczego. Widziałem dziwne błędy, a niektóre kontenery całkowicie przestały zapisywać dane. Nadal podążałem niewłaściwą ścieżką, zakładając, że to uszkodzone instalacje lub awaria sprzętu.

Nie wiedziałem, że nie ma limitu rozmiaru dla logów Docker. Przy jednym czatliwym kontenerze można w ciągu kilku tygodni zapełnić kilka gigabajtów, a Docker nie ostrzega, gdy dysk się zapełnia.

Uruchom df -h/i obserwuj kolumnę Use%, aby sprawdzić dostępne miejsce na dysku.

Aby uniknąć takiej sytuacji, uruchom to polecenie, aby zainstalować ncdu: sudo apt install ncdu. Następnie uruchom to polecenie, aby zobaczyć, co zajmuje miejsce: sudo ncdu /var/lib/docker. Następnym krokiem jest dodanie rotacji logów w pliku docker-compose.yml. Aby to zrobić, zaktualizuj lub dodaj poniższe w sekcji serwisu:

services: 
 your-service-name: 
 logging: 
 driver: json-file 
 options: 
 max-size: "10m" 
 max-file: "3"

Te proste kroki mogą zająć tylko kilka sekund, ale zaoszczędzą ci wiele bólu.

Ufałem najnowszemu

Jedna aktualizacja zepsuła wszystko

Tag latest był wspólnym elementem we wszystkich poradnikach, które czytałem. Oznaczało to, że zawsze korzystałem z najnowszej wersji, a wszystko wyglądało schludnie i nie wymagało konserwacji. Dopiero gdy najnowsza aktualizacja zepsuła usługę, na której mocno polegałem, zrozumiałem, co w praktyce oznacza najnowsza wersja.

Po uruchomieniu nowej aktualizacji nie było żadnych błędów w moim kontenerze. Jednak między wersjami aplikacja w jego wnętrzu uległa zmianie. Zepsuło to moje wcześniejsze konfiguracje, ponieważ nie miały już zastosowania w nowej wersji. Po godzinach bezskutecznego rozwiązywania problemów zdałem sobie sprawę, że nic faktycznie nie było zepsute; po prostu zmieniło się 'pod maską' bez żadnych powiadomień.

Stało się to jeszcze bardziej stresujące, gdy uświadomiłem sobie, że nie ma żadnej bezpośredniej opcji wycofania, ponieważ najnowsza wersja nie zapisuje, co było uruchomione wcześniej. Nie zapisałem mojej konfiguracji, a Docker nie przechowuje tej historii.

Rozwiązaniem jest przypinanie wersji i jest to całkiem proste. Odwiedź stronę obrazu na Docker Hub, a następnie wybierz numer wersji, coś w stylu 1.2.3. Zamiast używać latest, zastąp to 1.2.3. Tak więc your-image:latest staje się your-image:1.2.3. Za każdym razem, gdy pojawi się nowa wersja, uruchom ją na innym porcie, aby ją przetestować, i zaktualizuj swoje główne ustawienie, gdy upewnisz się, że działa idealnie.

Pominąłem kontrole zdrowia

Wszystko wyglądało online

Dopóki wszystkie kontenery działały i widziałem zielone światła na desce rozdzielczej, nie było powodu, by wątpić w moje ustawienia. A potem, nagle, nie mogłem uzyskać dostępu do usługi, która była „zdrowa” i działała poprawnie.

Spędziłem następne dwadzieścia minut na sprawdzaniu moich plików compose, ponownym czytaniu dokumentacji i ponownym uruchamianiu kontenera. W końcu zdałem sobie sprawę, że Docker wie tylko, że proces kontenera działa; tak naprawdę nie raportuje, czy aplikacja wewnątrz działa poprawnie. Na przykład, nawet jeśli strona internetowa zwraca tylko błędy, dopóki działa jako proces, Docker raportuje ją jako aktywną.

Dobrą praktyką jest dodanie healthcheck do pliku docker-compose.yml. Za pomocą prostego polecenia curl do lokalnego portu usługi, uruchamianego co trzydzieści sekund, można szybko wykryć awarie. Oto prosty przykład:

services: 
 your-service-name: 
 healthcheck: 
 test: ["CMD", "curl", "-f", "http://localhost:8080"] 
 interval: 30s 
 timeout: 10s 
 retries: 3

Jednak to Uptime Kuma było narzędziem, które zmieniło sposób, w jaki monitoruję mój homelab. Może wykrywać awarie, które Docker przeoczy, sprawdzając usługi spoza Dockera. Gdy coś przestaje odpowiadać, powiadamia cię natychmiast.

Błąd pod wszystkimi błędami

Główną przyczyną wszystkich błędów, które napotkałem, było założenie, że to, co ustawiłem, jest w porządku. Częściowo można to przypisać temu, jak łatwo Docker umożliwia konfigurację. Kusi, aby po prostu iść dalej. Prawdziwa lekcja polega na tym, że uruchamianie to nie to samo co dobre uruchamianie. Oszczędza to wiele problemów, jeśli poświęcisz popołudnie na audyt swojej konfiguracji. Rzeczy, na które warto zwrócić uwagę, to limity zasobów, otwarte porty i tagi obrazów. W ten sposób nie popełnisz niektórych błędów, które popełniłem.

Powiązane artykuły