물리 서버 DNS 장애를 애플리케이션부터 추적하는 방법

물리 서버 DNS 장애를 애플리케이션부터 추적하는 방법

물리 서버 DNS 장애를 애플리케이션부터 추적하는 방법

애플리케이션 프로세스에서 도메인 이름 해석 실패가 보고되지만 IP 주소로는 정상적으로 접속된다면, DNS 서버부터 바꾸는 것은 장애 당시의 상태를 가릴 수 있습니다. 원인은 애플리케이션 캐시, NSS 조회 순서, 시스템 이름 해석 서비스에 있을 수도 있고, 상위 DNS가 반환한 오류일 수도 있습니다. 진단의 목표는 특정 명령이 간헐적으로 성공하게 만드는 것이 아니라, 실제 애플리케이션 프로세스가 어떤 이름 해석 경로를 거치는지, 어느 계층에서 오류가 발생하는지 확인하는 것입니다.

이 글의 작업 환경은 Ubuntu Server 24.04 LTS입니다. AMDSSH 물리 서버는 결제 후 콘솔에서 접속 정보를 확인하고 SSH로 로그인합니다. 서버에 주소가 여러 개 있다면 첫 번째 주소로 접속합니다. 아래 점검은 네트워크 인터페이스 주소, 라우팅, 방화벽을 변경하지 않으므로 원인을 추적할 근거를 먼저 확보하는 데 적합합니다.

1. 조회 대상을 고정하고 원래 오류 기록하기

먼저 애플리케이션 오류 메시지, 조회한 이름, 레코드 유형, 발생 시각을 저장합니다. 모든 도메인에서 실패하는지 특정 이름에서만 실패하는지, 호스트의 프로세스에서 발생하는지 컨테이너 안의 프로세스에서 발생하는지도 구분해야 합니다. 짧은 이름은 검색 도메인의 영향을 받으므로, 진단할 때는 끝에 점이 붙은 정규화된 전체 도메인 이름을 우선 사용합니다.

아래에서는 조회 형식을 보여 주기 위해 amdssh.com.을 사용하며, 특정 주소가 반환되어야 한다고 가정하지 않습니다. 실제 검증에서는 애플리케이션에 필요하고 해당 유형의 레코드가 존재하는 것으로 확인된 이름으로 바꿔야 합니다. 먼저 도구가 있는지 확인한 뒤 기본 환경 정보를 저장합니다.

command -v getent resolvectl dig
date -Is
readlink -f /etc/resolv.conf
cat /etc/resolv.conf
grep '^hosts:' /etc/nsswitch.conf
systemctl is-active systemd-resolved
resolvectl status

dig는 dnsutils 패키지에 포함되어 있습니다. 설치되어 있지 않다면 이미 설정된 패키지 저장소를 통해 도구를 준비합니다. 이름 해석에 이미 장애가 발생한 상태라면, 패키지 설치 실패를 새로운 근본 원인의 증거로 삼아서는 안 됩니다.

IP 주소로 통신할 수 있다고 해서 DNS 조회 경로도 정상인 것은 아닙니다. DNS 응답을 받았다고 해서 애플리케이션이 필요한 레코드를 얻었다고 볼 수도 없습니다. 응답 상태, 레코드 유형, 실제 반환 내용을 함께 확인해야 합니다.

2. NSS와 시스템 이름 해석 서비스 비교하기

세 가지 조회 방식은 서로 다릅니다

getent는 NSS를 통해 조회하므로 일반적인 시스템 주소 해석 호출에 더 가깝습니다. resolvectl은 systemd-resolved에 질의합니다. dig는 DNS 질의를 수행하지만 전체 NSS 경로를 검증하지는 못합니다.

getent ahostsv4 amdssh.com.
resolvectl query --type=A amdssh.com.
dig amdssh.com. A +time=2 +tries=1

