총 길이 DR

총 길이 DR

총 길이 DR

내가 실행 중인 여러 도커 컨테이너를 시작할 때 npm ci다음과 같은 메시지가 표시되기 시작합니다.pthread_create: 리소스를 일시적으로 사용할 수 없습니다.오류(5개 미만의 Docker 컨테이너가 제대로 실행될 수 있음) 어딘가에 일종의 스레드 제한이 있는 것으로 추측되지만 여기서는 어떤 스레드가 차단되고 있는지 찾을 수 없습니다.

구성

  • 젠킨스인스턴스는 각 빌드에 대해 Docker 컨테이너를 시작합니다(Ssh를 통해 이 Docker 컨테이너에 연결).
  • 각 컨테이너에서 일부 빌드 명령을 실행합니다. 이 오류는 npm ci꽤 많은 스레드를 생성하는 것처럼 보이지만 이 문제가 npm그 자체와 관련이 있다고 생각하지 않습니다.
  • 모든 도커 컨테이너는 단일 컨테이너에서 실행됩니다.도커 호스트. 사양:

도커 호스트

  • Intel(R) Xeon(R) Gold 5118 CPU @ 2.30GHz, 12코어, 220GB 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: 리소스를 일시적으로 사용할 수 없습니다.

내가 조사했거나 시도한 것

많이 봤어요이 문제.

  • 도커 호스트버전 219 가 있으므로 systemd없습니다.TasksMax속성.
  • /proc/sys/kernel/threads-max=1798308
  • kernel.pid_max= 49152
  • 스레드 수( ps -elfT | wc -l)는 일반적으로 700개이지만 여러 컨테이너를 실행하면 4500개까지 올라가는 것을 보았습니다.
  • 모든 빌드는 docker 컨테이너 내에서 pid 1001을 가진 사용자로 실행되지만 pid 1001을 가진 사용자는 없습니다.도커 호스트그래서 이 사용자에게 어떤 제한이 적용되는지 모르겠습니다.
  • 모든 사용자에 대해 여러 제한을 추가했습니다 /etc/security/limits.conf(아래 참조).
  • 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 프로세스의 한계(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개 이상의 스레드에 액세스하는 방법을 찾았습니다.

내 도커 컨테이너는 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

내 도커 컨테이너에 로그인했을 때 해당 사용자에 대한 이 제한을 제거하는 ~/.bashrc명령을 추가했습니다 . ulimit -u unlimited이제 이 4096 천장을 돌파할 수 있게 되었습니다.

이 솔루션은 별로 만족스럽지 않습니다. 왜냐하면 실행 중인 모든 컨테이너를 조정해야 하기 때문입니다.도커 호스트모두 고유한 제한이 있기 때문에 모든 빌드 명령을 사용자로 실행하므로 1001컨테이너가 실행 중인 스레드 수를 묻는 것처럼 보입니다. 그는 자신의 예제뿐만 아니라 모든 컨테이너에 대한 모든 스레드를 함께 "봅니다".

이에 대해 docker-for-linux github에 문제를 만들었습니다.https://github.com/docker/for-linux/issues/654

관련 정보