CentOS 7에서 파일 디스크립터 제한을 확인하고 변경하는 방법

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

CentOS 7에서 웹 서버나 데이터베이스, 프록시 같은 서비스가 많은 파일이나 네트워크 소켓을 동시에 열면 Too many open files 오류가 발생할 수 있습니다. 이때는 현재 파일 디스크립터 사용량과 소프트·하드 제한을 먼저 확인한 뒤, 프로세스가 시작되는 방식에 맞는 설정을 변경해야 합니다.

이 문서에서는 현재 셸과 실행 중인 프로세스의 제한을 확인하는 방법, 로그인 사용자용 PAM 설정, systemd 서비스용 LimitNOFILE 설정, 시스템 전체 fs.file-max 한도를 구분하여 설명합니다.

적용 환경

운영체제 CentOS Linux 7
초기화 시스템 systemd
사용자 예시 admin_user
서비스 예시 httpd.service — 실제 변경 대상 서비스명으로 바꾸어 실행

파일 디스크립터 제한의 종류

파일 디스크립터는 프로세스가 열린 파일, 디렉터리, 네트워크 소켓, 파이프 등을 식별할 때 사용하는 번호입니다. 문제를 해결하려면 다음 세 가지 제한을 구분해야 합니다.

  • 소프트 제한: 현재 프로세스에 실제로 적용되는 값이며, 하드 제한을 넘지 않는 범위에서 낮추거나 높일 수 있습니다.
  • 하드 제한: 일반 사용자가 소프트 제한을 올릴 수 있는 최대값입니다.
  • 시스템 전체 한도: 커널이 시스템 전체에서 할당할 수 있는 파일 핸들의 최대값이며 fs.file-max로 확인합니다.

현재 파일 디스크립터 제한 확인

현재 로그인 셸에 적용된 열린 파일 수의 소프트 제한과 하드 제한을 확인합니다.

ulimit -Sn
ulimit -Hn

ulimit -Sn은 현재 적용되는 소프트 제한을, ulimit -Hn은 해당 셸에서 허용되는 하드 제한을 표시합니다. 숫자는 동시에 열 수 있는 파일 디스크립터 개수를 의미합니다.

현재 셸 프로세스의 제한을 표 형태로 확인하려면 다음 명령어를 사용합니다.

cat /proc/$$/limits | grep -i "Max open files"

출력에는 소프트 제한과 하드 제한이 함께 표시됩니다. 현재 셸의 값이 애플리케이션 프로세스의 값과 반드시 같지는 않으므로, 장애가 발생한 실제 프로세스도 별도로 확인해야 합니다.

실행 중인 프로세스의 제한과 사용량 확인

1. systemd 서비스의 Main PID 확인

예시로 Apache HTTP Server의 메인 프로세스 ID를 확인합니다. 다른 서비스를 점검한다면 httpd.service를 실제 서비스명으로 바꾸십시오.

systemctl show httpd.service -p MainPID

서비스가 실행 중이면 MainPID=숫자 형식으로 표시됩니다. MainPID=0이면 서비스가 실행 중인지 systemctl status로 먼저 확인합니다.

2. 실제 프로세스의 소프트·하드 제한 확인

다음 예시의 1234를 앞에서 확인한 실제 PID로 바꿉니다.

cat /proc/1234/limits | grep -i "Max open files"
prlimit --pid 1234 --nofile

/proc/PID/limitsprlimit은 실행 중인 해당 프로세스에 실제 적용된 값을 보여줍니다. 설정 파일을 수정했더라도 프로세스를 재시작하지 않았다면 기존 값이 계속 표시될 수 있습니다.

3. 프로세스가 현재 사용 중인 파일 디스크립터 수 확인

ls -1 /proc/1234/fd 2>/dev/null | wc -l

결과가 소프트 제한에 지속적으로 가까워진다면 단순히 제한을 높이기 전에 연결 누수, 파일 닫기 실패, 비정상 트래픽, 애플리케이션 설정을 함께 점검해야 합니다.

현재 셸에서 임시로 변경

현재 셸의 소프트 제한을 임시로 65536으로 변경하려면 다음 명령어를 실행합니다. 지정하는 값은 현재 하드 제한보다 클 수 없습니다.

ulimit -Sn 65536
ulimit -Sn

