使用 4.3 核心創建執行緒失敗並顯示“資源暫時不可用”
我在 Arch Linux(核心 4.3.3-2)上執行一個帶有多個容器的 docker 伺服器。自從我上次重新啟動以來,容器中的 docker 伺服器和隨機程序都會崩潰,並顯示無法創建執行緒或(較少)分叉的消息。具體的錯誤資訊因程序而異,但大部分似乎都提到了具體的錯誤
Resource temporarily unavailable
。請參閱本文末尾的一些範例錯誤消息。現在有很多人收到此錯誤消息,並且有很多回复。真正令人沮喪的是,每個人似乎都在猜測如何解決問題,但似乎沒有人指出如何確定問題的眾多可能原因中的哪一個。
我已經收集了這 5 個可能的錯誤原因以及如何驗證它們不存在於我的系統中:
/proc/sys/kernel/threads-max
在( source )中配置的執行緒數存在系統範圍的限制。在我的情況下,這設置為60613
.- 每個執行緒都在堆棧中佔用一些空間。使用
ulimit -s
( source ) 配置堆棧大小限制。我的 shell 的限制曾經是8192
,但我已經通過放入來增加它* soft stack 32768
,/etc/security/limits.conf
所以它ulimit -s
現在返回了32768
。我還通過放入 ( source 為 docker 程序增加了它LimitSTACK=33554432
,/etc/systemd/system/docker.service
並且我通過查看和在 docker 容器中/proc/<pid of docker>/limits
執行來驗證該限制是否適用。ulimit -s
- 每個執行緒都需要一些記憶體。使用 配置虛擬記憶體限制
ulimit -v
。在我的系統上,它設置為unlimited
,並且我的 3 GB 記憶體中有 80% 是空閒的。- 使用
ulimit -u
. 在這種情況下,執行緒算作程序(source)。在我的系統上,限制設置為30306
,對於 docker 守護程序和內部 docker 容器,限制為1048576
. 目前執行的執行緒數可以通過runningls -1d /proc/*/task/* | wc -l
或runningps -elfT | wc -l
( source )查出。在我的系統上,它們介於700
和之間800
。- 打開文件的數量是有限制的,根據一些來源,這在創建執行緒時也是相關的。限制是使用 配置的
ulimit -n
。在我的系統和 docker 內部,限制設置為1048576
.lsof | wc -l
使用( source )可以找到打開文件的數量,在我的系統上大約是30000
.看起來在上次重新啟動之前我執行的是核心 4.2.5-1,現在我執行的是 4.3.3-2。降級到 4.2.5-1 解決了所有問題。其他提到這個問題的文章是this和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
該問題是由
TasksMax
systemd 屬性引起的。它是在 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 文件的拉取請求正在增加, Arch Linux 錯誤報告正試圖為包實現相同的效果。Arch Linux 論壇和關於 lxc 的 Arch Linux 錯誤報告中正在進行一些額外的討論。
TasksMax
DefaultTasksMax
可用於(或用於使用者執行的服務)中的[Manager]
部分來控制./etc/systemd/system.conf``/etc/systemd/user.conf``TasksMax
Systemd 還對從登錄 shell 執行的程序應用限制。這些預設為
4096
每個使用者(將增加到12288
)並配置UserTasksMax
為[Login]
./etc/systemd/logind.conf