Создание потоков завершается неудачей с «Ресурсом временно недоступным» с ядром 4.3

Я запускаю сервер докеров на Arch Linux (ядро 4.3.3-2) с несколькими контейнерами. Начиная с моей последней перезагрузки, как сервер докеров, так и случайные программы в контейнерах вылетают с сообщением о невозможности создания потока или (реже) к вилке. Конкретное сообщение об ошибке отличается в зависимости от программы, но большинство из них, похоже, упоминает конкретную ошибку Resource temporarily unavailable. См. В конце этого сообщения некоторые примеры сообщений об ошибках.

Теперь есть много людей, у которых было это сообщение об ошибке, и много ответов на них. Что действительно расстраивает, так это то, что все, кажется, размышляют о том, как проблема может быть решена, но никто, кажется, не указывает, как идентифицировать , какая из многих возможных причин проблемы присутствует.

Я собрал эти 5 возможных причин ошибки и как проверить, что они не присутствуют в моей системе:

  1. Существует системное ограничение количества потоков, настроенных в /proc/sys/kernel/threads-max ( источник ). В моем случае это установлено на 60613.
  2. Каждый поток занимает некоторое место в стеке. Предел размера стека настраивается с помощью ulimit -s ( источник ). Предел для моей оболочки был 8192, но я увеличил его, поставив * soft stack 32768 в /etc/security/limits.conf, поэтому он ulimit -s теперь возвращает 32768. Я также увеличил его для процесса докера, поставив LimitSTACK=33554432 в /etc/systemd/system/docker.service ( источник , и я подтвердил, что этот предел применяется при просмотре /proc/<pid of docker>/limits и запустив ulimit -s внутри контейнера докера.
  3. Каждый поток занимает некоторую память. Предел виртуальной памяти настраивается с помощью ulimit -v. В моей системе установлено значение unlimited, а 80% моей 3 ГБ памяти бесплатны.
  4. Существует ограничение на количество процессов с помощью ulimit -u. В этом случае потоки учитываются как процессы ( источник ). В моей системе ограничение установлено на 30306, а для демона докеров и внутри контейнеров докеров предел равен 1048576. Количество текущих запущенных потоков можно узнать, запустив ls -1d /proc/*/task/* | wc -l или запустив ps -elfT | wc -l ( источник ). В моей системе они находятся между 700 и 800.
  5. Существует ограничение на количество открытых файлов, которое согласно некоторым source s также имеет значение при создании потоков. Предел настраивается с помощью ulimit -n. На моей системе и внутри докера предел установлен на 1048576. Количество открытых файлов можно узнать, используя lsof | wc -l ( источник ), в моей системе это примерно 30000.

Похоже, что до последней перезагрузки я запускал ядро ​​4.2.5-1, теперь я запускаю 4.3.3-2. Снижение до 4.2.5-1 устраняет все проблемы. Другие сообщения, упоминающие проблему, это и this . Я открыл отчет об ошибке для Arch Linux .

Что изменилось в ядре, которое может вызвать это?


Вот несколько примеров сообщений об ошибках:

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
28 голосов | спросил cdauth 7 Jpm1000000pmThu, 07 Jan 2016 18:16:58 +030016 2016, 18:16:58

3 ответа


41

Проблема вызвана TasksMax атрибут systemd. Он был введен в systemd 228 и использует подсистему pid cgroups, которая была введена в ядро ​​linux 4.3. Таким образом, предел задачи 512 включен в systemd, если запущено ядро ​​4.3 или новее. Эта функция объявлена ​​ здесь и была представлена ​​в this pull request , а значения по умолчанию были установлены this pull request . После обновления моего ядра до 4.3, systemctl status docker отображает 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

Настройка TasksMax=infinity в [Service] раздел docker.service устраняет проблему. docker.service обычно находится в /usr/share/systemd/system, но это также можно поместить /скопировать в /etc/systemd/system, чтобы избежать его переопределения менеджером пакетов.

A запрос на перенос увеличивается TasksMax для файлов docker example systemd и отчет об ошибке Arch Linux пытается добиться того же самого для пакета. Существует еще некоторое обсуждение на форуме Arch Linux и в отчете об ошибке Arch Linux относительно lxc .

DefaultTasksMax можно использовать в разделе [Manager] в /etc/systemd/system.conf (или /etc/systemd/user.conf для пользовательских служб) для управления значение по умолчанию для TasksMax.

Systemd также применяет ограничение для программ, запускаемых из оболочки входа. Эти значения по умолчанию равны 4096 для каждого пользователя (будет увеличен до 12288 ) и настроен как UserTasksMax в разделе [Login] /etc/systemd/logind.conf .

ответил cdauth 15 Jpm1000000pmFri, 15 Jan 2016 22:18:03 +030016 2016, 22:18:03
3

Ответ cdauth правильный, но есть еще одна деталь для добавления.

В моей системе Ubuntu 16.04 с systemd 229 и ядром 4.3 ограничение по умолчанию для pid было ограничено по умолчанию, даже когда UserTasksMax был установлен на новый, увеличенный по умолчанию 12288. Таким образом, всякая область пользовательского сеанса была ограничена 512 потоки.

Единственное, что я нашел, чтобы удалить ограничение, было установить DefaultTasksMax=unlimited в /etc/systemd/system.conf и systemctl daemon-reexec (или перезагрузка).

Вы можете проверить, происходит ли это, выпустив systemctl status, выбрав область сеанса и cat /sys/fs/cgroup/pids/user.slice/user-${UID}.slice/session-FOO.scope/pids.max

ответил Ryan C. Underwood 7 AMpThu, 07 Apr 2016 08:03:52 +030003Thursday 2016, 08:03:52
1

После чтения этого потока.

Это решение сработало для меня: docker -d --exec-opt native.cgroupdriver=cgroupfs. Я действительно добавил его в OPTIONS в /etc/sysconfig/docker ...

ответил Sebastiaan Pasterkamp 15 22016vEurope/Moscow11bEurope/MoscowTue, 15 Nov 2016 15:22:18 +0300 2016, 15:22:18

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132