세 결과를 함께 비교해야 합니다. getent는 이전 주소를 반환하고 DNS 질의는 새 주소를 반환한다면, 먼저 /etc/hosts와 hosts: 행의 모듈 순서를 확인합니다. resolvectl은 성공하지만 getent가 실패한다면, NSS 모듈이 존재하는지, 순서가 적절한지, 서비스가 다른 파일 시스템 환경에서 실행되는지 확인해야 합니다.

/etc/resolv.conf는 로컬 이름 해석 진입점을 가리킬 수 있으며, 최종 상위 DNS 서버를 직접 나열하지 않을 수도 있습니다. 네트워크 관리 도구가 생성하는 파일일 수도 있습니다. 로컬 주소가 보인다는 이유만으로 설정이 잘못되었다고 판단하거나, 심볼릭 링크를 덮어쓴 뒤 장애가 사라졌는지 확인해서는 안 됩니다.

일부 애플리케이션은 자체 DNS 라이브러리를 사용하며 NSS를 거치지 않습니다. 따라서 getent의 성공은 시스템 이름 해석 경로가 정상이라는 근거일 뿐, 모든 애플리케이션이 복구되었다는 증거는 아닙니다.

3. 상위 DNS를 지정해 응답 오류와 전송 장애 구분하기

resolvectl status에서 실패한 조회에 사용되는 인터페이스의 DNS 서버, 라우팅 도메인, 현재 사용 중인 서버를 기록합니다. 인터페이스가 여러 개인 서버는 도메인 이름에 따라 서로 다른 상위 DNS를 선택할 수 있으므로, 출력의 첫 번째 항목만 가져와서는 안 됩니다. 아래에서는 실제로 사용하는 상위 DNS 주소를 대화형으로 입력하며, 확인되지 않은 공용 DNS 서버를 추가하지 않습니다.

read -r -p 'DNS server address: ' DNS_SERVER
dig @"$DNS_SERVER" amdssh.com. A +time=2 +tries=1
dig @"$DNS_SERVER" amdssh.com. A +tcp +time=2 +tries=1
dig @"$DNS_SERVER" amdssh.com. AAAA +time=2 +tries=1

여기서 제한 시간 2초와 시도 횟수 1회는 진단용 매개변수이며, 실제 애플리케이션의 타임아웃 설정 권장값이 아닙니다. 전체 출력을 보관하고 status, 응답 섹션, 조회 소요 시간, 실제 응답 서버를 중점적으로 확인합니다. 명령의 종료 코드만으로 애플리케이션에 필요한 레코드가 유효한지 판단해서는 안 됩니다.

응답 상태에 따라 대응하기

NXDOMAIN은 이름이 존재하지 않는다는 뜻입니다. 먼저 철자, 검색 도메인, 권한 DNS의 레코드를 확인합니다. NOERROR이지만 응답 섹션이 비어 있다면 해당 유형의 레코드만 없는 것일 수 있으므로, 네트워크 장애로 간주해서는 안 됩니다. SERVFAIL은 이름 해석 과정이 실패했다는 뜻이므로 상위 DNS 로그를 확인하거나 관리 주체와 함께 점검해야 합니다. REFUSED라면 질의 권한을 확인합니다.

UDP 질의는 시간 초과되지만 TCP 질의는 성공한다면 두 전송 경로의 동작이 다르다는 단서가 됩니다. 관련 네트워크 정책을 이어서 확인할 수 있습니다. 둘 다 시간 초과된다면 해당 상위 DNS까지의 라우팅과 접근 정책을 확인해야 하지만, 시간 초과만으로 서버가 다운되었다고 판단해서는 안 됩니다. 상위 DNS는 응답하지만 시스템 이름 해석 경로가 실패한다면, 다시 로컬 설정과 캐시를 점검해 원인을 좁혀 나갑니다.

4. 근거에 따라 복구하고 설정 관리 주체의 구성을 덮어쓰지 않기

먼저 어느 계층에서 DNS 설정을 관리하는지 확인합니다. Ubuntu Server는 Netplan을 통해 특정 네트워크 백엔드에 설정을 전달할 수도 있고, 다른 관리 방식을 사용할 수도 있습니다. 영구 설정은 실제 관리 주체의 설정 파일에서 변경해야 하며, 생성된 /etc/resolv.conf만 수정해서는 안 됩니다.

