Справочник системных ошибок и решений

Windows Server, Active Directory, 1С:Предприятие, СУБД, Linux, Cisco, MikroTik, Asterisk.

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

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.

Полезные материалы
Рекомендуем