Das Erstellen von Threads schlägt mit "Ressource vorübergehend nicht verfügbar" im 4.3-Kernel fehl

39

Ich verwende einen Docker-Server unter Arch Linux (Kernel 4.3.3-2) mit mehreren Containern. Seit meinem letzten Neustart stürzen sowohl der Docker-Server als auch zufällige Programme in den Containern mit der Meldung ab, dass kein Thread erstellt werden kann oder (seltener) ein Zweig erstellt werden muss. Die spezifische Fehlermeldung ist je nach Programm unterschiedlich, aber die meisten scheinen den spezifischen Fehler zu erwähnen Resource temporarily unavailable. Am Ende dieses Beitrags finden Sie einige Beispiele für Fehlermeldungen.

Jetzt gibt es viele Leute, die diese Fehlermeldung erhalten haben, und viele Antworten auf diese. Was wirklich frustrierend ist, ist, dass jeder darüber zu spekulieren scheint, wie das Problem gelöst werden könnte, aber niemand darauf hinzuweisen scheint, wie zu identifizieren ist, welche der vielen möglichen Ursachen für das Problem vorhanden sind.

Ich habe diese 5 möglichen Ursachen für den Fehler gesammelt und wie Sie überprüfen, ob sie auf meinem System nicht vorhanden sind:

  1. Es gibt ein systemweites Limit für die Anzahl der Threads, die in /proc/sys/kernel/threads-max( Quelle ) konfiguriert sind . In meinem Fall ist dies eingestellt auf 60613.
  2. Jeder Thread nimmt etwas Platz im Stapel ein. Die Stapelgrößenbegrenzung wird mit ulimit -s( Quelle ) konfiguriert . Die Grenze für meine Schale verwendet werden 8192, aber ich habe es erhöht , indem sie * soft stack 32768in /etc/security/limits.conf, so dass er ulimit -sjetzt zurückkehrt 32768. Ich habe erhöht es auch für die Docker Prozess , indem sie LimitSTACK=33554432in /etc/systemd/system/docker.service( Quelle , und ich festgestellt , dass die Grenze , indem Sie gilt in /proc/<pid of docker>/limitsund durch Ausführen von ulimit -sin einem Docker - Container.
  3. Jeder Thread braucht etwas Gedächtnis. Ein virtuelles Speicherlimit wird mit konfiguriert ulimit -v. Auf meinem System ist es auf eingestellt unlimited, und 80% meiner 3 GB Speicher sind frei.
  4. Die Anzahl der verwendeten Prozesse ist begrenzt ulimit -u. Threads gelten in diesem Fall als Prozesse ( Quelle ). Auf meinem System ist das Limit auf festgelegt 30306, und für den Docker-Daemon und in Docker-Containern beträgt das Limit 1048576. Die Anzahl der aktuell ausgeführten Threads kann durch Ausführen ls -1d /proc/*/task/* | wc -loder durch Ausführen ps -elfT | wc -l( Quelle ) ermittelt werden. Auf meinem System sind sie zwischen 700und 800.
  5. Die Anzahl der geöffneten Dateien ist begrenzt, was laut einigen Quellen auch für das Erstellen von Threads relevant ist. Das Limit wird mit konfiguriert ulimit -n. Auf meinem System und in Docker ist das Limit auf festgelegt 1048576. Die Anzahl der geöffneten Dateien kann mit lsof | wc -l( source ) ermittelt werden, auf meinem System geht es darum 30000.

Es sieht so aus, als ob ich vor dem letzten Neustart Kernel 4.2.5-1 ausgeführt habe, jetzt 4.3.3-2. Ein Downgrade auf 4.2.5-1 behebt alle Probleme. Andere Beiträge, die das Problem erwähnen, sind dies und das . Ich habe einen Fehlerbericht für Arch Linux geöffnet .

Was hat sich im Kernel geändert, das dies verursachen könnte?


Hier sind einige Beispielfehlermeldungen:

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
quelle
1
Haben Sie kürzlich ein Upgrade auf den 4.3-Kernel durchgeführt?
Roni Choudhury
Das ist sehr gut möglich. Warum?
Cdauth
1
Erstaunlich, ich habe ein Downgrade auf Kernel 4.2.5-1 durchgeführt und alles funktioniert wieder! Haben Sie eine Ahnung, was dies verursacht und wie es mit 4.3 behoben werden kann?
Cdauth
Keine Ahnung, was es verursacht. Meine Methode zur Fehlerbehebung wartet darauf, dass die Arch Linux-Forenthreads zum Thema mit "Gelöst" gekennzeichnet werden :-P.
Roni Choudhury
1
+1 Für eine hervorragend gestellte und recherchierte Frage, auch wenn ich nicht das gleiche Problem hatte
Roy Truelove

Antworten:

47

Das Problem wird durch das TasksMaxAttribut systemd verursacht . Es wurde in systemd 228 eingeführt und verwendet das Subsystem cgroups pid, das im Linux-Kernel 4.3 eingeführt wurde. Ein Task-Limit von 512ist daher in systemd aktiviert, wenn Kernel 4.3 oder neuer ausgeführt wird. Die Funktion wird hier angekündigt und wurde in dieser Pull-Anforderung eingeführt, und die Standardwerte wurden durch diese Pull-Anforderung festgelegt . Nach dem Upgrade meines Kernels auf 4.3 wird systemctl status dockereine TasksZeile angezeigt :

# 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

Das Einstellen TasksMax=infinityim [Service]Abschnitt von docker.servicebehebt das Problem. docker.serviceist normalerweise in /usr/share/systemd/system, kann aber auch eingefügt / kopiert werden /etc/systemd/system, um zu verhindern, dass es vom Paketmanager überschrieben wird.

Eine Pull - Anforderung steigt TasksMaxfür das Docker Beispiel systemd - Dateien und ein Arch Linux Bug - Report versucht , das gleiche für das Paket zu erreichen. Im Arch Linux-Forum und in einem Arch Linux-Fehlerbericht zu lxc wird eine zusätzliche Diskussion geführt .

DefaultTasksMaxkann im [Manager]Abschnitt in /etc/systemd/system.conf(oder /etc/systemd/user.conffür vom Benutzer ausgeführte Dienste) verwendet werden, um den Standardwert für zu steuern TasksMax.

Systemd wendet auch ein Limit für Programme an, die von einer Login-Shell ausgeführt werden. Diese Standardeinstellungen 4096pro Benutzer (werden auf erhöht12288 ) und werden wie UserTasksMaxim [Login]Abschnitt von konfiguriert /etc/systemd/logind.conf.

cdauth
quelle
1
FWIW, die Servicedatei befand sich /lib/systemd/system/docker.servicein meinem Debian-Test.
Der Compiler
2
Mit FWIW systemctl set-property docker.service TasksMax=4096wird die Eigenschaft für einen aktuell ausgeführten Dienst festgelegt und die Einstellung für nachfolgende Neustarts an der richtigen Stelle für die betreffende Docker-Installation beibehalten.
Nakedible
Dies ist ein gängiger Ansatz . Beachten Sie jedoch, dass die von Ihnen vorgeschlagene Docker-Änderung zurückgesetzt wurde, nachdem Sie diese Antwort am 09.02.2016 gepostet haben. Diese Umkehrung wurde dann in Docker Version 1.10.1 für die Welt freigegeben.
JdeBP
Mann, danke, danke, danke! Ich habe zu lange dafür
gesucht
Wenn Sie die Konfigurationsdatei ändern (meine war in /etc/systemd/system/docker.service.d/50-TasksMax.confUbuntu 16), müssen Sie ausführen systemctl daemon-reload. Einen sudo service docker restartWillen zu tun , funktioniert NICHT.
Osman
4

Die Antwort von cdauth ist richtig, aber es gibt noch ein weiteres Detail hinzuzufügen.

Auf meinem Ubuntu 16.04-System mit systemd 229 und einem 4.3-Kernel wurde standardmäßig ein 512-PID-Limit für Sitzungsbereiche erzwungen, selbst wenn UserTasksMax auf den neuen, erhöhten Standardwert von 12288 festgelegt wurde. Daher war jeder Sitzungsbereich für Benutzer auf 512 Threads beschränkt.

Die einzige Möglichkeit, das Limit zu entfernen, bestand darin, DefaultTasksMax=unlimitedein /etc/systemd/system.confund systemctl daemon-reexec(oder einen Neustart) durchzuführen.

Sie können überprüfen, ob dies geschieht, indem Sie Folgendes ausgeben systemctl status, einen Sitzungsbereich auswählen und cat /sys/fs/cgroup/pids/user.slice/user-${UID}.slice/session-FOO.scope/pids.max.

Ryan C. Underwood
quelle
Ich nahm die Änderung an /etc/systemd/system.conf vor und startete neu. Docker listet das Limit für Aufgaben weiterhin mit 512 auf. Durch die Verwendung des obigen Kommentars von @ Nakedible wurden die verfügbaren Aufgaben aktualisiert.
Ben Mathews
1
Vielen Dank, Ryan! @BenMathews Vielleicht lag das daran, dass es sich bei beiden um gültige Probleme unter Ubuntu 16.04 handelt. Sie müssen beide beheben, damit die Dinge richtig funktionieren. Dieses Problem betrifft anscheinend Container, die von einem Dämon und nicht von einem Benutzer in einer Shell gestartet wurden. Alles scheint in Ordnung @reboot lxc-autostartzu sein. Fügen Sie Ihrer Crontab hinzu, um sie beim Booten automatisch zu starten, und Sie erhalten nach dem Neustart plötzlich verkrüppelte Container.
Qris
1

Nach dem Lesen dieses Themas.

Diese Lösung funktionierte für mich: docker -d --exec-opt native.cgroupdriver=cgroupfs. Ich fügte es tatsächlich zu den OPTIONSin /etc/sysconfig/docker...

Sebastiaan Pasterkamp
quelle