ulimit: open files: cannot modify limit: Operation not permitted가 표시되면 요청한 값이 하드 제한을 초과했거나 현재 계정에 하드 제한을 올릴 권한이 없는 상태입니다. 이 경우 다음의 영구 설정 방법을 사용하십시오.

로그인 사용자의 제한 영구 변경

SSH 로그인이나 콘솔 로그인으로 실행하는 프로그램의 제한은 PAM 설정 파일에서 지정할 수 있습니다. 기존 파일을 직접 길게 수정하기보다 별도의 설정 파일을 만드는 방식이 관리하기 쉽습니다.

admin_user 계정의 소프트·하드 제한을 65536으로 설정하는 예시입니다.

sudo vi /etc/security/limits.d/90-nofile.conf

파일에 다음 내용을 입력합니다.

admin_user soft nofile 65536
admin_user hard nofile 65536

사용자명은 실제 적용할 계정으로 바꾸고, 소프트 제한은 하드 제한보다 높게 설정하지 마십시오. 설정 후 해당 사용자의 기존 세션을 종료하고 새로 로그인한 다음 값을 확인합니다.

ulimit -Sn
ulimit -Hn

systemd 서비스의 제한 영구 변경

CentOS 7에서 systemd가 시작한 서비스는 PAM 로그인 세션을 거치지 않습니다. 따라서 limits.conf를 변경해도 서비스 값은 바뀌지 않으며, 서비스 유닛의 드롭인 설정에 LimitNOFILE을 지정해야 합니다.

1. 현재 서비스 설정 확인

systemctl show httpd.service -p LimitNOFILE

2. 드롭인 설정 작성

배포판이 제공한 원본 유닛 파일을 직접 수정하지 말고 systemctl edit로 재정의 파일을 만듭니다.

sudo systemctl edit httpd.service

열린 편집기에 다음 내용을 입력하고 저장합니다.

[Service]
LimitNOFILE=65536

3. 설정 다시 읽기 및 서비스 재시작

sudo systemctl daemon-reload
sudo systemctl restart httpd.service
sudo systemctl status httpd.service --no-pager

상태가 active (running)인지 확인합니다. 재시작에 실패하면 설정을 원상복구한 뒤 journalctl -u httpd.service로 오류를 확인하십시오.

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

프로세스별 제한을 충분히 높였는데도 시스템 전체 파일 핸들이 고갈되는 경우에만 커널 한도를 점검합니다.

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

fs.file-max는 시스템 전체 최대 파일 핸들 수입니다. /proc/sys/fs/file-nr의 첫 번째 값은 현재 할당된 파일 핸들 수, 세 번째 값은 최대값을 확인하는 데 사용할 수 있습니다.

시스템 전체 한도가 실제 병목으로 확인된 경우에만 다음과 같이 별도 sysctl 파일을 작성합니다. 아래 값은 설정 형식을 보여주는 예시이므로 서버 메모리와 실제 사용량에 맞게 결정해야 합니다.

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

설정을 즉시 적용하고 값을 다시 확인합니다.

sudo sysctl --system
sysctl fs.file-max

변경 결과 확인

systemd 서비스의 설정값과 실제 실행 중인 프로세스 값을 모두 확인해야 합니다.

systemctl show httpd.service -p LimitNOFILE
MAIN_PID=$(systemctl show httpd.service -p MainPID | cut -d= -f2)
cat /proc/"$MAIN_PID"/limits | grep -i "Max open files"
ls -1 /proc/"$MAIN_PID"/fd 2>/dev/null | wc -l

LimitNOFILE과 프로세스의 Max open files가 설정한 값으로 표시되고, 서비스가 정상 실행 중이면 변경이 적용된 것입니다. 실제 사용량이 계속 빠르게 증가한다면 애플리케이션 로그와 연결 상태를 추가로 점검하십시오.

최근 서비스 오류에서 열린 파일 한도 관련 메시지를 확인할 수 있습니다.

sudo journalctl -u httpd.service --since "1 hour ago" --no-pager | grep -iE "too many open files|file descriptor|nofile"

자주 발생하는 오류와 해결 방법