권한 DNS의 레코드가 이미 수정되었는데 systemd-resolved가 이전 결과를 보관하고 있는 것으로 확인되었다면, 장애 당시 상태를 기록한 뒤 캐시를 비울 수 있습니다.

resolvectl statistics
sudo resolvectl flush-caches
resolvectl query --type=A amdssh.com.
getent ahostsv4 amdssh.com.

캐시를 비워도 상위 DNS는 바뀌지 않으며, 애플리케이션 자체 캐시도 삭제되지 않습니다. 이전에 이름이 존재하지 않는다는 응답을 받았다면 부정 캐시의 영향을 받을 수도 있습니다. 응답의 SOA 정보를 함께 살펴 판단해야 하며, 서비스를 반복해서 재시작하는 것을 복구 방법으로 삼아서는 안 됩니다.

NSS 순서를 변경하기 전에는 원본 파일을 보관하고, 각 모듈이 로컬 파일, DNS, 그 밖의 이름 정보 출처 중 무엇을 담당하는지 명확히 파악해야 합니다. 조건부 동작이 지정된 모듈은 조회를 조기에 끝낼 수 있으므로, dns라는 문자열이 있는지만 확인해서는 안 됩니다.

영구 DNS 설정을 반드시 변경해야 한다면 먼저 기존 설정을 보관하고 문법을 검사한 뒤, 원본 파일로 복원하는 절차를 준비합니다. 원격으로 네트워크 변경을 적용하기 전에는 기존 SSH 세션을 유지하고, 설정 관리 도구가 제공하는 되돌릴 수 있는 적용 방식을 우선 사용합니다. DNS, 라우팅, 네트워크 인터페이스 이름을 동시에 변경해서는 안 됩니다.

5. 실제 애플리케이션 실행 환경에서 복구 검증하기

호스트가 복구된 뒤에도 컨테이너나 격리된 서비스에서 보이는 이름 해석 설정 파일을 확인해야 합니다. 컨테이너에는 별도의 /etc/resolv.conf가 있을 수 있고, 프로세스가 이전 주소를 캐시에 보관하고 있을 수도 있습니다. 호스트 터미널에서 같은 명령을 실행하는 데 그치지 말고, 실제 실행 환경에 들어가 조회를 반복해야 합니다.

최종 검증에는 다음 항목이 포함됩니다.

특정 프로세스에서만 문제가 발생한다면 서버 전체의 네트워크 설정 변경으로 범위를 넓히지 말고, 해당 프로세스의 리졸버, 실행 환경, 연결 풀을 계속 점검합니다. 완결된 진단이라면 원래 오류를 설명하고, 장애가 발생한 계층을 특정하며, 복구 후 애플리케이션 요청이 의도한 이름 해석 경로를 거쳤다는 사실을 입증할 수 있어야 합니다.

자주 묻는 질문

dig는 성공하는데 애플리케이션에서 이름 해석이 실패하는 이유는 무엇인가요?

dig는 DNS를 직접 조회하므로 전체 NSS 경로를 검사하지 않습니다. hosts 파일, 컨테이너 설정, 애플리케이션 캐시가 서로 다를 수 있습니다. getent 결과와 비교하고 문제가 발생한 프로세스 환경에서도 확인해야 합니다.

시스템 DNS 캐시를 비우면 모든 해석 장애가 해결되나요?

아닙니다. resolvectl flush-caches는 systemd-resolved 캐시만 비웁니다. 상위 DNS의 잘못된 응답이나 애플리케이션 자체 캐시는 그대로 남습니다. 먼저 응답 상태와 사용 중인 DNS 서버를 기록해야 합니다.

EPYC 7543P 단독 물리 서버월 $450.2부터

리소스 계획부터 서버 구성까지

서버 모델과 추가 옵션은 월 단위로 합산되며, 구성 페이지에서 전체 내역을 확인할 수 있습니다. 연결 정보는 서버 인도 후 콘솔에서 확인할 수 있습니다.