Docker 컨테이너가 종료되고 다음이 제공됩니다. -bash: 포크: 재시도: 리소스를 일시적으로 사용할 수 없음

Docker 컨테이너가 종료되고 다음이 제공됩니다. -bash: 포크: 재시도: 리소스를 일시적으로 사용할 수 없음

여기나 다른 커뮤니티에 물어보실지는 모르겠지만(예: 수퍼유저 또는 Unix&Linux)하지만 지금은 여기에 보관할 예정입니다.

Selenium을 사용하고 PM2 런타임으로 관리되는 Dockerised NodeJS 앱이 있습니다. 앱은 다음과 같이 DO 상자에서 실행됩니다.1GB메모리 &25GB디스크. 이 앱은 Selenium WebDriver를 사용하여 2분 간격으로 웹사이트에서 주기적으로 데이터를 긁어내는 것입니다. 얼마 전에 이 문제를 발견했는데 상자에 SSH를 연결하면 모든 명령이 다시 실행됩니다.

-bash: 포크: 재시도: 리소스를 일시적으로 사용할 수 없습니다.

메모리 사용량을 측정하기 위해 모니터링 기능이 있는 새로운 DO 상자를 설정하십시오. 내 사용량이 점점 늘어나고 있어서 어딘가에서 메모리 누수가 발생했다고 생각했습니다. 찾으려고 노력했지만 찾을 수 없었습니다(아직 찾고있는 중). PM2에옵션메모리 사용량이 특정 지점에 도달하면 앱을 다시 시작합니다. 예방 차원에서 이렇게 설정했습니다.800M (80%). 나의 ecosystem.config.js:

module.exports = {
    apps: [
        {
            name: 'scraper',
            script: './index.js',
            watch: process.env.NODE !== 'production',
            ignore_watch: ['node_modules', 'logs', 'test', 'scripts', '.vscode', '.git'],
            out_file: './logs/app.log',
            max_memory_restart: '800M',
            node_args: '--expose-gc',
            env_development: {
                NODE_ENV: 'development'
            },
            env_production: {
                NODE_ENV: 'production'
            }
        }
    ]
}

조금 더 둘러본 결과,PM2는 메모리 누수를 일으킬 수 있습니다가비지 수집을 철저하게 실행하지 않아서 --expose-gc1분 간격으로 강제로 가비지 수집을 실행하도록 노드 인수를 포함시켰습니다.(기준으로이 예):

exports.generateHeapDumpAndStats = function() {
    try {
        if (global.gc) {
            global.gc()
        } else {
            logger.info('Garbage collection unavailable. Use "--expose-gc" when launching to enable forced garbage collection')
        }
        const heapUsed = process.memoryUsage().heapUsed
        const heapUsedMb = (heapUsed / 1024 * 1024).toFixed(2)
        logger.info(`Program is using ${heapUsedMb} MB of heap`)
    } catch (err) {
        logger.error(`Error: ${err.message}`)
        process.exit(1)
    }
}

가비지 수집이 실패하더라도 PM2는 @ 80% 사용량으로 다시 시작되므로 이것이 발견될 것이라고 생각했습니다. @ 대략적으로 컨테이너를 시작했습니다.오후 10시 45분 (GMT +1)& 내 사용량 그래프로 판단하면 컨테이너가 잘립니다 @오전 2시. 지난 24시간 동안의 사용량 그래프는 다음과 같습니다.

여기에 이미지 설명을 입력하세요

메모리 사용량이 80%에도 미치지 못하는 것을 볼 수 있는데 임시 조치로 다시 시작 임계값을 낮춰야 합니까?

상자 자체의 메모리 사용량을 보려고 했지만 내가 입력하는 모든 명령에서 위의 오류가 발생합니다.

설정해 볼 가치가 있나요 --max_old_space_size? 나는 NodeJS 프로세스가 이 상자에 없는 1.5GB의 메모리를 스스로 할당하려고 시도하는 것을 보았습니다.

왜 이런 일이 일어나는지 매우 혼란스럽습니다. 안타깝게도 컨테이너의 로그는 상자의 로컬 파일에만 기록되므로 지금은 액세스할 수 없습니다.

실행 중인 컨테이너를 확인하려고 시도했는데 유용한 내용이 한 번 뱉어졌습니다.

여기에 이미지 설명을 입력하세요

npm start명령은 다음과 같습니다

sudo -E pm2-runtime --raw 생태계.config.js --env 프로덕션 --전용 스크레이퍼

그리고 완료하세요 Dockerfile:

FROM selenium/standalone-chrome

WORKDIR /usr/src/app

RUN curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
RUN sudo apt-get install -y nodejs build-essential firefox

# copy package.json & package-lock.json and install packages
# we do this separate from the application code to better use docker's caching
# `npm install` will be cached on future builds if only the app code changed
COPY package*.json ./

RUN sudo npm install pm2 -g
RUN sudo npm install

# ENV vars dynamically set here by CI

# copy the app
COPY . .

# expose port for express & start
EXPOSE 3000
CMD [ "npm", "start"]

필요한 경우 요청 시 코드를 제공하겠습니다. 처음에는 필요하다고 생각하지 않았고 질문을 너무 크게 만들고 싶지 않았습니다. :)

메모: 처음에 이 질문을 SO에 게시했지만 여기로 옮겨달라는 요청을 받았습니다.

편집하다

@dirkt의 의견에 따르면 리소스 제한에 도달한 것 같습니다. 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) 3842
max locked memory       (kbytes, -l) 16384
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 3842
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

따라서 사용자에게는 프로세스 제한이 있는데, 이는 제가 직면하고 있는 것이라고 생각합니다. 하지만 이 값을 어디에서 변경해야 할지 잘 모르겠습니다. 이 값을 설정해야 할까요, unlimited아니면 임의의 값으로 올리면 될까요? 에는 제한이 설정되어 있지 않습니다 /etc/security/limits.conf. 나는 소프트/하드를 변경하는 몇 가지 방법을 보았습니다.( ulimitCLI, limits.conf, user.conf- 내가 실행 중인 것처럼 후자가 나와 관련이 없다고 생각합니다 root.)사용자에 대한 제한. 이 도커 컨테이너를 다음과 같이 실행하고 있다는 점도 주목할 가치가 있습니다.root (나중에는 바뀔 예정)

관련 정보