Вопрос с собеседования · DevOps

Почему контейнер не останавливается корректно и «висит» до SIGKILL?

MiddleDocker и контейнерыDockerKubernetes
Ещё спрашивают так:
  • Чем exec-форма CMD отличается от shell-формы?
  • Что такое проблема PID 1 в контейнере?
Коротко

Процесс с PID 1 в контейнере особенный: ядро не применяет к нему действия сигналов по умолчанию, и если приложение не обрабатывает SIGTERM, оно его игнорирует. Частая причина — shell-форма CMD java -jar app.jar: PID 1 становится sh, который не передаёт сигнал приложению. Итог — ожидание таймаута (10 с в Docker, 30 с в Kubernetes) и SIGKILL.

  • Exec-форма: CMD ["java", "-jar", "app.jar"] — приложение само PID 1
  • В скриптах-обёртках — exec "$@" в конце
  • tini или docker run --init — минимальный init, передаёт сигналы и собирает зомби

А ещё В Kubernetes ещё нужна пауза перед остановкой (preStop), чтобы балансировщик успел убрать под

Подробно

Почему SIGTERM игнорируется. Для обычного процесса ядро по умолчанию завершает его при SIGTERM. Для PID 1 в pid-namespace это правило отключено: сигнал действует, только если установлен обработчик. Многие программы обработчика не ставят.

Shell-форма: CMD java -jar app.jar превращается в /bin/sh -c "java -jar app.jar". Sh получает SIGTERM и не пересылает его дочерним процессам.

Исправления:

  • exec-форма CMD и ENTRYPOINT;
  • в entrypoint-скрипте последней строкой exec java …;
  • tini как PID 1 (или --init) — пересылает сигналы и собирает зомби-процессы;
  • приложение корректно обрабатывает SIGTERM: Spring Boot — server.shutdown=graceful.

Kubernetes: при удалении пода одновременно начинается остановка и исключение из Service. Без preStop с короткой паузой часть запросов приходит в уже останавливающийся под.

Что хотят услышать

  • Особенность PID 1 и сигналов.
  • Shell против exec формы.
  • tini и graceful shutdown приложения.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✗Не хватает памяти — контейнер не успевает завершиться
  • ✗PID 1 игнорирует SIGKILL, поэтому нужен больший таймаут
  • ✓Shell-форма CMD: PID 1 — sh, он не передаёт SIGTERM
  • ✗Docker не отправляет SIGTERM, а сразу убивает контейнер по таймауту

Связанные вопросы

Партнёр платформы

Разбор собеседования с sotto

После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.

Разбор собеседования