web-dev-qa-db-fra.com

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

J'utilise 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 dans les conteneurs se bloquent avec un message indiquant qu'ils ne peuvent pas créer de thread, ou (moins souvent) à 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 ce post pour 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. 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 lequel des nombreux possibles les causes du problème sont présentes.

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

  1. Il existe une limite à l'échelle du système sur le nombre de threads configurés dans /proc/sys/kernel/threads-max ( source ). Dans mon cas, cela est défini sur 60613.
  2. Chaque thread prend de la place dans la pile. La limite de taille de pile est configurée à l'aide de ulimit -s ( source ). La limite pour mon Shell était 8192, mais je l'ai augmenté en mettant * soft stack 32768 en /etc/security/limits.conf, donc ça ulimit -s renvoie maintenant 32768. Je l'ai également augmenté pour le processus de docker en mettant LimitSTACK=33554432 en /etc/systemd/system/docker.service ( source , et j'ai vérifié que la limite s'applique en examinant /proc/<pid of docker>/limits et en exécutant ulimit -s à l'intérieur d'un conteneur Docker.
  3. Chaque thread 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 défini sur unlimited, et 80% de mes 3 Go de mémoire sont libres.
  4. Il existe une limite au nombre de processus utilisant ulimit -u. Les threads comptent comme 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 trouvé en exécutant ls -1d /proc/*/task/* | wc -l ou en exécutant ps -elfT | wc -l ( source ). Sur mon système, ils sont entre 700 et 800.
  5. Il y a une limite sur le nombre de fichiers ouverts, qui selon certains source s est également pertinent lors de la création de threads. La limite est configurée à l'aide de ulimit -n. Sur mon système et dans Docker, 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 de 30000.

Il semble qu'avant le dernier redémarrage, j'utilisais le noyau 4.2.5-1, maintenant j'exécute 4.3.3-2. La rétrogradation vers 4.2.5-1 résout tous les problèmes. Les autres articles mentionnant le problème sont this et this . J'ai ouvert un rapport de bogue pour Arch Linux .

Qu'est-ce qui a changé dans le noyau qui pourrait être à l'origine de cela?


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
42
cdauth

Le problème est dû à l'attribut TasksMax systemd. Il a été introduit dans systemd 228 et utilise le sous-système pid cgroups, qui a été introduit dans le noyau Linux 4.3. Une limite de tâches de 512 est donc activé 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 de tirage et les valeurs par défaut ont été définies par cette demande de tirage . Après la mise à niveau de mon noyau vers 4.3, systemctl status docker affiche une ligne Tasks:

# 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

Réglage TasksMax=infinity dans le [Service] section de docker.service résout le problème. docker.service est généralement dans /usr/share/systemd/system, mais il peut également être mis/copié dans /etc/systemd/system pour éviter qu'il soit remplacé par le gestionnaire de paquets.

Un pull request augmente TasksMax pour les exemples de fichiers systemd de docker, et un Arch Linux bug report essaie d'obtenir la même chose pour le package. Il y a d'autres discussions en cours sur le forum Arch Linux et dans un rapport de bogue Arch Linux concernant lxc .

DefaultTasksMax peut être utilisé dans le [Manager] section dans /etc/systemd/system.conf (ou /etc/systemd/user.conf pour les services géré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 shell de connexion. Ces valeurs par défaut sont 4096 par utilisateur (sera porté à 12288 ) et sont configurés comme UserTasksMax dans le [Login] section de /etc/systemd/logind.conf.

49
cdauth

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 a été appliquée par défaut aux étendues de session même lorsque UserTasksMax a été défini sur la nouvelle valeur par défaut augmentée de 12288. Ainsi, toute étendue de session utilisateur était limitée à 512 threads.

La seule façon que j'ai trouvée pour supprimer la limite était de définir DefaultTasksMax=unlimited dans /etc/systemd/system.conf et systemctl daemon-reexec (ou redémarrez).

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

4

Après avoir lu ce fil.

Cette solution a fonctionné pour moi: docker -d --exec-opt native.cgroupdriver=cgroupfs. Je l'ai en fait ajouté au OPTIONS dans /etc/sysconfig/docker...

1