Tworzenie wątków kończy się niepowodzeniem z „Zasobem tymczasowo niedostępnym” z jądrem 4.3

39

Używam serwera dokującego na Arch Linux (jądro 4.3.3-2) z kilkoma kontenerami. Od czasu mojego ostatniego restartu zarówno serwer dokera, jak i losowe programy w kontenerach ulegają awarii z komunikatem o niemożności utworzenia wątku lub (rzadziej) rozwidlenia. Konkretny komunikat o błędzie różni się w zależności od programu, ale większość z nich wydaje się wspominać o konkretnym błędzie Resource temporarily unavailable. Zobacz na końcu tego postu kilka przykładów komunikatów o błędach.

Teraz jest wiele osób, które otrzymały ten komunikat o błędzie i mnóstwo odpowiedzi na nie. Naprawdę frustrujące jest to, że wydaje się, że wszyscy spekulują, w jaki sposób problem można rozwiązać, ale nikt nie wskazuje, w jaki sposób określić, która z wielu możliwych przyczyn problemu jest obecna.

Zebrałem 5 możliwych przyczyn błędu i jak sprawdzić, czy nie występują w moim systemie:

  1. Istnieje ogólnosystemowy limit liczby wątków skonfigurowanych w /proc/sys/kernel/threads-max( źródłowym ). W moim przypadku jest to ustawione na 60613.
  2. Każdy wątek zajmuje trochę miejsca na stosie. Limit wielkości stosu konfiguruje się za pomocą ulimit -s( źródła ). Limit dla mojej skorupy kiedyś 8192, ale zwiększyły się poprzez umieszczenie * soft stack 32768na /etc/security/limits.conf, więc ulimit -spowraca 32768. Zwiększyłem go także dla procesu dokowania, wprowadzając LimitSTACK=33554432do /etc/systemd/system/docker.service( źródło , i zweryfikowałem, że limit ma zastosowanie, patrząc do /proc/<pid of docker>/limitsi uruchamiając ulimit -swewnątrz kontenera dokera.
  3. Każdy wątek zajmuje trochę pamięci. Limit pamięci wirtualnej konfiguruje się za pomocą ulimit -v. W moim systemie jest ustawiony na unlimited, a 80% mojej 3 GB pamięci jest wolne.
  4. Istnieje ograniczenie liczby używanych procesów ulimit -u. Wątki liczą się w tym przypadku jako procesy ( źródło ). W moim systemie limit jest ustawiony na 30306, a dla demona dokera i wewnątrz kontenerów dokowania limit jest 1048576. Liczbę aktualnie uruchomionych wątków można znaleźć, uruchamiając ls -1d /proc/*/task/* | wc -llub uruchamiając ps -elfT | wc -l( źródło ). W moim systemie są między 700i 800.
  5. Istnieje ograniczenie liczby otwartych plików, które według niektórych źródeł ma również znaczenie przy tworzeniu wątków. Limit jest konfigurowany za pomocą ulimit -n. W moim systemie i w oknie dokowanym limit jest ustawiony na 1048576. Liczbę otwartych plików można znaleźć za pomocą lsof | wc -l( źródła ), w moim systemie to chodzi 30000.

Wygląda na to, że przed ostatnim ponownym uruchomieniem uruchomiłem jądro 4.2.5-1, teraz działam 4.3.3-2. Obniżenie wersji do 4.2.5-1 rozwiązuje wszystkie problemy. Inne posty wspominające o tym problemie to i to . Otworzyłem raport o błędzie dla Arch Linux .

Co zmieniło się w jądrze, co mogło to powodować?


Oto kilka przykładowych komunikatów o błędach:

Crash dump was written to: erl_crash.dump
Failed to create aux thread

 

Jan 07 14:37:25 edeltraud docker[30625]: runtime/cgo: pthread_create failed: Resource temporarily unavailable

 

dpkg: unrecoverable fatal error, aborting:
 fork failed: Resource temporarily unavailable
E: Sub-process /usr/bin/dpkg returned an error code (2)

 

test -z "/usr/include" || /usr/sbin/mkdir -p "/tmp/lib32-popt/pkg/lib32-popt/usr/include"
/bin/sh: fork: retry: Resource temporarily unavailable
 /usr/bin/install -c -m 644 popt.h '/tmp/lib32-popt/pkg/lib32-popt/usr/include'
test -z "/usr/share/man/man3" || /usr/sbin/mkdir -p "/tmp/lib32-popt/pkg/lib32-popt/usr/share/man/man3"
/bin/sh: fork: retry: Resource temporarily unavailable
/bin/sh: fork: retry: No child processes
/bin/sh: fork: retry: Resource temporarily unavailable
/bin/sh: fork: retry: No child processes
/bin/sh: fork: retry: No child processes
/bin/sh: fork: retry: Resource temporarily unavailable
/bin/sh: fork: retry: Resource temporarily unavailable
/bin/sh: fork: retry: No child processes
/bin/sh: fork: Resource temporarily unavailable
/bin/sh: fork: Resource temporarily unavailable
make[3]: *** [install-man3] Error 254

 

Jan 07 11:04:39 edeltraud docker[780]: time="2016-01-07T11:04:39.986684617+01:00" level=error msg="Error running container: [8] System error: fork/exec /proc/self/exe: resource temporarily unavailable"

 

[Wed Jan 06 23:20:33.701287 2016] [mpm_event:alert] [pid 217:tid 140325422335744] (11)Resource temporarily unavailable: apr_thread_create: unable to create worker thread
cdauth
źródło
1
Czy ostatnio zaktualizowałeś jądro do wersji 4.3?
Roni Choudhury,
To bardzo możliwe. Czemu?
cdauth
1
Niesamowite, obniżyłem wersję jądra do 4.2.5-1 i wszystko znów działa! Czy masz jakieś pojęcie, co to powoduje i jak to naprawić w wersji 4.3?
cdauth
Nie mam pojęcia, co go powoduje. Moja metoda jego naprawy polega na oznaczeniu wątków forum Arch Linux na ten temat jako „ROZWIĄZANY” :-P.
Roni Choudhury
1
+1 Za bycie doskonale zadanym i przebadanym pytaniem, nawet gdybym nie miał tego samego problemu
Roy Truelove

Odpowiedzi:

47

Problem jest spowodowany przez TasksMaxatrybut systemd. Został wprowadzony w systemie 228 i korzysta z podsystemu pid cgroups, który został wprowadzony w jądrze Linuksa 4.3. Limit zadań 512jest więc włączony w systemd, jeśli jądro 4.3 lub nowsze jest uruchomione. Funkcja została ogłoszona tutaj i została wprowadzona w tym żądaniu ściągnięcia, a wartości domyślne zostały ustawione przez to żądanie ściągnięcia . Po aktualizacji mojego jądra do 4.3 systemctl status dockerwyświetla Taskswiersz:

# systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/etc/systemd/system/docker.service; disabled; vendor preset: disabled)
   Active: active (running) since Fri 2016-01-15 19:58:00 CET; 1min 52s ago
     Docs: https://docs.docker.com
 Main PID: 2770 (docker)
    Tasks: 502 (limit: 512)
   CGroup: /system.slice/docker.service

Ustawienie TasksMax=infinityw [Service]sekcji docker.servicenaprawia problem. docker.servicejest zwykle w /usr/share/systemd/system, ale można go także umieścić / skopiować, /etc/systemd/systemaby uniknąć zastąpienia go przez menedżera pakietów.

Prośba przyciąganie wzrasta TasksMaxdla przykładu Döcker Systemd plików, a także raport o błędzie Arch Linux stara się osiągnąć to samo na opakowaniu. Trwa dodatkowa dyskusja na forum Arch Linux i w raporcie o błędach Arch Linux dotyczącym lxc .

DefaultTasksMaxmoże być użyty w [Manager]sekcji w /etc/systemd/system.conf(lub /etc/systemd/user.confdla usług uruchamianych przez użytkownika) do kontrolowania wartości domyślnej dla TasksMax.

Systemd stosuje również limit dla programów uruchamianych z powłoki logowania. Są one domyślnie ustawione 4096na użytkownika (zostaną zwiększone do12288 ) i są skonfigurowane jak UserTasksMaxw [Login]sekcji /etc/systemd/logind.conf.

cdauth
źródło
1
FWIW, plik serwisowy był /lib/systemd/system/docker.servicew trakcie moich testów Debiana.
Kompilator
2
FWIW, powiedzenie systemctl set-property docker.service TasksMax=4096, ustawi właściwość dla aktualnie uruchomionej usługi i zachowa ustawienie dla kolejnych restartów w odpowiednim miejscu dla danej instalacji dokera.
Nakedible
To jest wspólne podejście . Należy jednak pamiętać, że zaproponowana zmiana Dockera została wycofana po opublikowaniu tej odpowiedzi, 09.02.2016, a ta wersja jest następnie udostępniona światu w wersji 1.10.1 Dockera.
JdeBP
stary dzięki, dzięki! szukałem tego
zbyt
Jeśli dokonasz zmiany w pliku konfiguracyjnym (mój był /etc/systemd/system/docker.service.d/50-TasksMax.confna Ubuntu 16), musisz uruchomić systemctl daemon-reload. Wykonanie sudo service docker restartNIE zadziała.
osman
4

Odpowiedź cdauth jest poprawna, ale należy dodać jeszcze jeden szczegół.

W moim systemie Ubuntu 16.04 z jądrem systemd 229 i jądrem 4.3 domyślnie na zakresach sesji obowiązywał limit 512 pid, nawet gdy UserTasksMax ustawiono na nowy, zwiększony domyślny 12288. Tak więc zakres sesji użytkownika był ograniczony do 512 wątków.

Jedynym sposobem znalazłem się usunąć limit było stworzenie DefaultTasksMax=unlimitedw /etc/systemd/system.confi systemctl daemon-reexec(lub restarcie).

Możesz sprawdzić, czy tak się dzieje, wydając systemctl status, wybierając zakres sesji i cat /sys/fs/cgroup/pids/user.slice/user-${UID}.slice/session-FOO.scope/pids.max.

Ryan C. Underwood
źródło
Dokonałem zmiany w /etc/systemd/system.conf i zrestartowałem. Docker nadal podaje limit zadań jako 512. Użycie powyższego komentarza @ Nakedible zaktualizowało dostępne zadania.
Ben Mathews
1
Dzięki Ryan! @BenMathews może to dlatego, że obie są ważne kwestie na Ubuntu 16.04, trzeba je naprawić zarówno rzeczy do pracy prawidłowo. Wydaje się, że ten problem dotyczy kontenerów uruchomionych przez demona, a nie przez użytkownika w powłoce. Tak więc wszystko wygląda dobrze, dodajesz @reboot lxc-autostartdo swojego crontaba, aby automatycznie uruchamiał je przy rozruchu, i nagle po restarcie dostajesz sparaliżowane pojemniki.
qris
1

Po przeczytaniu tego wątku.

To rozwiązanie pracował dla mnie docker -d --exec-opt native.cgroupdriver=cgroupfs. I rzeczywiście dodaje go do OPTIONSin /etc/sysconfig/docker...

Sebastiaan Pasterkamp
źródło