Node как PID 1 в контейнере
Вопрос
Контейнер запускается CMD ["node", "server.js"], обработчика SIGTERM в коде нет. При docker stop контейнер 10 секунд «думает», потом убивается. Почему?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Варианты ответа
- Node всегда игнорирует SIGTERM, для остановки нужно слать SIGINT
- У PID 1 нет действий по умолчанию: без обработчика SIGTERM игнорируетсяправильный ответ
- Docker отправляет SIGTERM только процессам, запущенным через shell
- 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 ошибок.