Контейнер Docker умирает и выдает: -bash: fork: retry: Ресурс временно недоступен

Контейнер Docker умирает и выдает: -bash: fork: retry: Ресурс временно недоступен

Не уверен, стоит ли спрашивать об этом здесь или в других сообществах.(т.е. SuperUser или Unix&Linux)но пока останусь здесь.

У меня есть докеризованное приложение NodeJS, использующее Selenium и управляемое средой выполнения PM2. Приложение работает на коробке DO с1ГБОбъем памяти &25ГБДиск. Приложение просто периодически извлекает данные с веб-сайта с интервалом в 2 минуты с помощью Selenium WebDriver. Я столкнулся с этой проблемой некоторое время назад, когда при подключении по SSH к ящику любая команда выдавала:

-bash: fork: retry: Ресурс временно недоступен

Настройте новый DO box с мониторингом для измерения использования памяти. У меня использование росло, поэтому я подумал, что где-то есть утечка памяти. Пытался найти ее, но не смог(еще ищете). Я видел, что 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-gcдля принудительного запуска сборки мусора с интервалом в минуту(на основеэтот пример):

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:00 утра. Вот графики моего использования за последние 24 часа:

введите описание изображения здесь

Вы видите, что использование памяти даже близко не приближается к 80%. Может, мне стоит снизить порог перезапуска в качестве временной меры?

Я попытался посмотреть использование памяти на самом устройстве, но любая введенная мной команда выдает указанную выше ошибку.

Стоит ли мне попытаться установить --max_old_space_size? Я видел, что процесс NodeJS пытается выделить себе 1,5 ГБ памяти, которой у меня нет на этом компьютере.

Я очень озадачен, почему это происходит. К сожалению, логи контейнера записываются только в локальный файл на коробке, поэтому сейчас я не могу получить к ним доступ.

Я попытался проверить запущенные контейнеры, и однажды он выдал что-то полезное:

введите описание изображения здесь

Моя npm startкоманда:

sudo -E pm2-runtime --raw экосистема.config.js --env производство --only скребок

И завершите 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. Я видел несколько способов изменить soft/hard( ulimitCLI, limits.conf, user.conf- я полагаю, что последнее не имеет для меня значения, поскольку я баллотируюсь как root)ограничения для пользователя. Также стоит отметить, что я запускаю этот docker-контейнер какroot (в будущем это изменится)

Связанный контент