TLDR
当我在其中运行多个 docker 容器时npm ci
,我开始收到pthread_create: Resource暂时不可用错误(少于 5 个 docker 容器可以正常运行)。我推断某处存在某种线程限制,但我找不到哪一个在这里阻塞。
配置
- 一个Jenkins实例为每个构建启动 docker 容器(通过 ssh 连接到这个 docker 容器)。
- 在每个容器中运行一些构建命令;我在使用时经常看到错误,
npm ci
因为这似乎创建了很多线程;但我不认为问题与npm
它本身有关。 - 所有 docker 容器都在单个docker-host上运行。它的规格:
码头主机
- Intel(R) Xeon(R) Gold 5118 CPU @ 2.30GHz,12 核,220 GB RAM
- 森托斯 7
- Docker 版本 18.06.1-ce,构建 e68fc7a
- 系统版本 219
- 内核 3.10.0-957.5.1.el7.x86_64
错误
我可以看到不同形式的错误:
- jenkins 无法联系到 docker 容器;像这样的错误:java.lang.OutOfMemoryError:无法创建新的本机线程
git clone
在容器内失败并出现错误:克隆远程 repo 'origin' 时出错 ... 原因:java.lang.OutOfMemoryError:无法创建新的本机线程npm ci
使用节点 [1296] 在容器内失败:pthread_create:资源暂时不可用
我调查或尝试过的事情
我看了很多这个问题。
- docker-host的
systemd
版本为 219,因此没有该TasksMax
属性。 /proc/sys/kernel/threads-max
= 1798308kernel.pid_max
= 49152- 线程数
ps -elfT | wc -l
( - 所有构建都以 docker 容器内 pid 1001 的某个用户身份运行;但是docker-host上没有 pid 1001 的用户,所以我不知道哪些限制适用于该用户。
- 我已经为所有用户增加了多个限制
/etc/security/limits.conf
(见下文) - 我在docker-host上创建了一个 uid 1001 的虚拟用户,并确保它也
nproc
将限制设置为无限制。登录该用户ulimit -u
= 无限制。这仍然没有解决问题
/etc/security/limits.conf :
* soft nproc unlimited
* soft stack 65536
* soft nofile 2097152
ulimit -a
作为根的输出:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 899154
max locked memory (kbytes, -l) 1048576
max memory size (kbytes, -m) unlimited
open files (-n) 1048576
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 65536
cpu time (seconds, -t) unlimited
max user processes (-u) 899154
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
我的 dockerd 进程的限制(/proc/16087/limits
16087 是 dockerd 的 pid 的猫)
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size unlimited unlimited bytes
Max core file size unlimited unlimited bytes
Max resident set unlimited unlimited bytes
Max processes unlimited unlimited processes
Max open files 65536 65536 files
Max locked memory 65536 65536 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 899154 899154 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
我找到了一种访问超过 4096 个线程的方法。
我的 docker 容器是 centos7 镜像;默认情况下,用户限制设置为 4096 个进程;如定义
/etc/security/limits.d/20-nproc.conf
:登录到我的 docker 容器时;我添加到
~/.bashrc
命令ulimit -u unlimited
中,以便为该用户删除此限制。现在我可以突破这个4096的天花板了。我对这个解决方案并不完全满意;因为这意味着我需要调整将在docker-host上运行的所有容器,因为它们都有自己的限制;并且由于我以用户身份运行所有构建命令,
1001
因此似乎当容器询问他运行了多少线程时;他“看到”了所有容器的所有线程;不仅是他自己的例子。为此,我在 docker-for-linux github 中创建了一个问题:https ://github.com/docker/for-linux/issues/654