Я использую докер-сервер в Arch Linux (ядро 4.3.3-2) с несколькими контейнерами. Со времени моей последней перезагрузки сервер Docker и случайные программы в контейнерах аварийно завершают работу с сообщением о невозможности создать поток или (реже) выполнить ветвление. Конкретное сообщение об ошибке зависит от программы, но в большинстве из них упоминается конкретная ошибка Resource temporarily unavailable
. Посмотрите в конце этого поста несколько примеров сообщений об ошибках.
Сейчас есть много людей, у которых было это сообщение об ошибке, и множество ответов на них. Что действительно расстраивает, так это то, что все, похоже, размышляют о том, как решить проблему, но никто, кажется, не указывает, как определить, какая из множества возможных причин проблемы присутствует.
Я собрал эти 5 возможных причин для ошибки и как проверить, что они не присутствуют в моей системе:
- Существует общесистемное ограничение на количество потоков, настроенных в
/proc/sys/kernel/threads-max
( источник ). В моем случае это установлено на60613
. - Каждый поток занимает некоторое место в стеке. Предел размера стека настраивается с помощью
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
внутри контейнера докера. - Каждый поток занимает немного памяти. Ограничение виртуальной памяти настраивается с помощью
ulimit -v
. В моей системе он установленunlimited
, и 80% моих 3 ГБ памяти свободны. - Существует ограничение на количество используемых процессов
ulimit -u
. В этом случае потоки считаются процессами ( источник ). В моей системе ограничение установлено на30306
, а для демона Docker и внутри контейнеров Docker - на1048576
. Количество запущенных в данный момент потоков можно узнать, запустивls -1d /proc/*/task/* | wc -l
или запустивps -elfT | wc -l
( источник ). В моей системе они между700
и800
. - Существует ограничение на количество открытых файлов, что, согласно некоторым источникам, также важно при создании потоков. Предел настраивается с помощью
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
Ответы:
Проблема вызвана
TasksMax
атрибутом systemd. Он был введен в systemd 228 и использует подсистему pid cgroups, которая была представлена в ядре linux 4.3.512
Таким образом, в systemd включено ограничение задачи, если работает ядро 4.3 или новее. Эта функция была анонсирована здесь и была представлена в этом запросе извлечения, а значения по умолчанию были заданы этим запросом извлечения . После обновления моего ядра до 4.3,systemctl status docker
отображаетсяTasks
строка:Установка
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
.источник
/lib/systemd/system/docker.service
в моем тестировании Debian.systemctl set-property docker.service TasksMax=4096
, установит свойство для работающей в данный момент службы и сохранит настройку для последующих перезагрузок в правильном месте для рассматриваемой установки докера./etc/systemd/system/docker.service.d/50-TasksMax.conf
Ubuntu 16), вам нужно запуститьsystemctl daemon-reload
. Делать неsudo service docker restart
будет работать.Ответ 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
.источник
@reboot lxc-autostart
в свой crontab автоматический запуск при загрузке, и вы внезапно получаете поврежденные контейнеры после перезагрузки.Прочитав эту ветку.
Это решение работает для меня:
docker -d --exec-opt native.cgroupdriver=cgroupfs
. Я на самом деле добавил егоOPTIONS
в/etc/sysconfig/docker
...источник