Trouble Shooting

DB Connection Error (ECONNRESET) 문제 해결

Somaz 2025. 8. 6. 09:41
728x90
반응형

Overview

Kubernetes 환경에서 MySQL 또는 RDS 같은 데이터베이스와의 연결이 불안정할 때 "ECONNRESET" 오류가 발생하는 경우가 있다.

 

특히 IPVS 환경을 사용할 때, 대량의 동시 연결 또는 네트워크 세션이 누적되면 DB 연결이 비정상적으로 종료되는 현상이 자주 발생한다.

 

이 글에서는 conntrack, IPVS, 그리고 TCP keepalive 관련 설정을 조정하여 DB 연결 해제 문제를 해결한 사례를 공유한다.

 

 

 

 

 

 

 

 


 

 

문제 상황

  • 서비스에서 MySQL로 쿼리를 날릴 때 read ECONNRESET 오류가 빈번하게 발생함
  • OpenSearch 또는 Loki 로그를 통해 에러를 확인해보면 대부분 소켓 단에서 연결이 갑자기 끊기는 패턴을 보임
  • Kubernetes는 kube-proxy가 IPVS 모드로 설정되어 있음
  • conntrack 설정 확인 결과 max 커넥션 수가 기본값으로 되어 있었음
 
 
 

원인 분석

 

1. Conntrack 용량 초과

  • IPVS는 커널의 conntrack 기능을 사용하여 세션 상태를 관리함
  • conntrack 테이블이 가득 차면 새로운 연결을 추적할 수 없음
  • 이로 인해 DB 연결 요청이 끊어지거나 드롭됨
sudo dmesg | grep -i conntrack
# [ 123.456789] nf_conntrack: table full, dropping packet.
 
 

2. IPVS Timeout 과 Conntrack Timeout 불일치

  • IPVS가 연결을 유지하는 시간보다 conntrack이 연결을 더 빨리 끊는 경우 발생

 

 

3. TCP Keepalive 설정 미흡

  • 노드 간의 장시간 연결 유지가 필요한 상황에서 TCP 연결이 너무 빨리 종료됨
 

 

 
 
 

해결 방법

 

1. Conntrack 설정 증가

sudo sysctl -w net.netfilter.nf_conntrack_max=131072
sudo sysctl -w net.netfilter.nf_conntrack_buckets=32768
  • `nf_conntrack_max`: 동시에 추적 가능한 연결 수
  • `nf_conntrack_buckets`: 해시 테이블 bucket 수 (max의 1/4 권장)

 

 
 

2. IPVS Timeout 증가

sudo ipvsadm --set 7200 120 300
sudo ipvsadm -Ln --timeout
# Timeout (tcp tcpfin udp): 7200 120 300
  • 7200s: TCP 연결 유지
  • 120s: FIN-WAIT 타임아웃
  • 300s: UDP 타임아웃
 
 

3. TCP Keepalive 조정

sudo sysctl -w net.ipv4.tcp_keepalive_time=7200
sudo sysctl -w net.ipv4.tcp_keepalive_intvl=75
sudo sysctl -w net.ipv4.tcp_keepalive_probes=5
  • 장시간 유휴 연결을 유지하여 조기 종료 방지

 

 

 

4. Conntrack Timeout 세부 조정

sudo sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=7200
sudo sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=120
sudo sysctl -w net.netfilter.nf_conntrack_udp_timeout=300
sudo sysctl -w net.netfilter.nf_conntrack_udp_timeout_stream=300
  • IPVS와 conntrack 간 timeout 정렬이 중요함

 

 

 

 

5. 지속 적용 (/etc/sysctl.d/99-custom.conf)

et.netfilter.nf_conntrack_max=131072
net.netfilter.nf_conntrack_buckets=32768

net.ipv4.tcp_keepalive_time=7200
net.ipv4.tcp_keepalive_intvl=75
net.ipv4.tcp_keepalive_probes=5

net.netfilter.nf_conntrack_tcp_timeout_established=7200
net.netfilter.nf_conntrack_tcp_timeout_time_wait=120
net.netfilter.nf_conntrack_udp_timeout=300
net.netfilter.nf_conntrack_udp_timeout_stream=300

 

 

 

 

 

 


 

 

 

 

 

마무리

DB 연결이 자주 끊기거나 ECONNRESET 오류가 발생할 때, 이를 단순한 어플리케이션 버그로 오해할 수 있다.


하지만 IPVS와 conntrack, TCP 커널 설정을 점검하면 이러한 문제의 원인을 인프라 네트워크 계층에서 해결할 수 있다.

 

이번 사례처럼 `conntrack_max, ipvsadm --set, keepalive` 설정 등을 조정하면 수천~수만 개의 동시 연결 상황에서도 DB 연결 안정성을 유지할 수 있다.

 

고가용성 환경을 목표로 한다면, Prometheus+Grafana 기반의 conntrack 지표 모니터링과 자동 경고 시스템도 구축하길 권장한다.

 

 

 

 

 

 

 

 


Reference

https://access.redhat.com/solutions/11334

https://github.com/sidorares/node-mysql2/issues/1243

728x90
반응형