Ubuntu 22.04에서 Too many open files 오류를 해결하는 방법

안녕하세요. VISION IDC 기술팀입니다.

Ubuntu 22.04 서버에서 웹 서버, 데이터베이스, 애플리케이션 또는 백그라운드 서비스가 많은 파일과 소켓을 동시에 열면 Too many open files 오류가 발생할 수 있습니다. 이 오류는 일반적으로 해당 프로세스가 사용할 수 있는 파일 디스크립터 한도인 RLIMIT_NOFILE에 도달했을 때 나타나지만, 드물게 시스템 전체 파일 핸들 한도가 부족한 경우에도 비슷한 문제가 발생할 수 있습니다.

이 문서에서는 현재 한도와 실제 사용량을 확인하고, systemd 서비스와 로그인 사용자 환경에 맞게 파일 디스크립터 제한을 수정하는 방법을 설명합니다. 한도를 무조건 크게 설정하기보다 열린 파일 수가 계속 증가하는 원인이 애플리케이션의 파일 또는 소켓 누수인지 먼저 확인하는 것이 중요합니다.

적용 환경

운영체제 Ubuntu 22.04 LTS (Jammy Jellyfish)
서비스 관리 systemd
주요 설정 LimitNOFILE, /etc/security/limits.d/*.conf, fs.file-max

Ubuntu 22.04 LTS는 현재 표준 보안 유지보수 기간에 있으며 Canonical의 현재 릴리스 주기 기준 표준 지원은 2027년 5월까지 제공됩니다.

가장 먼저 확인할 항목

현재 셸 세션의 soft limit과 hard limit을 확인합니다. soft limit은 프로세스가 현재 적용받는 한도이며, 일반 사용자는 hard limit을 초과해 soft limit을 높일 수 없습니다.

ulimit -Sn
ulimit -Hn

이 값은 현재 로그인 셸의 한도입니다. 오류가 systemd로 실행되는 웹 서버나 데이터베이스 서비스에서 발생했다면 셸의 ulimit 값만 확인해서는 실제 서비스 한도를 알 수 없습니다.

문제가 발생한 프로세스의 한도와 사용량 확인

1. systemd 서비스의 MainPID 확인

SERVICE_NAME.service를 실제 서비스 이름으로 바꿔 실행합니다.

systemctl show SERVICE_NAME.service -p MainPID --value

실행 중인 단일 메인 프로세스가 있는 서비스라면 PID가 표시됩니다. 값이 0이면 서비스가 실행 중인지 또는 별도의 프로세스 구조를 사용하는지 systemctl status로 확인합니다.

2. 실제 프로세스의 open files 제한 확인

PID를 앞에서 확인한 숫자로 바꿉니다.

cat /proc/PID/limits | grep 'Max open files'

출력에는 해당 프로세스의 soft limit과 hard limit이 표시됩니다. 오류가 발생한 프로세스의 실제 제한을 판단할 때는 이 값을 기준으로 확인하는 것이 정확합니다.

3. 현재 열려 있는 파일 디스크립터 수 확인

ls -1 /proc/PID/fd | wc -l

현재 FD 수가 soft limit에 매우 근접해 있고 로그에도 Too many open files가 기록된다면 프로세스별 한도 부족일 가능성이 높습니다. 반대로 FD 수가 지속적으로 증가해 내려오지 않는다면 한도를 늘리기 전에 애플리케이션의 파일 또는 소켓 누수를 점검해야 합니다.

4. 서비스 로그에서 오류 확인

journalctl -u SERVICE_NAME.service --since '30 minutes ago' --no-pager

해당 시간대에 Too many open files 또는 파일·소켓 생성 실패와 관련된 메시지가 있는지 확인합니다. 애플리케이션이 자체 로그를 사용하는 경우 해당 로그도 함께 확인해야 합니다.

systemd 서비스의 파일 디스크립터 한도 변경

Ubuntu 22.04에서 systemd가 관리하는 서비스라면 /etc/security/limits.conf를 수정하는 대신 해당 유닛의 LimitNOFILE= 설정을 사용하는 것이 명확합니다. 먼저 현재 systemd가 서비스에 적용하는 값을 확인합니다.

systemctl show SERVICE_NAME.service -p LimitNOFILE

서비스의 기본 유닛 파일을 직접 수정하면 패키지 업데이트 시 변경 내용이 사라질 수 있으므로 systemd drop-in을 사용합니다.

sudo systemctl edit SERVICE_NAME.service

편집기에 다음 내용을 입력합니다. 65536은 예시 값이며 실제 동시 연결 수와 애플리케이션 요구사항에 맞춰 결정해야 합니다.

[Service]
LimitNOFILE=65536

설정을 저장한 뒤 systemd 구성을 다시 읽고 서비스를 재시작합니다.

sudo systemctl daemon-reload
sudo systemctl restart SERVICE_NAME.service

재시작 후 서비스가 정상인지 확인합니다.

systemctl status SERVICE_NAME.service --no-pager
systemctl show SERVICE_NAME.service -p LimitNOFILE

로그인 사용자의 파일 디스크립터 한도 변경

SSH나 콘솔 로그인으로 시작되는 사용자 세션의 한도를 변경하려면 PAM의 pam_limits가 읽는 /etc/security/limits.conf 또는 /etc/security/limits.d/*.conf를 사용할 수 있습니다. 관리 편의를 위해 별도의 파일을 만드는 방법을 권장합니다.

sudo nano /etc/security/limits.d/99-nofile.conf

예를 들어 admin_user의 soft/hard limit을 각각 65536으로 설정하려면 다음과 같이 작성합니다.

admin_user soft nofile 65536
admin_user hard nofile 65536

이 설정은 기존 세션에 소급 적용되지 않습니다. 해당 사용자가 완전히 로그아웃한 뒤 새로 로그인하고 다시 확인합니다.

ulimit -Sn
ulimit -Hn

시스템 전체 파일 핸들 한도 확인

프로세스별 RLIMIT_NOFILE과 시스템 전체 파일 핸들 한도는 서로 다른 제한입니다. 먼저 시스템 전체의 현재 사용량과 최대값을 확인합니다.

cat /proc/sys/fs/file-nr
sysctl fs.file-max
sysctl fs.nr_open

/proc/sys/fs/file-nr의 첫 번째 값은 할당된 파일 핸들 수이고 마지막 값은 시스템 전체 최대값입니다. 할당된 수가 최대값에 근접하거나 커널 로그에 VFS: file-max limit ... reached 메시지가 확인되는 경우에만 fs.file-max 조정을 검토하는 것이 좋습니다.

커널 로그를 확인합니다.

journalctl -k --no-pager | grep -i 'file-max\|file handle'

시스템 전체 한도 부족이 실제로 확인된 경우 임시로 값을 높일 수 있습니다. 아래 2097152는 예시이므로 서버 메모리와 워크로드에 맞춰 결정해야 합니다.

sudo sysctl -w fs.file-max=2097152

재부팅 후에도 유지하려면 별도 sysctl 설정 파일을 만듭니다.

sudo nano /etc/sysctl.d/99-file-max.conf
fs.file-max = 2097152

설정을 다시 읽고 값을 확인합니다.

sudo sysctl --system
sysctl fs.file-max

변경 사항 적용 여부 확인

systemd 서비스라면 먼저 설정값과 실제 프로세스 한도를 모두 확인합니다. 서비스 재시작 후 새 PID가 생성될 수 있으므로 PID를 다시 조회합니다.

systemctl show SERVICE_NAME.service -p LimitNOFILE
systemctl show SERVICE_NAME.service -p MainPID --value

PID를 새로 확인한 값으로 바꿔 실제 프로세스 제한을 확인합니다.

cat /proc/PID/limits | grep 'Max open files'
ls -1 /proc/PID/fd | wc -l

로그인 사용자 설정을 변경했다면 새 세션에서 ulimit -Snulimit -Hn을 확인합니다. 이후 실제 트래픽이나 작업을 수행하면서 오류가 재발하는지 서비스 로그를 모니터링합니다.

자주 발생하는 문제와 해결 방법

파일 디스크립터 제한 변경 시 자주 확인하는 항목
증상 가능한 원인 확인 방법 해결 방법
Too many open files가 계속 발생 실제 서비스 프로세스에 새 한도가 적용되지 않음 /proc/PID/limitssystemctl show 비교 drop-in 저장 여부를 확인하고 daemon-reload 후 서비스를 재시작합니다.
limits.d를 수정해도 값이 그대로임 기존 로그인 세션을 사용 중이거나 systemd 시스템 서비스에 적용하려고 함 새 로그인 후 ulimit 확인, 서비스라면 systemctl show 확인 로그인 세션은 완전히 재로그인하고, systemd 서비스는 LimitNOFILE을 설정합니다.
한도를 높여도 FD 수가 계속 증가 애플리케이션의 파일·소켓 누수 또는 비정상적인 연결 증가 /proc/PID/fd 개수를 시간 간격을 두고 비교하고 애플리케이션 로그 확인 원인이 되는 애플리케이션, 연결 관리, 워커 수 또는 코드의 파일 닫기 처리를 점검합니다.
시스템 전체에서 파일 열기 실패가 발생 fs.file-max 한도에 근접 /proc/sys/fs/file-nr, fs.file-max, 커널 로그 확인 실제 한도 부족이 확인된 경우에만 fs.file-max를 조정하고 비정상적으로 많은 FD를 사용하는 프로세스를 함께 점검합니다.
매우 큰 LimitNOFILE 값 설정이 실패 설정값이 fs.nr_open 상한을 초과 sysctl fs.nr_open 확인 필요한 FD 규모를 다시 산정하고, 정말 필요한 경우에만 커널 상한 변경을 검토합니다.

원상복구 방법

systemd 서비스 설정 제거

추가한 drop-in을 제거하려면 다음 명령으로 편집기를 열어 LimitNOFILE 설정을 삭제하거나, 해당 서비스에 추가한 drop-in 파일을 정확히 확인한 뒤 제거합니다. 변경 후에는 systemd 구성을 다시 읽고 서비스를 재시작해야 합니다.

sudo systemctl edit SERVICE_NAME.service
sudo systemctl daemon-reload
sudo systemctl restart SERVICE_NAME.service

로그인 사용자 설정 제거

직접 만든 /etc/security/limits.d/99-nofile.conf의 해당 사용자 항목을 삭제한 뒤 새 로그인 세션에서 기본값으로 돌아왔는지 확인합니다.

시스템 전체 설정 제거

직접 만든 /etc/sysctl.d/99-file-max.conf에서 fs.file-max 항목을 제거하고 재부팅하여 커널 기본값을 사용하거나, 이전에 기록해 둔 원래 값을 명시적으로 복원합니다.

자주 묻는 질문

파일 디스크립터 한도는 무조건 크게 설정해도 되나요?

권장하지 않습니다. 필요한 동시 연결 수와 애플리케이션의 동작 방식을 기준으로 결정해야 하며, FD 사용량이 비정상적으로 계속 증가한다면 한도 확대보다 누수 원인을 먼저 해결해야 합니다.

ulimit -n 값과 systemd 서비스의 값이 다른가요?

현재 셸은 로그인 세션에서 받은 제한을 사용하지만 systemd 시스템 서비스는 서비스 관리자와 유닛의 LimitNOFILE 설정에 따라 별도의 제한을 받을 수 있기 때문입니다.

서비스 재시작 없이 새 한도를 적용할 수 있나요?

일반적으로 유닛의 LimitNOFILE 변경은 새로 시작되는 프로세스에 적용되므로 서비스를 재시작해야 합니다. 운영 서비스에서는 재시작에 따른 영향과 애플리케이션 자체의 무중단 재로드 지원 여부를 별도로 확인하십시오.

시스템 전체 fs.file-max도 항상 같이 높여야 하나요?

아닙니다. Too many open files는 보통 프로세스별 한도에 먼저 도달했을 때 발생합니다. /proc/sys/fs/file-nr와 커널 로그에서 시스템 전체 한도 부족이 확인되지 않았다면 fs.file-max를 변경할 필요가 없습니다.

공식 참고자료

마무리

Ubuntu 22.04에서 Too many open files 오류가 발생하면 먼저 오류를 낸 프로세스의 현재 FD 사용량과 RLIMIT_NOFILE을 비교해야 합니다. systemd 서비스는 LimitNOFILE, 로그인 사용자는 limits.d에서 설정하고, 시스템 전체 fs.file-max는 실제 한도 부족이 확인된 경우에만 조정하는 것이 안전합니다.

한도를 높인 뒤에도 열린 파일 수가 계속 증가한다면 설정 문제가 아니라 애플리케이션의 파일 또는 소켓 누수일 수 있습니다. 변경 후에는 반드시 실제 프로세스의 /proc/PID/limits와 서비스 로그를 다시 확인하시기 바랍니다.

  • 0 사용자에게 유용한 정보 제공
이 답변이 도움이 되었나요?
« Back