← Назад к вопросам

В чём разница между kill-15 и kill-9 в Linux?

1.0 Junior🔥 281 комментариев
#Linux и администрирование

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между kill -15 (SIGTERM) и kill -9 (SIGKILL)

В Linux сигналы SIGTERM (15) и SIGKILL (9) — это два принципиально разных механизма завершения процессов, с ключевыми отличиями в уровне контроля, безопасности и корректности освобождения ресурсов. Как инженер с десятилетним опытом, я всегда рассматриваю выбор между ними как компромисс между корректным завершением и гарантированным прекращением работы процесса.

Основное концептуальное различие

  • kill -15 или SIGTERM (Signal Terminate) — это вежливый запрос на завершение. Он уведомляет процесс о том, что ему пора завершить работу, позволяя ему выполнить процедуры очистки.
  • kill -9 или SIGKILL (Signal Kill) — это безусловный и немедленный приказ на уничтожение. Сигнал направляется непосредственно ядру ОС, которое принудительно останавливает процесс, не уведомляя само приложение.

Детальное сравнение

SIGTERM (Корректное завершение)

Это сигнал по умолчанию для утилиты kill. Его поведение:

  • Перехват и обработка: Процесс может (и должен) перехватить этот сигнал (trap в bash, сигнальные обработчики в C/Python/Go и т.д.) и выполнить критически важные действия перед выходом.
  • Корректность: Позволяет приложению:
    *   Сохранить данные пользователя или состояние приложения на диск.
    *   Закрыть открытые файлы, сетевые соединения (сокеты) и дескрипторы баз данных корректно.
    *   Отправить уведомления связанным системам или дочерним процессам.
    *   Освободить другие выделенные ресурсы (разделяемую память, семафоры).
    *   Завершить работу с правильным кодом выхода.
  • Иерархия: При правильной настройке может быть распространен на дочерние процессы.
  • Сценарий использования: Является предпочтительным и первым шагом при любом плановом или аварийном останове сервиса (рестарт, деплой, масштабирование). Все системы инициализации (systemd, sysvinit) и оркестраторы (Kubernetes) сначала используют SIGTERM.

Пример обработки SIGTERM в Bash-скрипте:

#!/bin/bash

# Функция для корректной очистки
cleanup() {
    echo "Получен SIGTERM, выполняю очистку..."
    # Закрываем файловые дескрипторы, останавливаем фонные задачи
    kill -TERM ${CHILD_PID} 2>/dev/null
    rm -f /tmp/myapp.lock
    echo "Очистка завершена."
    exit 0
}

# Назначаем функцию cleanup обработчиком для SIGTERM
trap cleanup SIGTERM

# Главный цикл работы приложения
echo "Приложение запущено с PID $$"
some_background_task &
CHILD_PID=$!

# Ожидаем сигнала или делаем свою работу
wait

SIGKILL (Принудительное уничтожение)

Это сигнал последней инстанции. Его характеристики:

  • Неперехватываемый: Процесс не может перехватить или проигнорировать SIGKILL. Обработчик (trap) для этого сигнала назначить невозможно.
  • Немедленный и грубый: Ядро ОС немедленно удаляет процесс из планировщика, освобождает его память и закрывает все его файловые дескрипторы со стороны ядра. Логика самого приложения не выполняется.
  • Риски:
    *   **Потеря данных:** Незавершенные операции записи на диск, в базу данных или в сеть будут прерваны.
    *   **Повреждение состояния:** Могут остаться "висеть" блокировки файлов (`/tmp/myapp.lock`), открытые, но не закрытые корректно соединения к БД (до таймаута).
    *   **Сиротские процессы:** Дочерние процессы могут стать "сиротами" (reparented к init), если родитель не успел их завершить.
    *   **Ресурсные утечки:** Ресурсы, требующие корректного освобождения на уровне приложения (не на уровне ядра), могут быть утеряны.
  • Сценарий использования: Применяется только тогда, когда SIGTERM не сработал и процесс не реагирует, "завис". Это средство для "разруливания" безнадежных ситуаций.

Стратегия использования в продакшн-среде (DevOps)

В современных инфраструктурах важно правильно настроить обработку этих сигналов:

  1. В Docker: По умолчанию docker stop отправляет SIGTERM, а затем, после таймаута (по умолчанию 10 секунд) — SIGKILL. Этот таймаут настраивается флагом --time (-t).

    docker stop --time=30 my_container # Даст 30 секунд на корректное завершение
    
  2. В Kubernetes: При удалении Pod'а:

    *   Сначала отправляется `SIGTERM`.
    *   Начинается отсчет `terminationGracePeriodSeconds` (по умолчанию 30s).
    *   По истечении этого времени отправляется `SIGKILL`.
    *   Ваши приложения должны укладываться в этот grace period. Конфигурация в манифесте:
```yaml
apiVersion: v1
kind: Pod
spec:
  terminationGracePeriodSeconds: 60 # Даем 60 секунд на очистку
  containers:
  - name: app
    ...
```

3. В systemd: Для сервиса можно настроить TimeoutStopSec (таймаут между SIGTERM и SIGKILL) и даже собственный скрипт остановки (ExecStop=) для сложной логики очистки. ini [Service] ExecStart=/usr/bin/myapp ExecStop=/usr/bin/myapp_cleanup.sh # Кастомный скрипт для graceful shutdown TimeoutStopSec=45 KillSignal=SIGTERM # Сигнал по умолчанию можно изменить

Итог и рекомендации

  • Всегда стремитесь сначала к kill -15 (SIGTERM). Это позволяет поддерживать целостность данных и предсказуемость системы.
  • Проектируйте приложения с обработкой graceful shutdown. Они должны ловить SIGTERM, завершать текущие соединения и освобождать ресурсы.
  • kill -9 — это "аварийный молоток". Используйте его осознанно, когда процесс не отвечает на SIGTERM (стал зомби или впал в глубокий дедлок), понимая потенциальные последствия.
  • Правильный порядок в скриптах и ручной работе: kill <PID> -> ждать -> kill -9 <PID>.

Вывод: SIGTERM — это про инженерию и надежность, а SIGKILL — про администрирование и немедленный контроль в критических ситуациях. Понимание этой разницы — базовый навык для любого DevOps-инженера, работающего с Linux-системами.

В чём разница между kill-15 и kill-9 в Linux? | PrepBro