Створення потоків не вдається з "ресурсом тимчасово недоступним" з ядром 4.3


39

Я запускаю докер-сервер на Arch Linux (ядро 4.3.3-2) з кількома контейнерами. З моєї останньої перезавантаження і докер-сервер, і випадкові програми в контейнерах виходять з ладу з повідомленням про неможливість створення потоку або (рідше) для розщеплення. Повідомлення про конкретну помилку відрізняється в залежності від програми, але, здається, більшість із них згадує конкретну помилку Resource temporarily unavailable. Дивіться наприкінці цієї публікації кілька прикладів повідомлень про помилки.

Зараз є багато людей, які отримали це повідомлення про помилку, і багато відповідей на них. Що насправді засмучує те, що, здається, всі спекулюють, як проблему можна було б вирішити, але, здається, ніхто не вказує, як визначити, яка з багатьох можливих причин проблеми є.

Я зібрав ці 5 можливих причин помилки та як перевірити їх відсутність у моїй системі:

  1. Існує загальносистемне обмеження щодо кількості потоків, налаштованих у /proc/sys/kernel/threads-max( джерело ). У моєму випадку це встановлено 60613.
  2. Кожна нитка займає певний простір у стеці. Ліміт розміру стека налаштовується за допомогою ulimit -s( source ). Межа для моєї оболонки раніше була 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. Існує обмеження на кількість відкритих файлів, що згідно з деякими джерелами s також є актуальним при створенні потоків. Ліміт налаштовано за допомогою ulimit -n. Для моєї системи та всередині докера встановлено обмеження 1048576. Кількість відкритих файлів можна дізнатися за допомогою lsof | wc -l( source ), в моїй системі це приблизно 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

1
Ви нещодавно оновили до ядра 4.3?
Roni Choudhury

Це дуже добре можливо. Чому?
cdauth

1
Дивно, я перейшов на ядро ​​4.2.5-1 і все знову працює! Чи є у вас поняття, що це викликає, і як це виправити за допомогою 4.3?
cdauth

Немає поняття, що це викликає. Мій метод його виправлення чекає, коли теми форуму Arch Linux по темі будуть позначені "РІШЕННІ" :-P.
Roni Choudhury

1
+1 За те, що я був прекрасно заданим і дослідженим питанням, навіть якщо у мене не було тієї самої проблеми
Roy 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.


1
FWIW, файл служби був /lib/systemd/system/docker.serviceу моєму тестуванні Debian.
Укладач

2
FWIW, кажучи systemctl set-property docker.service TasksMax=4096, встановить властивість для поточно запущеної послуги та збереже налаштування для наступних перезавантажень у потрібному місці для відповідної установки докера.
Голий

Це загальний підхід . Але зауважте, що запропоновану вами зміну Докера було скасовано після опублікування цієї відповіді, 2016-02-09, після чого ця реверсія була випущена у світ у Докерській версії 1.10.1.
JdeBP

людина спасибі спасибі спасибі! я дуже довго шукав цього
achabahe

Якщо ви внесете зміни в конфігураційний файл (мій був /etc/systemd/system/docker.service.d/50-TasksMax.confна Ubuntu 16), вам потрібно запустити systemctl daemon-reload. Робити sudo service docker restartзаповіт НЕ буде працювати.
осман

4

Відповідь cdauth правильна, але слід додати ще одну деталь.

У моїй системі Ubuntu 16.04 з ядром systemd 229 та ядром 4.3, 512 під-лідеру було застосовано в діапазонах сеансу за замовчуванням навіть тоді, коли 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 і перезавантажився. Докер все ще перераховує ліміт завдань як 512. Використання коментаря @ Nakedible зверху оновило доступні завдання.
Бен Метюз

1
Дякую, Райан! @BenMathews, можливо, це було тому, що обидва є дійсними проблемами на Ubuntu 16.04, вам потрібно виправити їх обидва, щоб речі працювали належним чином. Здається, ця проблема стосується контейнерів, запущених демоном, а не користувачем у оболонці. Отже, все здається нормально, ви додаєте @reboot lxc-autostartв свій crontab, щоб автоматично запустити їх під час завантаження, і ви раптом отримаєте каліку контейнерів після перезавантаження.
qris

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.