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

39

Я использую докер-сервер в Arch Linux (ядро 4.3.3-2) с несколькими контейнерами. Со времени моей последней перезагрузки сервер Docker и случайные программы в контейнерах аварийно завершают работу с сообщением о невозможности создать поток или (реже) выполнить ветвление. Конкретное сообщение об ошибке зависит от программы, но в большинстве из них упоминается конкретная ошибка 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( source) , и проверил, что ограничение применяется, изучив /proc/<pid of docker>/limitsи запустив ulimit -sвнутри контейнера докера.
  3. Каждый поток занимает немного памяти. Ограничение виртуальной памяти настраивается с помощью ulimit -v. В моей системе он установлен unlimited, и 80% моих 3 ГБ памяти свободны.
  4. Существует ограничение на количество используемых процессов ulimit -u. В этом случае потоки считаются процессами ( источник ). В моей системе ограничение установлено на 30306, а для демона Docker и внутри контейнеров Docker - на 1048576. Количество запущенных в данный момент потоков можно узнать, запустив ls -1d /proc/*/task/* | wc -lили запустив ps -elfT | wc -l( источник ). В моей системе они между 700и 800.
  5. Существует ограничение на количество открытых файлов, что, согласно некоторым источникам, также важно при создании потоков. Предел настраивается с помощью ulimit -n. В моей системе и в докере ограничение установлено на 1048576. Количество открытых файлов можно узнать с помощью lsof | wc -l( источник ), в моей системе это примерно 30000.

Похоже, что до последней перезагрузки у меня было ядро ​​4.2.5-1, сейчас я работаю 4.3.3-2. Понижение до 4.2.5-1 устраняет все проблемы. Другие посты, упоминающие проблему, это и это . Я открыл сообщение об ошибке для 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
cdauth
источник
1
Вы недавно обновились до ядра 4.3?
Рони Чоудхури
Это очень хорошо возможно. Зачем?
cdauth
1
Удивительно, я опустился до ядра 4.2.5-1 и все снова работает! Есть ли у вас какие-либо понятия, что вызывает это и как это исправить с 4.3?
cdauth
Понятия не имею, что это вызывает. Мой метод исправления заключается в том, что ветки форума Arch Linux по этой теме помечаются как «решенные» :-P.
Рони Чоудхури
1
+1 За то, что я отлично задал и исследовал вопрос, даже если у меня не было той же проблемы
Рой Truelove

Ответы:

47

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

Запрос тянуть увеличивается TasksMaxна докер пример 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
источник
1
FWIW, файл сервиса был /lib/systemd/system/docker.serviceв моем тестировании Debian.
Компилятор
2
FWIW, говоря systemctl set-property docker.service TasksMax=4096, установит свойство для работающей в данный момент службы и сохранит настройку для последующих перезагрузок в правильном месте для рассматриваемой установки докера.
Nakedible
Это общий подход . Но учтите, что предложенное вами изменение в Docker было отменено после того, как вы опубликовали этот ответ, 2016-02-09, и тогда это возвращение было выпущено для всего мира в Docker версии 1.10.1.
JdeBP
человек спасибо спасибо спасибо я долго искал это слишком долго
ахабахе
Если вы внесете изменения в файл конфигурации (мой был в /etc/systemd/system/docker.service.d/50-TasksMax.confUbuntu 16), вам нужно запустить systemctl daemon-reload. Делать не sudo service docker restartбудет работать.
осман
4

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

В моей системе Ubuntu 16.04 с systemd 229 и ядром 4.3 ограничение объема 512 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.

Райан С. Андервуд
источник
Я внес изменения в /etc/systemd/system.conf и перезагрузил компьютер. Docker по-прежнему перечисляет ограничение для задач как 512. Использование комментария @ Nakedible сверху действительно обновило доступные задачи.
Бен Мэтьюз
1
Спасибо Райан! @BenMathews, возможно, это было связано с тем, что обе проблемы допустимы в Ubuntu 16.04, вам нужно исправить их обе, чтобы все работало правильно. Эта проблема относится к контейнерам, запускаемым демоном, а не пользователем в оболочке. Таким образом, все выглядит хорошо, вы добавляете @reboot lxc-autostartв свой crontab автоматический запуск при загрузке, и вы внезапно получаете поврежденные контейнеры после перезагрузки.
Крис
1

Прочитав эту ветку.

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

Себастьян Пастеркамп
источник