기술 · 실용 가이드
Linux에서 “fork: Resource temporarily unavailable”? 고갈된 작업 예산부터 증명하세요
제한 상향, 프로세스 종료, 재부팅 전에 사용자·cgroup·systemd·커널 PID/스레드 상한을 구분합니다.

Linux의 fork나 clone은 메모리와 파일 디스크립터가 충분해 보여도 EAGAIN을 반환할 수 있습니다. 고갈된 예산은 사용자, cgroup, systemd 유닛 또는 호스트에 속할 수 있습니다.
이 감사는 증거를 보존하고 실제 경계와 프로세스·스레드 확장 주체를 찾은 뒤 가장 작은 되돌릴 수 있는 수정을 검증합니다.
작업을 해제하기 전에 실패를 고정하세요
복구 셸 하나를 유지하고 재시작 전에 정확한 명령, 시간, 사용자, 서비스/컨테이너, stderr와 종료 상태를 복사합니다. EAGAIN과 ENOMEM을 구분하고 메모리처럼 보인다는 인상으로 실제 errno를 대체하지 않습니다.
같은 범위에서 PID, PPID, 사용자, 명령, NLWP 목록과 최근 배포·트래픽 변화를 저장합니다. 무차별 kill은 어떤 예산과 확장 주체가 문제인지 보여 주는 트리와 카운터를 지울 수 있습니다.
사용자별 예산을 먼저 검사하세요
fork(2)는 RLIMIT_NPROC를 EAGAIN 원인으로 설명합니다. Linux에서는 실제 UID의 작업, 더 정확히는 스레드에 적용됩니다. 실패 프로세스의 실제 UID와 soft/hard limit를 비교하고 프로세스 행이 아닌 살아 있는 스레드를 셉니다.
조사 셸의 높은 ulimit는 서비스의 유효 값을 증명하지 않습니다. 실패 문맥이나 서비스 관리자에서 제한을 수집하고 서비스 계정과 운영자를 구분합니다. 상한에 가깝다면 증가하는 실행 파일과 부모를 찾습니다.
cgroup을 찾고 PID 원장을 읽으세요
cgroup v2 pids 컨트롤러는 각 스레드를 포함한 작업 ID를 셉니다. 대상 cgroup의 pids.current, pids.peak, pids.events, pids.max를 읽고 max 이벤트 증가를 경계 초과와 EAGAIN의 증거로 사용합니다.
systemd 유닛에서는 TasksCurrent, TasksMax, EffectiveTasksMax를 비교합니다. TasksMax는 pids.max에 대응하고 유효 값은 더 좁은 부모 경계를 반영합니다. 실제 유닛과 cgroup을 읽고 호스트와 같은 여유가 있다고 가정하지 않습니다.
가까운 제한에 여유가 있을 때만 호스트 상한을 보세요
사용자와 cgroup에 여유가 있으면 threads-max, pid_max와 호스트 작업 수를 확인합니다. fork(2)는 둘 다 EAGAIN 원인으로 들며 큰 pid_max만으로 다른 상한을 배제할 수 없습니다.
파일 디스크립터 제한과 분리합니다. nofile을 높여도 PID나 스레드 예산은 생기지 않습니다. reset-on-fork 없는 SCHED_DEADLINE도 기록하되 특수 사례를 기본 설명으로 삼지 않습니다.
확장 주체를 찾아 분류하세요
스레드와 자식 수로 정렬해 선두 부모, 서비스, 부하를 정상 기준선과 비교합니다. 한 프로세스의 NLWP 급증은 스레드 누수, 많은 단명 자식은 재시도 폭주·과도한 worker·상류 동시성 변경을 시사합니다.
정상 동시성인지 통제되지 않은 성장인지 결정하고 완화 전에 로그, 스택 샘플, 트리를 보존합니다. 재부팅이나 kill만으로는 원인과 성장 형태가 사라져 사건이 반복됩니다.
가장 작은 되돌릴 수 있는 수정을 적용하세요
누수 또는 폭주 생산자를 중지하고 worker·재시도 동시성을 낮추거나 실제로 너무 낮은 서비스 경계만 수정합니다. 정상 부하와 안전 여유가 측정될 때만 상한을 높이고 무제한과 전체 사용자 변경을 피합니다.
이전 값, 새 값, 소유자, 이유, 롤백 명령을 기록합니다. systemd는 관리되는 유닛 설정을, cgroup·컨테이너는 원본 설정을 바꾸고 일시적 런타임 쓰기에 의존하지 않습니다.
원래 생성 경로를 다시 실행해 여유를 증명하세요
같은 사용자, 유닛, 컨테이너에서 원 명령이나 통제된 부하를 다시 실행하고 실제 자식 생성 여부를 확인합니다. 사용자 스레드, pids.current 대 pids.max, pids.events와 호스트 상한을 재확인합니다.
성공은 fork/clone이 작동하고 관련 이벤트가 더 늘지 않으며 관찰 기간 동안 사용량이 경계 아래에 머무는 것입니다. 증거와 롤백을 보존하고 검증 없는 재부팅 성공을 진단이라 부르지 않습니다.
