Dlaczego uruchomiony kontener zachowuje stary limit pamięci po zmianie pliku Compose?

Eva Wong jest Technicznym pisarzem i stałym majsterkowiczem w ZimaSpace. Całe życie geek z pasją do homelabów i oprogramowania open-source, specjalizuje się w tłumaczeniu skomplikowanych koncepcji technicznych na przystępne, praktyczne przewodniki. Eva wierzy, że samodzielne hostowanie powinno być zabawą, a nie czymś onieśmielającym. Poprzez swoje samouczki umożliwia społeczności rozwiewanie tajemnic konfiguracji sprzętu, od budowy pierwszego NAS po opanowanie kontenerów Docker.

Działający kontener zachowuje stary limit pamięci, gdy zmieniona konfiguracja Compose nie została zastosowana do aktywnego cgroup tego kontenera.

Zmiana pliku YAML sama w sobie nie modyfikuje istniejącego kontenera, a zwykły restart uruchamia ten sam kontener z tą samą konfiguracją ustaloną podczas jego utworzenia. Nieporozumienia wynikają również z porównywania twardego limitu pamięci z rezerwacją, limitem swapu, nadrzędnym zakresem systemd lub ustawieniem sterty aplikacji. Przed stwierdzeniem, że Docker zignorował zmianę, sprawdź rzeczywistą wartość cgroup i identyfikator kontenera.

Odczytaj aktywny limit cgroup zamiast ufać plikowi YAML

Zapisz identyfikator kontenera, czas jego utworzenia, dane z inspekcji Dockera, wersję cgroup oraz pliki sterujące pamięcią używane przez działający proces.

Jądro Linuksa definiuje memory.max jako twardy limit cgroup, natomiast memory.high wywołuje presję odzyskiwania pamięci, ale nie działa jako taki sam bezwzględny limit.

Jeśli aktywny cgroup nadal zawiera starą wartość, konfiguracja nie została zastosowana. Jeśli zawiera nową wartość, ale monitoring pokazuje coś innego, sprawdź jednostki, rozliczanie pamięci podręcznej, swap oraz metryki na poziomie aplikacji.

Odróżnij restart od ponownego utworzenia kontenera

Porównaj identyfikator kontenera przed wykonaniem polecenia wdrażającego zmianę i po nim. Zapisz, czy użyto polecenia restart, up, create, działania w interfejsie NAS czy bezpośredniej aktualizacji Dockera.

Docker informuje, że restart Compose nie stosuje zmian konfiguracji, ponieważ uruchamia ponownie istniejące kontenery usług.

Użyj kontrolowanej aktualizacji Compose, która ponownie utworzy usługę, albo — gdy jest to właściwe — obsługiwanej aktualizacji zasobów działającego kontenera. Zachowaj wcześniejsze dane z inspekcji, aby można było zweryfikować zmienione pole.

Zweryfikuj końcowy model Compose i pole pamięci

Wygeneruj efektywną konfigurację Compose po zastosowaniu wszystkich plików, profili i podstawień zmiennych środowiskowych. Sprawdź, czy limit należy do aktywnej usługi.

Specyfikacja Compose definiuje mem_limit jako limit pamięci usługi i wymaga spójności, gdy zadeklarowano również równoważne limity wdrażania.

Wartość w nieużywanym pliku nadpisującym, nieaktywnym profilu, błędnie zapisanej nazwie usługi lub innym interfejsie Stack nie zmieni wdrożonego modelu. Porównaj wygenerowaną konfigurację z inspekcją Dockera.

Oddziel twardy limit, rezerwację i swap

Zapisz twardy limit pamięci, rezerwację lub miękki limit, limit swapu, bieżące i szczytowe zużycie oraz zdarzenia OOM. Nie traktuj każdej wartości związanej z pamięcią jako jednego limitu.

Dokumentacja kontroli zasobów systemd rozróżnia MemoryHigh i MemoryMax oraz pokazuje, że nadrzędne cgroup mogą nakładać dodatkowe limity na usługi i kontenery.

