总长DR

总长DR

总长DR

当启动我运行的多个 docker 容器时npm ci,我开始得到pthread_create:资源暂时不可用错误(少于 5 个 docker 容器可以正常运行)。我推断某处存在某种线程限制,但我找不到哪个线程在这里阻塞。

配置

  • A詹金斯实例为每个构建启动 docker 容器(通过 ssh 连接到此 docker 容器)。
  • 在每个容器中运行一些构建命令;我在使用时经常看到这个错误,npm ci因为这似乎创建了相当多的线程;但我不认为这个问题与其npm本身有关。
  • 所有 docker 容器都运行在一个单一的容器上docker主机。它的规格:

docker主机

  • 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容器内失败错误:克隆远程存储库“origin”时出错...引起:java.lang.OutOfMemoryError:无法创建新的本机线程
  • npm ci容器内失败节点[1296]:pthread_create:资源暂时不可用

我调查过或尝试过的事情

我看了很多这个问题

  • docker主机systemd版本 219,因此没有TasksMax属性。
  • /proc/sys/kernel/threads-max=1798308
  • kernel.pid_max= 49152
  • 线程数 ( ps -elfT | wc -l) 通常为 700,但随着多个容器运行,我发现它攀升至 4500。
  • 所有构建都以 docker 容器内 pid 1001 的某个用户身份运行;但是没有 pid 1001 的用户docker主机所以我不知道哪些限制适用于该用户。
  • 我已经为所有用户增加了多个限制/etc/security/limits.conf(见下文)
  • 我创建了一个 uid 1001 的虚拟用户docker主机并确保它也将nproc限制设置为无限制。登录该用户ulimit -u=无限制。这仍然没有解决问题

/etc/security/limits.conf :

*               soft    nproc           unlimited
*               soft    stack           65536
*               soft    nofile          2097152

作为 root的输出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 进程的限制(cat /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

答案1

我找到了一种方法来访问超过 4096 个线程。

我的docker容器是centos7镜像;默认情况下,用户限制设置为 4096 个进程;定义如下/etc/security/limits.d/20-nproc.conf

# Default limit for number of user's processes to prevent
# accidental fork bombs.
# See rhbz #432903 for reasoning.

*          soft    nproc     4096
root       soft    nproc     unlimited

当登录到我的 docker 容器时;我添加到~/.bashrc命令中ulimit -u unlimited,以便为该用户删除此限制。现在我可以突破这个4096的天花板了。

我对这个解决方案不太满意;因为这意味着我需要调整所有运行的容器docker主机因为他们都有自己的极限;由于我以用户身份运行所有构建命令,1001因此似乎容器询问他正在运行多少个线程;他“看到”所有容器的所有线程在一起;不仅仅是他自己的例子。

我为此在 docker-for-linux github 中创建了一个问题:https://github.com/docker/for-linux/issues/654

相关内容