파일 디스크립터 제한 변경 시 점검 항목
증상 가능한 원인 확인 방법 해결 방법
Too many open files 프로세스 사용량이 소프트 제한에 도달함 /proc/PID/limits/proc/PID/fd 개수 비교 적정 수준으로 제한을 높이고 파일·소켓 누수 여부를 함께 점검
limits.d를 수정했지만 서비스 값이 그대로임 서비스가 systemd에서 직접 시작됨 systemctl show 서비스명 -p LimitNOFILE 서비스 드롭인에 LimitNOFILE을 설정하고 재시작
Operation not permitted 소프트 제한을 현재 하드 제한보다 높게 변경하려 함 ulimit -Snulimit -Hn 비교 관리자 권한으로 영구 설정의 하드 제한을 조정한 뒤 새 세션 시작
새 사용자 설정이 기존 터미널에 적용되지 않음 PAM 제한은 로그인 세션 생성 시 적용됨 새 SSH 세션에서 ulimit 재확인 기존 세션을 종료하고 다시 로그인
fs.file-max를 높였지만 오류가 계속됨 개별 프로세스의 nofile 제한이 낮음 cat /proc/PID/limits 사용자 또는 systemd 서비스의 프로세스별 제한을 별도로 조정

원상복구 방법

사용자 제한 설정 제거

이 문서에서 만든 사용자 설정 파일을 제거한 뒤 해당 사용자가 다시 로그인하도록 합니다.

sudo rm -f /etc/security/limits.d/90-nofile.conf

systemd 서비스 설정 제거

서비스용 드롭인 파일을 제거하고 설정을 다시 읽은 다음 서비스를 재시작합니다.

sudo rm -f /etc/systemd/system/httpd.service.d/override.conf
sudo systemctl daemon-reload
sudo systemctl restart httpd.service

시스템 전체 한도 설정 제거

sudo rm -f /etc/sysctl.d/99-file-descriptor.conf
sudo sysctl --system
sysctl fs.file-max

다른 sysctl 파일에도 fs.file-max가 설정되어 있으면 해당 값이 계속 적용될 수 있습니다. 다음 명령으로 중복 설정을 확인하십시오.

grep -R "^[[:space:]]*fs\.file-max" /etc/sysctl.conf /etc/sysctl.d 2>/dev/null

자주 묻는 질문

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

권장하지 않습니다. 애플리케이션의 정상 동시 연결 수와 파일 사용량을 기준으로 여유를 두어 설정하고, 변경 후 실제 사용량을 관찰해야 합니다. 과도한 값은 파일 디스크립터 누수나 비정상 연결 증가를 늦게 발견하게 만들 수 있습니다.

설정 후 서버를 재부팅해야 하나요?

사용자용 PAM 설정은 새 로그인 세션부터 적용되고, systemd 서비스 설정은 daemon-reload 후 해당 서비스를 재시작하면 적용됩니다. 일반적으로 전체 서버 재부팅은 필요하지 않습니다.

root에서 확인한 ulimit 값과 서비스 값이 다른 이유는 무엇인가요?

각 프로세스는 자신을 시작한 부모 프로세스와 서비스 관리자에서 제한을 상속받습니다. root의 로그인 셸과 systemd 서비스는 서로 다른 경로로 시작되므로 제한값이 다를 수 있습니다.

현재 열린 파일 수가 제한보다 낮은데도 오류가 발생할 수 있나요?

오류를 낸 작업 프로세스나 자식 프로세스가 별도의 낮은 제한을 가지고 있을 수 있습니다. 메인 PID뿐 아니라 실제 요청을 처리하는 워커 PID의 /proc/PID/limits/proc/PID/fd도 확인하십시오.

공식 참고자료

마무리

CentOS 7에서 파일 디스크립터 제한을 변경할 때는 현재 셸의 ulimit 값만 확인하지 말고, 오류가 발생한 실제 프로세스의 /proc/PID/limits와 열린 디스크립터 수를 함께 확인해야 합니다.

로그인 사용자에는 PAM의 limits.d, systemd 서비스에는 LimitNOFILE, 시스템 전체 파일 핸들에는 fs.file-max를 사용합니다. 제한을 높인 뒤에도 사용량이 계속 증가한다면 애플리케이션의 파일 또는 소켓 누수를 우선 점검하시기 바랍니다.

CentOS 7은 이미 지원이 종료된 운영체제이므로 설정 변경과 함께 지원 중인 운영체제로의 마이그레이션도 준비하는 것이 안전합니다.

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