Выбор ответа Senior Файлы и процессы обновлено

Node как PID 1 в контейнере

Вопрос

Контейнер запускается CMD ["node", "server.js"], обработчика SIGTERM в коде нет. При docker stop контейнер 10 секунд «думает», потом убивается. Почему?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: У PID 1 нет действий по умолчанию: без обработчика SIGTERM игнорируется. Ядро Linux не применяет действия по умолчанию (завершение) к сигналам для PID 1 в пространстве имён, если процесс сам не установил обработчик.

Варианты ответа

  1. Node всегда игнорирует SIGTERM, для остановки нужно слать SIGINT
  2. У PID 1 нет действий по умолчанию: без обработчика SIGTERM игнорируетсяправильный ответ
  3. Docker отправляет SIGTERM только процессам, запущенным через shell
  4. Node ждёт, пока сборщик мусора освободит память, и не успевает

Разбор

Ядро Linux не применяет действия по умолчанию (завершение) к сигналам для PID 1 в пространстве имён, если процесс сам не установил обработчик. Node без обработчика SIGTERM оказывается неубиваемым по-хорошему, и Docker после таймаута (10 с по умолчанию) шлёт SIGKILL: запросы рвутся без graceful shutdown.

Решения: свой обработчик process.on("SIGTERM", ...) с корректной остановкой и --init (tini) как PID 1, который заодно собирает зомби-процессы. Плохая альтернатива: CMD npm start или shell-форма CMD node server.js, тогда PID 1 становится shell или npm, и сигнал может вообще не дойти до node. Node SIGTERM не игнорирует, когда он не PID 1; GC тут ни при чём.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.