使用4.3内核创建线程失败,并显示“资源暂时不可用”


39

我在带有多个容器的Arch Linux(内核4.3.3-2)上运行docker服务器。自从我上次重启以来,Docker服务器和容器中的随机程序都崩溃,并显示一条消息,提示无法创建线程或(较不频繁)进行分叉。根据程序的不同,特定的错误消息也有所不同,但是大多数错误消息似乎都提到了特定的错误Resource temporarily unavailable。有关某些示例错误消息,请参见本文末尾。

现在有很多人收到此错误消息,并对它们有很多响应。真正令人沮丧的是,每个人似乎都在猜测如何解决该问题,但是似乎没有人指出如何确定问题的许多可能原因中的哪一个。

我已经收集了以下5种可能的错误原因以及如何验证它们在我的系统上不存在的原因:

  1. /proc/sys/kernel/threads-maxsource)中配置的线程数存在系统范围的限制。就我而言,该设置为60613
  2. 每个线程都在堆栈中占用一些空间。堆栈大小限制是使用ulimit -ssource)配置的。我的壳的极限曾经是8192,但我已经通过将增加其* soft stack 32768/etc/security/limits.conf,因此它ulimit -s现在的回报32768。我还通过将(source)添加LimitSTACK=33554432到docker进程中,并通过查看docker容器并在其中运行来验证该限制是否适用。/etc/systemd/system/docker.service/proc/<pid of docker>/limitsulimit -s
  3. 每个线程都会占用一些内存。使用来配置虚拟内存限制ulimit -v。在我的系统上,它设置为unlimited,并且我3 GB的内存中有80%可用。
  4. 使用的进程数有限制ulimit -u。在这种情况下,线程被视为进程(source)。在我的系统上,限制设置为30306,对于docker守护程序和docker容器内部,限制为1048576。可以通过运行ls -1d /proc/*/task/* | wc -l或通过运行ps -elfT | wc -lsource)找出当前正在运行的线程数。在我的系统上,它们介于700和之间800
  5. 打开文件的数量有限制,根据某些来源的资料,在创建线程时这也很重要。限制是使用配置的ulimit -n。在我的系统和docker内部,限制设置为1048576。可以使用lsof | wc -lsource)找出打开的文件数,在我的系统上大约是30000

上次重启之前,我正在运行内核4.2.5-1,现在我正在运行4.3.3-2。降级到4.2.5-1可以解决所有问题。其他提到问题的帖子是thisthis。我已经打开了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内核?
罗尼·乔杜里

那很有可能。为什么?
cdauth

1
太神奇了,我降级到了4.2.5-1内核,一切又恢复了!您是否有什么原因导致此问题以及如何使用4.3修复它?
cdauth

不知道是什么原因造成的。我的解决方法是等待该主题上的Arch Linux论坛线程被标记为“已解决” :-P。
罗尼·乔杜里

1
+1即使我没有遇到同样的问题,这也是一个经过很好研究和询问的问题
Roy Truelove

Answers:


47

该问题是由TasksMaxsystemd属性引起的。它是在systemd 228中引入的,并利用了Linux内核4.3中引入的cgroups pid子系统。512如果内核4.3或更高版本正在运行,则在systemd中启用了任务限制。该功能在宣布并在此请求请求中引入,默认值由该请求请求设置。将内核升级到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以避免被程序包管理器覆盖。

对于docker示例systemd文件的拉取请求正在增加TasksMax,并且Arch Linux错误报告正试图对该软件包实现相同的要求。在Arch Linux论坛以及关于lxc的Arch Linux错误报告中,还有一些其他讨论。

DefaultTasksMax可以在中的[Manager]部分/etc/systemd/system.conf(或/etc/systemd/user.conf用于用户运行的服务)中用于控制的默认值TasksMax

Systemd还对从登录Shell运行的程序施加了限制。这些默认为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将为当前正在运行的服务设置属性,并将该设置保留在有关所涉及的docker安装的正确位置,以供后续重启。
Nakedible

这是一种常见的方法。但是请注意,您在2016年2月9日发布此答案后,对您提出的Docker更改进行了还原,然后将该版本在Docker 1.10.1版中发布到了全世界。
JdeBP '16

男人谢谢谢谢谢谢!我一直在寻找这个太久了
achabahe '17

如果您对配置文件进行了更改(/etc/systemd/system/docker.service.d/50-TasksMax.conf在Ubuntu 16上是我的),则需要运行systemctl daemon-reload。这样做是sudo service docker restart行不通的。
奥斯曼

4

cdauth的答案是正确的,但是还需要添加另一个细节。

在我的具有systemd 229和4.3内核的Ubuntu 16.04系统上,即使将UserTasksMax设置为新的增加的默认值12288,默认情况下也会在会话范围上强制执行512 pid限制。因此,任何用户会话范围均限于512个线程。

我发现,取消该限制的唯一方法是设置DefaultTasksMax=unlimited/etc/systemd/system.confsystemctl 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中以在启动时自动启动它们,并且重新启动后突然出现容器残缺的情况。
qris

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.