Сравнение Docker Stop и Kill: Когда использовать каждую команду

Освойте управление контейнерами Docker, поняв критические различия между `docker stop` и `docker kill`. Узнайте, когда использовать `SIGTERM` для корректного завершения работы с сохранением целостности данных, и когда необходим `SIGKILL` для немедленного принудительного завершения работы неотвечающих контейнеров. Это руководство содержит практические примеры и лучшие практики для выбора правильной команды для оптимальной стабильности приложения и эффективного рабочего процесса.

Сравнение Docker Stop и Kill: когда использовать каждую команду

Когда ваш контейнер нужно остановить, docker stop и docker kill не взаимозаменяемы. Разница наиболее важна, когда ваше приложение записывает данные, поддерживает сетевые соединения или требует времени для очистки перед завершением.

Используйте docker stop для обычного завершения работы. Используйте docker kill, когда вам нужен немедленный сигнал, обычно потому, что контейнер проигнорировал корректную остановку или вы тестируете поведение при сбоях.

Понимание docker stop

Команда docker stop запрашивает корректный выход основного процесса контейнера. По умолчанию Docker отправляет SIGTERM PID 1 внутри контейнера, ожидает в течение периода ожидания, а затем отправляет SIGKILL, если процесс все еще работает.

Этот первый сигнал может быть изменен инструкцией STOPSIGNAL образа или опцией --stop-signal, используемой при создании контейнера. Однако в большинстве повседневных случаев вы можете думать о docker stop как о "отправить приложению запрос на завершение, затем принудительно завершить его, только если оно не выйдет".

  • Сохранить свое текущее состояние.
  • Закрыть открытые сетевые соединения.
  • Освободить ресурсы, которые он удерживает.
  • Завершить любые текущие операции (например, запись данных на диск).

В контейнерах Linux время ожидания по умолчанию обычно составляет 10 секунд, если для контейнера не был настроен другой тайм-аут остановки. Контейнеры Windows используют более длинное значение по умолчанию. Вы можете переопределить время ожидания для каждой команды с помощью -t или --time.

Как работает docker stop

  1. Отправка SIGTERM: Docker отправляет сигнал SIGTERM основному процессу (PID 1) внутри контейнера.
  2. Ожидание периода ожидания: Docker ожидает завершения процесса.
  3. Отправка SIGKILL (при необходимости): Если процесс не завершился к концу периода ожидания, Docker отправляет сигнал SIGKILL.

Когда использовать docker stop

  • Обычное завершение работы приложения: Это предпочтительный метод для остановки приложений, которые должны корректно завершать работу, таких как базы данных, веб-серверы или приложения, выполняющие критически важные записи.
  • Среды разработки: Для обычных остановок во время разработки docker stop гарантирует, что вы случайно не прервете текущие процессы.
  • Производственные среды для планового обслуживания: Когда вам нужно перезапустить службу или выполнить обновления, docker stop позволяет приложению завершить свою работу.

Пример

# Запустить контейнер с именем 'my-web-server'
docker run -d --name my-web-server -p 80:80 nginx

# Корректно остановить контейнер
docker stop my-web-server

# Проверить, что контейнер остановлен
docker ps -a | grep my-web-server

Если вашему приложению нужно больше времени для очистки очередей или закрытия соединений с базой данных, дайте ему более длительный тайм-аут:

docker stop --time 30 my-web-server

Понимание docker kill

Команда docker kill немедленно отправляет сигнал основному процессу контейнера. По умолчанию этот сигнал — SIGKILL. В отличие от SIGTERM, SIGKILL не может быть перехвачен, проигнорирован или обработан процессом. Операционная система завершает процесс, не давая ему возможности выполнить очистку.

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

Вы также можете использовать docker kill --signal для отправки другого сигнала, например SIGHUP, но если ваша цель — корректное завершение работы, docker stop обычно понятнее.

Как работает docker kill

  1. Отправка SIGKILL: Docker отправляет сигнал SIGKILL непосредственно основному процессу (PID 1) внутри контейнера.
  2. Немедленное завершение: Процесс завершается операционной системой.

Когда использовать docker kill

  • Неотвечающие контейнеры: Когда контейнер завис и docker stop не смог завершить его даже после периода ожидания.
  • Экстренные остановки: В ситуациях, когда вам нужно немедленно остановить контейнер, независимо от последствий, например, при инцидентах безопасности или критических сбоях.
  • Тестирование отказоустойчивости: Чтобы увидеть, как ваше приложение ведет себя, когда процесс исчезает без очистки.

Пример

# Запустить контейнер с именем 'my-test-app'
docker run -d --name my-test-app ubuntu sleep infinity

# Принудительно завершить контейнер
docker kill my-test-app

# Проверить, что контейнер остановлен
docker ps -a | grep my-test-app

Ключевые различия в сводке

Особенность docker stop docker kill
Отправляемый сигнал Обычно SIGTERM, затем SIGKILL, если истек тайм-аут SIGKILL по умолчанию
Завершение Корректное, позволяет выполнить очистку Немедленное, принудительное, без очистки
Целостность данных Обычно сохраняет целостность данных Риск повреждения данных или неконсистентного состояния
Сценарий использования Обычное завершение, плановое обслуживание Неотвечающие контейнеры, экстренные остановки
Период ожидания Да Нет

Лучшие практики и соображения

  • Всегда сначала пробуйте docker stop: Для рутинных операций docker stop должен быть вашим выбором по умолчанию. Он защищает ваши приложения и данные.
  • Понимайте сигналы вашего приложения: Приложения могут быть запрограммированы на обработку сигналов SIGTERM. Убедитесь, что сценарий точки входа вашего приложения или менеджер процессов настроены на прослушивание и корректный ответ на SIGTERM.
  • Настройте период ожидания для docker stop: Вы можете указать собственный период ожидания для docker stop, используя флаг -t или --time. Например, docker stop -t 30 my-container дает контейнеру 30 секунд на завершение работы.
  • Используйте docker kill как крайнюю меру: Прибегайте к docker kill только тогда, когда docker stop неэффективен или в критических, срочных ситуациях.
  • Мониторьте состояние контейнера: Внедрение проверок здоровья в вашей настройке Docker может помочь выявить контейнеры, которые становятся неотвечающими, что позволит вам потенциально решить проблемы до того, как они потребуют docker kill.
  • Проверьте поведение PID 1: Скрипты-оболочки могут проглатывать сигналы, если они не перенаправляют их реальному процессу приложения. Предпочитайте exec в сценариях точки входа, чтобы приложение получало сигналы завершения напрямую.

Практический вывод

Сделайте docker stop своей обычной привычкой, особенно для всего, что имеет состояние. Используйте docker kill только тогда, когда контейнер не отвечает, когда скорость важнее очистки или когда вы намеренно тестируете поведение при сбое.