DNS Lookup Timeout 발생 요인
DNS Lookup Timeout은 애플리케이션이 특정 도메인(ex. api.service.com)에 연결하려고 할 때,
시스템은 이 이름을 ip주소로 바꾸는 과정(DNS Resolution)을 거친다. 이때 설정된 제한시간 timeout 내에 응답을 받지 못하면
발생하는 장애가 있는데 이게 바로 DNS Lookup Timeout 이다.
- 간헐적에러: 평소엔 잘 되다가 갑자기
UnknownHostExceptionorTemporary failure iname resolution에러가 뜸 - 응답 지연 latency: 타임아웃 설정이 5초라면 실제 api 호출은 0.1초만에 끝내야 하는데, dns 때문에 5초를 꽉 채우고 실패하게 된다.
- 연쇄 장애 (Cascading Failure): DNS 요청이 밀리면서 애플리케이션 워커 스레드가 모두 점유되어 서비스 전체가 먹통이 된다.
위의 현상들이 발생해서 조심해야할 에러 유형이다.
그럼 왜 발생할까? 주요 원인들을 알아보면 아래를 예를들 수 있는데
- UDP 패킷 유실: dns는 기본적으로 udp를 쓴다. udp는 보냈으니 알아서 해 방식으로 네트워크가 혼잡하면 패킷이 버려져도 재전송을 즉시 안한다
- ndots 설정문제 (k8s 환경):
/etc/resolv.conf의ndots:5설정때문에 google.com 하나를 찾는데 google.com.default.svc.cluster.local 부터 5번 헛발질하며 탐색하는 경우 (이건 별도로 k8s에서 값을 줄여주거나 개발자측에서 양해를 구해 마지막에.을 붙여 FDQN을 명시해준다거나 해결해야됨.) - Conntrack Table Full: 리눅스 서버의 연결 추적 테이블 conntrack이 꽉 차면 DNS 응답 패킷이 무시될 수 있음
- Rate Limiting: AWS, GCP 같은 클라우드 환경에서는 인스턴스당 초당 DNS 쿼리 제한(예: 1024PPS)이 있다. 이를 넘으면 가챠없이 드랍됨.
이를 해결하게 된다면 시스템 안정성 api 실패율 감소, 비용절감(재시도 비용 없어짐), 사용자 경험 개선등을 확보할 수 있으니 중요하다.
DNS 타임아웃 재현 및 확인 #
터미널에서 직접 확인을 해보겠다. 일단 서버의 DNS 설정상태를 보자
cat /etc/resolv.conf
nameserver 8.8.8.8
options timeout:2 attempts:3 ndots:5
timeout 2는 2초 기다린다는 뜻이며 attempts는 3번 시도한다는 뜻으로 총 6초가 걸릴것이다 2 x 3
dig 명령어를 통해서 응답속도를 체크할 수 있다.
# 특정 dns 서버 8.8.8.8을 지정해서 google.com을 찾음
dig @8.8.8.8 google.com
; <<>> DiG 9.16.1-Ubuntu <<>> google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45678 # <--- status: NOERROR가 중요!
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;google.com. IN A
;; ANSWER SECTION:
google.com. 237 IN A 142.250.207.46 # <--- 우리가 원하던 IP 주소
;; Query time: 15 msec # <--- 1. 응답 속도 (아주 빠름)
;; SERVER: 8.8.8.8#53(8.8.8.8) # <--- 2. 누구한테 물어봤는지
;; WHEN: Thu Feb 19 18:50:00 KST 2026
;; MSG SIZE rcvd: 55
가짜로 ip dns서버를 지정해 강제로 타임아웃을 내보겠다.
dig @1.2.3.4 google.com +timeout=2
;; [네트워크 연결 지연 중...]
;; connection timed out; no servers could be reached # <--- 이게 네 에러 로그에 찍힐 내용이야.
패킷의 흐름도 한번 쫒아보자 tcpdump를 통해서 패킷이 나갔는지, 응답이 안왓는지를 실시간으로 볼 수 있다.
# -n: 호스트네임 변환 안 함, -vv: 상세 정보, -i any: 모든 인터페이스
sudo tcpdump -i any port 53 -n -vv
# 정상
18:55:01.123 IP 192.168.1.10.54321 > 8.8.8.8.53: [1234] A? google.com. (28)
18:55:01.138 IP 8.8.8.8.53 > 192.168.1.10.54321: [1234] 1/0/0 A 142.250.207.46 (44)
# 타임아웃 발생
18:56:00.000 IP 192.168.1.10.54321 > 8.8.8.8.53: [5678] A? google.com. (28)
18:56:05.000 IP 192.168.1.10.54321 > 8.8.8.8.53: [5678] A? google.com. (28) # <--- 재시도!
18:56:10.000 IP 192.168.1.10.54321 > 8.8.8.8.53: [5678] A? google.com. (28) # <--- 또 재시도...
k8s를 관리하고 있다면 ndots 트랩을 조심해야한다. 리눅스 서버의 /etc/resolv.conf 설정때문에 DNS가 느려지는 예시다.
cat /etc/resolv.conf
nameserver 10.96.0.10
search my-namespace.svc.cluster.local svc.cluster.local cluster.local
options ndots:5 # <--- 이 녀석이 범인!
이 설정때문에 google.com을 시스템이 호출하면 시스템은 점이 5개 미만인 모든 도메인을 내부 도메인으로 착각하고 아래 순서대로 물어본다.
- google.com.my-namespace.svc.cluster.local (응답 없음/Error)
- google.com.svc.cluster.local (응답 없음/Error)
- google.com.cluster.local (응답 없음/Error)
- google.com (드디어 성공!)
결론 #
결과적으로 ndots 최적화, Timeout 값 조정을 해볼 수 있고(요청이 밀리는게 문제면 더 빨리 실패하도록 둔다거나)
Local DNS Caching 등으로 nscd나 NodeLocal DNSCache가 깔려있는지도 확인해 해결해볼 수 있다.
혹은 FQDN을 사용해 외부 도메인 호출시 끝에 점을 찍어 google.com. ndots탐색을 건너뛰도록 코드를 수정할 수도 있다.
options single-request-reopen을 추가하여 IPv4/IPv6 동시 요청 시 발생하는 커널 레이스 컨디션을 방지도 가능하다.