fork rejected by pids controller (pids.max exceeded) — Решение лимита процессов
Архитектура ошибки и симптомы сбоя
Ошибка «cgroup: fork rejected by pids controller (pids.max exceeded)» генерируется подсистемой контрольных групп cgroups v1 / cgroups v2 (pids controller). Она возникает, когда процесс внутри определенного слайса systemd, контейнера Docker/Podman или Kubernetes Pod пытается создать дочерний процесс или поток (системные вызовы fork(), vfork(), clone()), но суммарное количество PID в данной cgroup уже достигло жесткого лимита pids.max (или TasksMax в systemd). Приложение возвращает ошибку EAGAIN / Resource temporarily unavailable.
Диагностическая таблица параметров сбоя
| Параметр | Значение | Инженерный смысл сбоя |
|---|---|---|
| pids.max | Integer / max | Максимально разрешенное количество потоков/процессов в контрольной группе. |
| pids.current | Current PID Count | Фактическое число активных PID/TID внутри cgroup в данный момент. |
| Trigger Scope | Docker / Systemd / K8s | Предотвращение исчерпания системной таблицы PID всей ОС (защита от Fork-Bomb). |
Пошаговое дерево решений и сценарии траблшутинга
Сценарий 1: Поиск контрольной группы с превышенным лимитом PID
# Поиск cgroups, где текущее число PID равно лимиту (cgroups v2):
for p in /sys/fs/cgroup/**/pids.current; do
dir=$(dirname $p)
max=$(cat $dir/pids.max 2>/dev/null)
cur=$(cat $p)
if [ "$max" != "max" ] && [ "$cur" -ge "$max" ]; then
echo "EXCEEDED: $dir (Current: $cur / Max: $max)"
fi
doneСценарий 2: Увеличение TasksMax для служб Systemd
Если лимит процессов превышен системной службой (например, Nginx, PostgreSQL, GitLab):
# Открытие оверрайда конфигурации службы:
sudo systemctl edit service_name.service
# Добавьте в открывшийся файл:
[Service]
TasksMax=infinity
# Примените изменения:
sudo systemctl daemon-reload
sudo systemctl restart service_name.serviceСценарий 3: Настройка лимитов PID в Docker и Kubernetes
Для контейнеров Docker увеличьте --pids-limit:
# Запуск контейнера без ограничения PID:
docker run -d --pids-limit -1 my_image
# Либо глобально в /etc/docker/daemon.json:
{
"default-pids-limit": 8192
}В Kubernetes настройте параметры Kubelet в файле /var/lib/kubelet/config.yaml: podPidsLimit: 4096.
ITSTM выполнит комплексный сайзинг ресурсов pod-ов (CPU/RAM/PIDs), аудит утечек потоков в Java/Go приложениях и тонкую настройку cgroups v2.
Частые вопросы (FAQ)
Считаются ли потоки (threads) отдельными PID для pids controller?
Да. В ядре Linux каждый поток создается системным вызовом clone() и получает собственный уникальный идентификатор задачи (TID), который контроллером cgroups pids учитывается как отдельный PID.
Чем pids.max отличается от ulimit -u (nproc)?
ulimit -u ограничивает количество процессов для конкретного UID пользователя глобально по всей системе, тогда как cgroup pids.max ограничивает суммарное число процессов внутри изолированного дерева cgroup (контейнера или юнита systemd) независимо от пользователя.
Где задается глобальный дефолтный лимит TasksMax для всех служб systemd?
В конфигурационном файле /etc/systemd/system.conf с помощью параметра DefaultTasksMax=512 (или infinity). После изменения требуется выполнить systemctl daemon-reexec.
Как быстро найти процесс, создающий лавину дочерних потоков?
Выполните команду: ps -eo nlwp,pid,args --sort -nlwp | head -n 10. Столбец NLWP покажет количество потоков, созданных процессом.