리눅스 서버의 로그에서 "IPTABLES nf_conntrack: table full, dropping packet." 경고 메세지를 발견했을 때 대처 방법을 알아보고, 실습을 통해 쉽게 설정하고 사용할 수 있습니다.
f_conntrack: table full, dropping packet. 에러 로그 |
리눅스 서버의 로그에서 "IPTABLES nf_conntrack: table full, dropping packet." 경고 메세지를 발견했을 때 대처 방법을 알아보고, 실습을 통해 쉽게 설정하고 사용할 수 있습니다.
nf_conntrack: table full, dropping packet 커널 메시지를 발생시키며 패킷이 드롭되는 증상과 해결 방법을 설명합니다.
3월 1일 마스크 대란으로 방문자 폭주 현상이 발생했습니다.
Jennifer 모니터링으로 이상 현상을 확인하고 아래와 같은 NGINX 웹 서버의 에러 로그를 다수 확인했습니다.
실습 환경
- OS : CentOS 6.10
- Kernel: 2.6.32-754.2.1.el6.x86_64
- 로그 파일 : /var/log/messages
- 에러 로그 : Mar 1 02:16:40 HOSTNAME kernel: [28476780.603173] nf_conntrack: table full, dropping packet.
로그를 보니 nf_conntrack의 테이블의 용량이 꽉차서 패킷이 DROP 되고 있는 것을 알 수 있습니다.
빠른 장애 처리를 위해 IPTABLES 서비스 종료 후 해결되었습니다.
iptables 서비스를 사용하면서 위와 같은 장애 방지를 위해 커널 파라미터 설정을 알아보겠습니다.
nf_conntrack 이란?
nf_conntrack은 ip_conntrack의 후속 커널 모듈로 netfilter가 네트워크에서 발생하는 커넥션에 대한 내용을 기록하고 추적하기 위한 모듈 입니다.
일반적으로 활성화되지는 않지만 iptables를 이용한 NAT 환경에서 사용되며, 아래와 같은 경우 활성화됩니다.
- iptables -t nat -L 같은 NAT 테이블 추가 및 확인 명령을 실행한 경우
- docker와 같이 iptables의 NAT 기능이 필요한 어플리케이션을 사용 할 경우
단순히, 해당 모듈이 활성화된다고 해서 문제가 되지는 않지만 접속량이 많은 네트워크 서비스를 제공하는 경우에는 nf_conntrack의 설정을 기본 값으로 사용할 경우 연결을 기록하는 테이블의 크기를 기본 값인 65536를 사용하기 때문에 문제가 발생할 수 있습니다.
따라서, 해당 값을 서버의 환경에 맞추어 충분히 늘려주는 게 좋으며 적절한 값을 알아보겠습니다.
네트워크 관련 커널 파라미터 설정하기
nf_conntrack_max 란?
nf_conntrack_max는 nf_conntrack 모듈이 기록 할 최대 연결 개수를 지정하는 파라미터 입니다.
[ 커널 문서 참조 ] nf_conntrack_max - INTEGER Size of connection tracking table. Default value is nf_conntrack_buckets value * 4
nf_conntrack_buckets는 bucket들의 개수이며 다시 말해 해시 테이블의 크기를 의미합니다. 커널 문서에서는 해시 테이블 크기의 4배로 max 값을 지정하는 걸 기본으로 하고 있기 때문에 각 해시 테이블의 bucket은 4개의 노드를 갖는 연결 리스트로 구성됩니다.
[ 메모리 크기에 따른 적정값 계산 ] 계산식 : RAM SIZE(in bytes) / 16384 / (ARCH/32) ex) 메모리 8GB 일 때 (8 * 1073741824) / 16384 / (64/32) = 262144
아래 명령을 통해 실시간 적용 가능합니다.
[echo "최대 연결 개수" > /proc/sys/net/nf_conntrack_max
nf_conntrack_buckets 란?
[ 커널 문서 참조 ] nf_conntrack_buckets - INTEGER Size of hash table. If not specified as parameter during module loading, the default size is calculated by dividing total memory by 16384 to determine the number of buckets but the hash table will never have fewer than 32 and limited to 16384 buckets. For systems with more than 4GB of memory it will be 65536 buckets. This sysctl is only writeable in the initial net namespace.
4GB 메모리에는 65536이 적합하며, 해시 테이블 크기를 지정하지 않고 모듈을 올리면 기본값인 16384로 설정됩니다.
이 상태에서 nf_conntrack_max 값을 늘리게 되면 연결 리스트가 길어지며 해시 테이블의 속도가 느려집니다.
또한 nf_conntrack_buckets 값을 크게 설정하게 되면, 그만큼 해시 테이블을 생성할 때 많은 메모리를 사용하게 됩니다.
따라서 적절한 크기를 할당해야 하며, 해시 테이블 크기에 대한 모듈 파라미터는 docker나 iptables에 의해서 자동으로 로딩 되므로 이 값을 변경해 주어야 하는데, 모듈이 올라가게 되면 sysctl을 이용해서 커널 파라미터 값을 변경 할 수 없고 sysfs를 통해서만 변경이 가능합니다.
[sudo echo 65536 > /sys/module/nf_conntrack/parameters/hashsize]
nf_conntrack_generic_timeout 란?
[ 커널 문서 참조 ] nf_conntrack_generic_timeout - INTEGER (seconds) default 600 Default for generic timeout. This refers to layer 4 unknown/unsupported protocols.
Layer 4 기반 타임아웃 설정값으로 기본 값은 600초입니다. 이 값이 너무 길기 때문에 조정하는 것이 좋습니다.
ex) 120 또는 300
nf_conntrack_tcp_timeout_established 란?
[ 커널 문서 참조 ] nf_conntrack_tcp_timeout_established - INTEGER (seconds) default 432000 (5 days)
활성화 된 연결에 대한 타임아웃 파라미터로 기본 값은 432000초(5일)입니다. 이 값 또한 조정하는 것이 좋습니다.
ex) 54000(15시간)
nf_conntrack 관련 정보 확인하기
nf_conntrack module 확인하기
[sudo lsmod | grep nf_conntrack]
nf_conntrack 최대값 확인하기
[sudo cat /proc/sys/net/nf_conntrack_max]
nf_conntrack 현재 접속 카운트하기
[sudo cat /proc/sys/net/netfilter/nf_conntrack_count]
nf_conntrack 기록 내용 확인하기
[sudo cat /proc/net/nf_conntrack]
nf_conntrack 추천 설정하기
nf_conntrack_max = (메모리용량(GB) * 1073741824) / 16384 / (64/32)
nf_conntrack_buckets = 메모리 4GB 미만이거나 초과 시 (nf_conntrack_max /4 설정)
메모리 4GB 일 때 (65536 설정)
마무리
iptalbes의 nf_conntrack 에러를 확인하고 해결방법을 알아보았습니다.
참고 자료
https://www.kernel.org/doc/Documentation/networking/nf_conntrack-sysctl.txt
COMMENTS