Центр Диагностики & База Системных Ошибок

Решения для Windows Server, Active Directory, 1С, СУБД, Linux, Cisco, MikroTik и IP-телефонии.

⚠️ Важная информация Все материалы, инструкции, команды и скрипты предоставлены исключительно в ознакомительных целях. Их применение может повлиять на работу операционной системы, баз данных и сетевого оборудования. Перед выполнением действий обязательно создайте резервную копию. При отсутствии необходимой квалификации обратитесь к ИТ-специалистам.
CONTAINER_ZOMBIE_LEAK Linux / DevOps

Траблшутинг зомби-процессов (defunct) внутри Docker-контейнеров

Обновлено: 21.08.2026
  • Внутри контейнера накапливаются сотни процессов со статусом Z или [command] <defunct> в выводе ps aux.
  • Исчерпание лимита системных дескрипторов процессов ядра (kernel.pid_max), невозможность запустить новые процессы (ошибка fork: Cannot allocate memory).
  • Контейнер зависает при остановке и не реагирует на команду docker stop в течение 10 секунд (падает по SIGKILL).

1. Выявление процессов-зомби внутри запущенного контейнера

docker exec -it <container_name> ps aux | grep -i defunct

# Проверка количества занятых PID на уровне хоста
cat /sys/fs/cgroup/pids/docker/<container_id>/pids.current

2. Решение через встроенный механизм Docker Init (флаг --init)

Docker содержит встроенный легковесный init-процесс (Tini), перехватывающий сигналы и собирающий завершившиеся дочерние потоки (reaping dead children):

docker run -d --name my-service --init my-image:latest

3. Настройка Tini в Docker Compose

Добавьте директиву init: true в блок сервиса:

version: "3.8"
services:
  worker:
    image: python-worker:latest
    init: true
    restart: always

4. Интеграция dumb-init / tini напрямую в Dockerfile

Если образ запускается в средах Kubernetes или старых версиях Docker без поддержки флага --init:

FROM node:18-alpine
RUN apk add --no-cache tini
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["node", "server.js"]
Практический опыт инженера: Если вы запускаете фоновые воркеры через конструкции CMD sh -c 'my_app', шелл sh становится PID 1 и блокирует сигналы. Всегда используйте exec-синтаксис ENTRYPOINT ["/bin/app"] совместно с Tini.

Частые вопросы (FAQ)

Почему процессы переходят в состояние defunct внутри контейнера?

В Linux процесс с PID 1 обязан собирать коды возврата завершившихся дочерних процессов через системный вызов waitid()/waitpid(). Обычные серверные приложения (Node.js, Python, Java) не реализуют эту логику и оставляют зомби-структуры в таблице процессов ядра.

Почему контейнер долго завершается при выполнении docker stop?

Если приложение с PID 1 не перехватывает сигнал SIGTERM, ядро не передает его по умолчанию дочерним процессам. Docker ждет 10 секунд по таймауту и принудительно убивает контейнер через SIGKILL.