La création de threads échoue avec «Ressource temporairement indisponible» avec le noyau 4.3

39

J'exécute un serveur Docker sur Arch Linux (noyau 4.3.3-2) avec plusieurs conteneurs. Depuis mon dernier redémarrage, le serveur Docker et les programmes aléatoires des conteneurs se bloquent avec le message de ne pas pouvoir créer de fil, ou (moins souvent) de faire un fork. Le message d'erreur spécifique est différent selon le programme, mais la plupart d'entre eux semblent mentionner l'erreur spécifique Resource temporarily unavailable. Voir à la fin de cet article quelques exemples de messages d'erreur.

Maintenant, il y a beaucoup de gens qui ont eu ce message d'erreur, et beaucoup de réponses à eux. Ce qui est vraiment frustrant, c’est que tout le monde semble spéculer sur la façon dont le problème pourrait être résolu, mais personne ne semble indiquer comment identifier l’une des nombreuses causes possibles du problème.

J'ai rassemblé ces 5 causes possibles de l'erreur et comment vérifier qu'elles ne sont pas présentes sur mon système:

  1. Le nombre de threads configurés dans /proc/sys/kernel/threads-max( source ) est limité au niveau du système . Dans mon cas, cela est réglé sur 60613.
  2. Chaque thread prend de la place dans la pile. La taille limite de la pile est configurée avec ulimit -s( source ). Auparavant, la limite pour ma coquille était 8192, mais je l’ai augmentée en la mettant * soft stack 32768dans /etc/security/limits.conf, elle ulimit -srevient donc 32768. Je l'ai également augmenté pour le processus de menu fixe en passant LimitSTACK=33554432dans /etc/systemd/system/docker.service( source ) et j'ai vérifié que la limite s'appliquait en examinant /proc/<pid of docker>/limitset en s'exécutant ulimit -sà l' intérieur d'un conteneur de menu fixe.
  3. Chaque fil prend de la mémoire. Une limite de mémoire virtuelle est configurée à l'aide de ulimit -v. Sur mon système, il est réglé sur unlimitedet 80% de mes 3 Go de mémoire sont libres.
  4. Il y a une limite sur le nombre de processus utilisant ulimit -u. Les threads sont considérés comme des processus dans ce cas ( source ). Sur mon système, la limite est définie sur 30306, et pour le démon docker et à l'intérieur des conteneurs docker, la limite est 1048576. Le nombre de threads en cours d'exécution peut être déterminé en exécutant ls -1d /proc/*/task/* | wc -lou en exécutant ps -elfT | wc -l( source ). Sur mon système, ils sont entre 700et 800.
  5. Le nombre de fichiers ouverts est limité, ce qui, selon certaines sources, est également pertinent lors de la création de threads. La limite est configurée avec ulimit -n. Sur mon système et à l'intérieur du menu fixe, la limite est définie sur 1048576. Le nombre de fichiers ouverts peut être trouvé en utilisant lsof | wc -l( source ), sur mon système il s'agit 30000.

Il semblerait qu'avant le dernier redémarrage, j'utilisais le noyau 4.2.5-1, maintenant j'exécute le 4.3.3-2. Le passage à la version 4.2.5-1 corrige tous les problèmes. D'autres articles mentionnant le problème sont ceci et cela . J'ai ouvert un rapport de bogue pour Arch Linux .

Qu'est-ce qui a pu changer cela dans le noyau?


Voici quelques exemples de messages d'erreur:

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
la source
1
Avez-vous récemment effectué une mise à niveau vers le noyau 4.3?
Roni Choudhury
C'est très bien possible. Pourquoi?
Cdauth
1
Incroyable, j'ai rétrogradé le noyau 4.2.5-1 et tout fonctionne à nouveau! Avez-vous une idée de ce qui cause cela et comment y remédier avec la version 4.3?
Cdauth
Aucune idée de ce qui le cause. Ma méthode de correction attend que les discussions du forum Arch Linux sur le sujet portent la mention "RESOLU" :-P.
Roni Choudhury
1
+1 Pour être une question extrêmement bien posée et recherchée, même si je n'ai pas eu le même problème
Roy Truelove

Réponses:

47

Le problème est dû à l' TasksMaxattribut systemd. Il a été introduit dans systemd 228 et utilise le sous-système cgroups pid, introduit dans le noyau linux 4.3. Une limite de tâche de 512est donc activée dans systemd si le noyau 4.3 ou plus récent est en cours d'exécution. La fonctionnalité est annoncée ici et a été introduite dans cette demande d'extraction et les valeurs par défaut ont été définies par cette demande d'extraction . Après la mise à niveau de mon noyau vers la version 4.3, systemctl status dockeraffiche une Tasksligne:

# 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

Le réglage TasksMax=infinitydans la [Service]section de docker.servicerésout le problème. docker.serviceest généralement dans /usr/share/systemd/system, mais il peut également être inséré / copié /etc/systemd/systempour éviter son remplacement par le gestionnaire de paquets.

Une demande d'extraction augmente TasksMaxpour les exemples de fichiers systemd de docker et un rapport de bogue Arch Linux tente d'obtenir la même chose pour le paquet. Des discussions supplémentaires sont en cours sur le forum Arch Linux et dans un rapport de bogue Arch Linux concernant lxc .

DefaultTasksMaxpeut être utilisé dans la [Manager]section /etc/systemd/system.conf(ou /etc/systemd/user.confpour les services exécutés par l'utilisateur) pour contrôler la valeur par défaut de TasksMax.

Systemd applique également une limite pour les programmes exécutés à partir d'un login-shell. Ces valeurs 4096par défaut ( par utilisateur) (seront augmentées à12288 ) et sont configurées comme UserTasksMaxdans la [Login]section /etc/systemd/logind.conf.

Cdauth
la source
1
FWIW, le fichier de service était à l’ /lib/systemd/system/docker.serviceessai de Debian.
Le compilateur
2
FWIW, dit systemctl set-property docker.service TasksMax=4096définira la propriété pour un service en cours d’exécution et conservera le réglage pour les redémarrages ultérieurs à l’endroit correct pour l’installation du menu fixe en question.
Nakedible le
C'est une approche commune . Notez cependant que le changement Docker que vous avez proposé a été annulé après que vous ayez posté cette réponse, le 2016-02-09, cette inversion étant ensuite rendue publique dans le monde dans la version 1.10.1 de Docker.
JdeBP
homme merci merci merci! je cherche depuis trop longtemps pour cela
achabahe
Si vous modifiez le fichier de configuration (le mien était sous /etc/systemd/system/docker.service.d/50-TasksMax.confUbuntu 16), vous devez l'exécuter systemctl daemon-reload. Faire un sudo service docker restarttestament ne fonctionne pas.
osman
4

La réponse de cdauth est correcte, mais il y a un autre détail à ajouter.

Sur mon système Ubuntu 16.04 avec systemd 229 et un noyau 4.3, une limite de 512 pid était appliquée par défaut aux portées de session, même si UserTasksMax était défini sur la nouvelle valeur par défaut augmentée de 12288. Ainsi, toute portée de session utilisateur était limitée à 512 threads.

La seule manière que je trouvais à supprimer la limite était de mettre DefaultTasksMax=unlimiteden /etc/systemd/system.confet systemctl daemon-reexec(ou redémarrage).

Vous pouvez vérifier si cela se produit en émettant systemctl status, en choisissant une étendue de session, et cat /sys/fs/cgroup/pids/user.slice/user-${UID}.slice/session-FOO.scope/pids.max.

Ryan C. Underwood
la source
J'ai apporté la modification à /etc/systemd/system.conf et redémarré. Docker indique toujours que le nombre maximal de tâches est 512. L'utilisation du commentaire de @ Nakedible ci-dessus a permis de mettre à jour les tâches disponibles.
Ben Mathews
1
Merci Ryan! @BenMathews c'est peut-être parce que les deux sont des problèmes valables sous Ubuntu 16.04, vous devez les résoudre tous les deux pour que les choses fonctionnent correctement. Ce problème semble s’appliquer aux conteneurs lancés par un démon et non par un utilisateur dans un shell. Ainsi, tout semble @reboot lxc-autostartaller pour le mieux , vous ajoutez à votre crontab de les démarrer automatiquement au démarrage, et vous obtenez soudain des conteneurs estropiés après le redémarrage.
Qris
1

Après avoir lu ce fil.

Cette solution a fonctionné pour moi: docker -d --exec-opt native.cgroupdriver=cgroupfs. En fait , j'ajouté au OPTIONSen /etc/sysconfig/docker...

Sebastiaan Pasterkamp
la source