Kontener może pozornie przekraczać rezerwację, ponieważ rezerwacja nie jest tym samym co twardy limit. Może również używać swapu lub pamięci podręcznej stron, której jeden z pulpitów nie uwzględnia albo raportuje osobno.

Sprawdź, czy środowisko uruchomieniowe ma własny limit sterty

W przypadku aplikacji Java zapisz informacje o wykrywaniu ograniczeń kontenera przez JVM, maksymalnym rozmiarze sterty, pamięci bezpośredniej, metaspace, stosach wątków oraz flagach przekazywanych przez obraz lub konfigurację aplikacji.

Oracle dokumentuje, że JVM dobiera rozmiar sterty na podstawie dostępnych ograniczeń pamięci i umożliwia użycie MaxRAMPercentage do ustawienia udziału pamięci przeznaczonego na stertę.

Zmiana limitu kontenera może nie przynieść oczekiwanego rozmiaru sterty aplikacji, jeśli nadal obowiązuje jawne -Xmx lub wartość procentowa. Pamięć sterty nie jest również całkowitym zużyciem pamięci przez proces.

Sprawdź limity Node.js i inne ograniczenia na poziomie aplikacji

Sprawdź flagi środowiska uruchomieniowego, zmienne środowiskowe, liczbę procesów roboczych, pamięci podręczne oraz wewnętrzne docelowe wartości pamięci. Porównaj je z limitem systemu operacyjnego.

Node.js opisuje max-old-space-size jako limit sterty V8, który może pozostać niezmieniony nawet po przyznaniu kontenerowi większego lub mniejszego limitu cgroup.

Limit kontenera chroni hosta, ale nie dostosowuje automatycznie każdej aplikacji. Ustaw limit środowiska uruchomieniowego poniżej limitu kontenera, pozostawiając zapas na alokacje natywne i pamięć podręczną systemu plików.

Zastosuj jedną zmianę i zweryfikuj ją przy kontrolowanym obciążeniu

Wygeneruj końcowy model Compose, ponownie utwórz tylko zmienioną usługę, potwierdź nowy identyfikator kontenera i aktywny cgroup, a następnie uruchom ograniczone obciążenie, obserwując zużycie pamięci i zdarzenia OOM.

Artykuł ZimaSpace Tech & AI Hub wyjaśnia, co dzieje się po osiągnięciu aktywnego limitu kontenera; ten artykuł skupia się na potwierdzeniu, że zmieniony limit został rzeczywiście wdrożony.

Problem jest rozwiązany, gdy wygenerowana konfiguracja, inspekcja kontenera, pliki cgroup, sterta środowiska uruchomieniowego i zaobserwowana granica awarii są zgodne z zamierzoną polityką po ponownym uruchomieniu systemu.

Najczęściej zadawane pytania

Czy restart kontenera stosuje zmieniony limit pamięci Compose?

Nie. Restart zazwyczaj korzysta z tej samej konfiguracji istniejącego kontenera. Utwórz usługę ponownie albo użyj obsługiwanej aktualizacji działającego kontenera.

Czy kontener może tymczasowo przekroczyć twardy limit pamięci?

Rozliczanie przez jądro i odzyskiwanie pamięci mogą chwilowo pokazywać wartości bliskie granicy lub nieznacznie ją przekraczające, ale utrzymujące się, niemożliwe do odzyskania zużycie przy twardym limicie prowadzi do obsługi OOM przez cgroup.

Dlaczego aplikacja nadal zgłasza stary rozmiar sterty?

Środowisko uruchomieniowe aplikacji może mieć jawną flagę sterty albo obliczać wartość procentową tylko podczas uruchamiania. Po zweryfikowaniu limitu kontenera utwórz kontener ponownie lub uruchom aplikację ponownie.

Wsparcie i wskazówki

Więcej do przeczytania

Get More Builds Like This

Stay in the Loop

Get updates from Zima - new products, exclusive deals, and real builds from the community.

Stay in the Loop preferences

We respect your inbox. Unsubscribe anytime.