infra
Platform

모듈 맵

[Network] DNS 질의 실패 극복 및 resolv.conf 수동 복구 가이드

0 / 35 완료

펼치기
0 / 35 완료0%

네트워크 트러블슈팅 · 07 / 35

[Network] DNS 질의 실패 극복 및 resolv.conf 수동 복구 가이드

IP ping은 되는데 도메인 ping이 안 될 때 resolv.conf를 즉시 수정합니다

🚨INCIDENT ALERT
HIGH

서버에서 ping 8.8.8.8은 되는데 ping google.com은 실패합니다. 네트워크는 살아 있는데 배포 스크립트는 저장소 도메인을 찾지 못해 중단됩니다.

이 상황에서 봐야 할 곳은 애플리케이션 로그가 아니라 이름 해석 경로입니다. /etc/resolv.conf와 resolver 설정을 확인해야 합니다.

DNS 질의 실패와 /etc/resolv.conf 설정

인프라 운영 중 가장 황당한 순간 중 하나가 있습니다. ping 8.8.8.8은 잘 되는데 ping google.com은 안 되는 상황입니다. 네트워크는 분명 살아있는데 도메인으로는 아무것도 안 됩니다. 이 문제의 원인은 거의 항상 /etc/resolv.conf 하나입니다. 이 챕터에서는 DNS 클라이언트 설정 파일인 resolv.conf를 완전히 이해하고, 빠르게 수정하는 방법을 배웁니다.


resolv.conf 구조 이해

이번 챕터에서 배울 것
  • 1/etc/resolv.conf 파일 구조와 nameserver, search, domain, options 지시어를 이해할 수 있다
  • 2IP ping은 되는데 도메인 ping이 안 될 때 DNS 문제를 진단할 수 있다
  • 3NetworkManager와 systemd-resolved가 resolv.conf를 덮어쓰는 원인을 설명할 수 있다
  • 4nmcli / systemd-resolved / Netplan으로 DNS를 영구 설정할 수 있다
  • 5재부팅 후 resolv.conf가 초기화되는 문제를 해결할 수 있다
  • 6Docker·Kubernetes 환경에서 컨테이너 DNS 실패 원인을 파악하고 대처할 수 있다
실습 환경 준비
현재 DNS 설정 확인
cat /etc/resolv.conf
resolv.conf 관리 주체 확인 (심볼릭 링크 여부)
ls -la /etc/resolv.conf
DNS 해석 즉시 테스트
nslookup google.com
systemd-resolved 사용 여부 확인
systemctl is-active systemd-resolved
💡개념

/etc/resolv.conf — DNS 클라이언트 설정 파일 해부

서버에서 curl api.internal이 안 됩니다. ping api.internal도 "Name or service not known"입니다. 외부 IP로는 되는데 내부 도메인만 안 됩니다. 이런 상황에서 /etc/resolv.conf를 보면 내부 DNS 서버 주소가 없거나 잘못된 서버를 바라보고 있습니다. DNS 클라이언트 설정 파일의 구조를 모르면 어디를 어떻게 고쳐야 하는지 알 수 없습니다.

/etc/resolv.conf — DNS 클라이언트 설정 파일 완전 해부. nameserver(DNS 질의를 보낼 서버 IP, 최대 3개까지 순서대로 시도)·search(도메인 자동 완성 접미사)·options(ndots 점 개수 임계값, timeout 응답 대기 초, attempts 재시도 횟수, rotate) 지시자로 구성된다. DNS 질의 흐름은 애플리케이션(curl·ping)→glibc getaddrinfo()→/etc/resolv.conf 설정 읽기→nameserver 8.8.8.8→응답 IP 반환 순. 트러블슈팅은 cat /etc/resolv.conf(현재 설정)·dig google.com @8.8.8.8(특정 서버 직접 질의)·nslookup·resolvectl status·systemd-resolve --status로 확인한다확대

resolv.conf란

/etc/resolv.conf는 리눅스/유닉스 시스템에서 DNS 해석(Resolver) 동작을 설정하는 파일입니다. 프로그램이 google.com 같은 도메인 이름을 IP로 변환할 때 이 파일을 참조합니다.

resolv.conf가 사용되는 시점:
curl google.com
    → curl이 OS에 "google.com의 IP 알려줘" 요청
    → OS 리졸버가 /etc/resolv.conf 읽음
    → nameserver로 지정된 DNS 서버에 질의
    → IP 응답 받아서 curl에 전달
    → curl이 해당 IP로 HTTP 요청

resolv.conf 파일 구조

실제 파일 내용을 보면 지시어 구조를 바로 파악할 수 있습니다.

로컬 터미널
# 실습 디렉토리 준비
mkdir -p /tmp/networking/part2/exam_7 && cd /tmp/networking/part2/exam_7

cat /etc/resolv.conf
🔍실행 후 확인할 것
  • nameserver현재 서버가 어떤 DNS 서버에 질의하는지 확인합니다
  • 심볼릭 링크/etc/resolv.conf가 systemd-resolved 또는 NetworkManager에 의해 관리되는지 봅니다
  • IP vs 도메인IP 통신 성공과 DNS 실패를 분리해 원인을 좁힙니다

전형적인 내용:

# DNS 서버 IP (최대 3개, 위에서 아래 순서로 시도)
nameserver 8.8.8.8
nameserver 8.8.4.4
nameserver 1.1.1.1

# 검색 도메인 (짧은 호스트명 자동 보완)
search example.com internal.company.com

# 현재 도메인 (일반적으로 search와 유사한 역할)
domain example.com

# 추가 옵션
options ndots:5 timeout:2 attempts:3

각 지시어 상세 설명

nameserver

DNS 질의를 보낼 서버 IP를 지정합니다. 최대 3개까지 설정하며 위에서 아래 순서로 시도합니다.

nameserver 8.8.8.8

역할: DNS 질의를 보낼 서버 IP 지정
규칙:
- 최대 3개까지 설정 가능
- 첫 번째 서버가 응답 없을 때 두 번째 시도
- IPv4 또는 IPv6 주소 사용 가능

search

짧은 호스트명 입력 시 자동으로 도메인을 붙여 완전한 FQDN으로 만드는 검색 도메인을 지정합니다.

search example.com internal.company.com

역할: 짧은 호스트명 → FQDN 자동 변환
예시:
  ping web01
  → web01.example.com 시도
  → web01.internal.company.com 시도

실무 활용:
  쿠버네티스: search default.svc.cluster.local svc.cluster.local cluster.local
  → ping my-service 입력 시 my-service.default.svc.cluster.local로 질의

domain

시스템의 기본 도메인을 설정합니다. search와 함께 선언되면 마지막에 선언된 것이 적용됩니다.

domain example.com

역할: 시스템의 기본 도메인 설정
search와의 차이: search는 여러 도메인 지정 가능, domain은 하나만
참고: search와 domain이 둘 다 있으면 마지막에 선언된 것이 적용

options ndots

도메인 이름의 점(.) 개수가 ndots 값보다 작으면 search 도메인을 먼저 시도합니다. 쿠버네티스 환경에서는 기본값 5를 자주 만납니다.

options ndots:5

역할: 도메인 이름에 점(.)이 몇 개 미만이면 search 도메인 먼저 시도
기본값: 1
쿠버네티스 기본값: 5

예시 (ndots:2 설정 시):
  nslookup google.com  → 점이 1개, ndots:2보다 작음
  → google.com.example.com 먼저 시도 (search 도메인 붙임)
  → 실패하면 google.com 시도

/etc/nsswitch.conf와의 관계

resolv.conf는 DNS 질의 자체를 설정하지만, OS가 이름 해석에 어떤 방법을 어떤 순서로 사용할지는 /etc/nsswitch.conf가 결정합니다.

로컬 터미널
grep hosts /etc/nsswitch.conf
# hosts: files dns myhostname

이 한 줄이 이름 해석 순서를 정합니다.

  • files/etc/hosts를 먼저 확인
  • dns — 그다음 /etc/resolv.conf의 nameserver로 DNS 질의
  • myhostname — 마지막으로 자기 호스트명 해석

/etc/hosts에 항목이 있으면 DNS보다 먼저 사용됩니다.

💡개념

이름 하나를 조회할 때 resolv.conf가 개입하는 순서 — nsswitch부터 응답까지

nameserver 한 줄만 맞으면 될 것 같지만, 실제 한 번의 이름 조회는 nsswitch 순서 판정 → /etc/hosts 확인 → resolv.confnameserver·search·options 적용이라는 여러 단계를 거칩니다. 이 순서를 알면 "IP는 되는데 도메인만 안 되는" 경우가 어느 단계에서 끊긴 것인지, "가끔 정확히 5초 지연"이 어디서 새는지를 짚을 수 있습니다.

TEXT
[앱]  getaddrinfo("web01") — 이름 하나 조회
   │
   ① nsswitch.conf의 hosts 행이 순서 결정
   │    hosts: files dns → /etc/hosts 먼저, 없으면 DNS
   │
   ② /etc/hosts 조회 (files)
   │    매칭 있으면 즉시 반환 (DNS로 안 감)
   │
   ③ resolv.conf 로드 — nameserver·search·options 읽기
   │
   ④ ndots 판정 (options ndots:N)
   │    이름의 점(.) 개수 < N → search 도메인부터 붙여 시도
   │
   ⑤ search 도메인 하나씩 붙여 nameserver에 질의
   │    web01.example.com → ... → 마지막에 절대 이름
   │    첫 nameserver 무응답이면 timeout 후 다음 nameserver로
   │
   ⑥ 응답(A/AAAA) 수신 → IP 반환
   ▼
[앱]  받은 IP로 실제 연결

각 단계에서 무슨 일이 일어나고, 막히면 어떤 증상인가:

단계하는 일여기서 막히면
① nsswitch 순서hosts: 행이 files(hosts 파일)·dns의 사용 순서를 정함dns가 빠져 있으면 resolv.conf가 멀쩡해도 DNS 질의 자체를 안 함
② /etc/hostsfiles 단계에서 로컬 고정 매핑을 먼저 조회잘못된 고정 항목 → DNS를 보기 전에 엉뚱한 IP로 감 (nslookup은 정상인데 앱만 이상)
③ resolv.conf 로드nameserver·search·options를 읽어 이후 질의 방식을 결정nameserver 비었음·틀림 → Name or service not known / SERVFAIL
④ ndots 판정이름의 점 개수가 ndots보다 작으면 search부터 붙임쿠버네티스 기본 ndots:5 → 외부 도메인도 search 확장 폭증 → 조회 수·지연이 몇 배
⑤ nameserver 순차 시도search 후보를 위 nameserver부터 순서대로 질의, 무응답이면 timeout 후 다음 서버1순위 nameserver 죽음 → options timeout(기본 5초)만큼 멈췄다 폴백 → "가끔 정확히 5초"
⑥ 응답 반환받은 A/AAAA 레코드의 IP를 앱에 돌려줌응답 유실(병렬 A/AAAA 경쟁 등) → timeout 후 재시도로 지연

resolv.conf는 단순히 'DNS 서버 IP를 적는 곳'이 아니라 한 번의 조회가 몇 번의 질의로 불어나고 어디서 지연되는지를 결정하는 지점 입니다. 그래서 IP는 되는데 도메인만 안 되면 ③(nameserver)을, 사내 도메인만 실패하면 ⑤의 search·nameserver 우선순위를, 외부 도메인이 유독 느리면 ④(ndots 확장)를, 가끔 정확히 5초 걸리면 ⑤의 timeout 폴백을 의심합니다. cat /etc/resolv.conf로 이 네 필드(nameserver·search·options·ndots)를 먼저 읽는 것이 DNS 진단의 출발점입니다.

💡개념

NetworkManager와 resolv.conf — 덮어쓰기 문제의 원인

/etc/resolv.conf를 직접 수정해서 DNS 서버를 바꿨습니다. 그런데 다음 날 아침에 보면 원래대로 돌아가 있습니다. 다시 수정하면 또 바뀝니다. NetworkManager나 systemd-resolved가 자동으로 덮어쓰기 때문인데, 이 구조를 모르면 같은 작업을 계속 반복하게 됩니다.

NetworkManager가 resolv.conf를 덮어쓰는 원인과 해결. 문제 시나리오: vi로 /etc/resolv.conf에 nameserver 8.8.8.8을 직접 적어도 서비스 재시작·재부팅 후 nameserver 192.168.1.1처럼 원치 않는 값으로 다시 바뀐다. 원인은 NetworkManager가 DHCP 정보로 resolv.conf를 자동 생성하고 systemd-resolved가 심볼릭 링크로 관리하기 때문(수동 수정은 재부팅 시 사라짐). 해결 방법 3가지: ① nmcli con mod로 DNS를 영구 설정하고 ipv4.ignore-auto-dns yes, ② /etc/NetworkManager/NetworkManager.conf에 dns=none 설정 후 직접 관리, ③ systemd-resolved 활성화 후 /etc/systemd/resolved.conf에 DNS 지정확대

문제의 핵심

현대 리눅스(Ubuntu 18.04+, RHEL 7+)에서는 /etc/resolv.conf를 직접 수정해도 재부팅이나 네트워크 재연결 시 원래대로 돌아갑니다. 이는 NetworkManager 또는 systemd-resolved가 자동으로 관리하기 때문입니다.

resolv.conf 관리 주체 확인:

# resolv.conf가 심볼릭 링크인지 확인
ls -la /etc/resolv.conf

# Ubuntu 20.04+ (systemd-resolved 사용):
# /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf
# → 심볼릭 링크! 직접 수정해도 재부팅 시 덮어써짐

# 일반 파일인 경우:
# -rw-r--r-- 1 root root 89 ...
# → NetworkManager가 관리하거나, 수동 설정

resolv.conf 관리 구조

어떤 프로세스가 resolv.conf를 관리하는지에 따라 영구 설정 방법이 달라집니다.

resolv.conf 관리 구조 — systemd-resolved(심볼릭 링크→stub-resolv.conf) 시나리오와 NetworkManager 직접 관리 시나리오 비교확대

관리 주체 확인 방법

아래 순서로 확인하면 어떤 프로세스가 resolv.conf를 관리하는지 파악할 수 있습니다.

서버 터미널
# systemd-resolved 실행 중인지 확인
systemctl is-active systemd-resolved
# active → systemd-resolved 사용

# NetworkManager 실행 중인지 확인
systemctl is-active NetworkManager
# active → NetworkManager 사용

# resolv.conf 내용으로 판단
head -3 /etc/resolv.conf
# "# Generated by NetworkManager" → NetworkManager 관리
# "# This is /run/systemd/resolve/stub-resolv.conf" → systemd-resolved 관리
# 주석 없음 → 수동 관리 가능성
DNS 실패 증상별 판단 — 어디가 끊겼는가
ping <도메인> 실패 + ping <IP>는 성공이름 해석만 고장 — 네트워크는 정상. DNS 계층(resolv.conf·nameserver·systemd-resolved)부터 본다. 'IP는 되는데 도메인만 안 되면 DNS'
nslookup은 응답 + 브라우저/앱만 실패애플리케이션 캐시 또는 NSS 순서 문제. /etc/nsswitch.conf의 hosts 행, 그리고 /etc/hosts 오버라이드를 먼저 의심
해석이 2~5초씩 지연 후 성공1순위 nameserver가 응답 없음 → timeout 후 2순위로 폴백. resolv.conf의 options timeout:1 attempts:2로 줄이고, 죽은 nameserver 제거
재부팅·NetworkManager 재시작 후 설정이 사라짐resolv.conf를 직접 수정했는데 NM/systemd-resolved가 덮어씀. 심볼릭 링크 여부(ls -l /etc/resolv.conf) 확인 후 NM 연결 프로파일에 dns 영구 등록
일부 도메인만 실패 (사내 도메인 등)split-DNS/search 도메인 누락 또는 내부 DNS 서버 미지정. search 라인과 사내 nameserver 우선순위 점검
SERVFAIL / 간헐적 NXDOMAIN상위 DNS 서버 장애 또는 DNSSEC 검증 실패. dig +trace로 위임 경로 추적, 서버 측 문제면 nameserver를 안정적인 것으로 교체

실습 — DNS 문제 진단과 수정

DNS 문제 증상 확인 및 즉시 진단

가장 먼저 IP ping과 도메인 ping을 비교하여 DNS 문제임을 확인합니다.

로컬 터미널
# 1단계: 네트워크 연결 확인 (IP 주소로)
ping -c 2 8.8.8.8
# 성공하면 → L3 네트워크는 정상

# 2단계: 도메인 ping 시도
ping -c 2 google.com
# 실패 시 오류 메시지 확인:
# ping: google.com: Name or service not known  → DNS 해석 실패
# ping: google.com: Temporary failure in name resolution  → DNS 서버 응답 없음

# 3단계: resolv.conf 현재 내용 확인
cat /etc/resolv.conf
# nameserver 없거나 잘못된 IP → 원인 발견!

# 4단계: 직접 DNS 질의 테스트
nslookup google.com
# Server: 127.0.0.1  (DNS 서버)
# ** server can't find google.com: SERVFAIL  → DNS 서버 문제

nslookup google.com 8.8.8.8
# 성공 시 → DNS 서버 자체는 살아있음, resolv.conf 설정 문제

# 5단계: dig으로 상세 진단
dig google.com
dig @8.8.8.8 google.com  # 특정 DNS 서버에 직접 질의

진단 결과 해석:

nslookup google.com → 실패
nslookup google.com 8.8.8.8 → 성공
→ resolv.conf의 nameserver 설정 문제

nslookup google.com → 실패
nslookup google.com 8.8.8.8 → 실패
→ 네트워크에서 DNS 포트(53) 차단 가능성
  또는 DNS 서버 자체 문제

ping 8.8.8.8 → 실패
→ 기본 네트워크 연결 문제 (DNS와 무관)
resolv.conf 즉시 수정 — 임시 해결책

시스템이 관리하는 상황에서 resolv.conf를 직접 수정하는 임시 방법입니다.

위험 명령어

이 명령은 시스템 설정 파일을 변경합니다. 기존 파일 백업과 적용 후 검증 방법을 준비하지 않으면 재부팅이나 서비스 재시작 때 장애가 반복될 수 있습니다.

로컬 터미널
# 현재 resolv.conf 내용 확인
cat /etc/resolv.conf

# resolv.conf가 심볼릭 링크인지 확인
ls -la /etc/resolv.conf
# lrwxrwxrwx → 심볼릭 링크 (systemd-resolved 사용)
# -rw-r--r-- → 일반 파일 (직접 수정 가능)

# 방법 A: 일반 파일인 경우 — 직접 수정
sudo tee /etc/resolv.conf << 'EOF'
nameserver 8.8.8.8
nameserver 8.8.4.4
nameserver 1.1.1.1
search example.com
EOF

# 방법 B: 심볼릭 링크인 경우 — chattr로 덮어쓰기 방지 후 수정
# (임시 방편으로 권장되지 않음)
sudo rm /etc/resolv.conf
sudo tee /etc/resolv.conf << 'EOF'
nameserver 8.8.8.8
nameserver 8.8.4.4
EOF
sudo chattr +i /etc/resolv.conf  # 수정 불가 속성 설정 (임시)
# 나중에 해제: sudo chattr -i /etc/resolv.conf

# 즉시 테스트
ping -c 2 google.com
nslookup google.com

주의: 이 방법은 재부팅이나 NetworkManager 재시작 시 다시 초기화될 수 있습니다. 영구 설정은 다음 단계를 따르세요.

영구 DNS 설정 — NetworkManager와 systemd-resolved

재부팅 후에도 유지되는 영구 DNS 설정 방법입니다.

방법 1: nmcli로 NetworkManager 연결 프로파일 수정

NetworkManager가 관리하는 환경에서는 연결 프로파일에 DNS를 설정해야 재부팅 후에도 유지됩니다.

로컬 터미널
# 현재 활성 연결 이름 확인
nmcli con show --active
# NAME         UUID                                  TYPE      DEVICE
# ens3         12345678-1234-1234-1234-123456789012  ethernet  ens3

# DNS 서버 설정 (연결 이름으로)
sudo nmcli con mod "ens3" ipv4.dns "8.8.8.8 8.8.4.4"

# DHCP로 받아온 DNS 무시 설정 (선택)
sudo nmcli con mod "ens3" ipv4.ignore-auto-dns yes

# 변경 사항 적용
sudo nmcli con up "ens3"

# 확인
nmcli con show "ens3" | grep ipv4.dns
# ipv4.dns: 8.8.8.8,8.8.4.4

# resolv.conf 확인 (NetworkManager가 업데이트해야 함)
cat /etc/resolv.conf

방법 2: NetworkManager conf.d 파일로 글로벌 설정

연결별 설정 대신 모든 연결에 공통으로 적용될 DNS를 conf.d에 설정합니다.

위험 명령어

이 명령은 실행 중인 서비스 상태를 바꿔 순간적인 중단이나 설정 반영 실패를 만들 수 있습니다. 운영 트래픽 영향과 재시작 후 확인 명령을 먼저 준비하세요.

로컬 터미널
# 모든 연결에 적용되는 DNS 설정
sudo tee /etc/NetworkManager/conf.d/dns-servers.conf << 'EOF'
[global-dns-domain-*]
servers=8.8.8.8,8.8.4.4,1.1.1.1
EOF

sudo systemctl restart NetworkManager

cat /etc/resolv.conf

방법 3: systemd-resolved 설정 (Ubuntu 18.04+)

systemd-resolved가 관리하는 환경에서는 /etc/systemd/resolved.conf에 DNS를 설정합니다.

위험 명령어

이 명령은 실행 중인 서비스 상태를 바꿔 순간적인 중단이나 설정 반영 실패를 만들 수 있습니다. 운영 트래픽 영향과 재시작 후 확인 명령을 먼저 준비하세요.

로컬 터미널
# /etc/systemd/resolved.conf 편집
sudo tee /etc/systemd/resolved.conf << 'EOF'
[Resolve]
DNS=8.8.8.8 8.8.4.4
FallbackDNS=1.1.1.1 9.9.9.9
Domains=~.
DNSSEC=no
DNSOverTLS=no
Cache=yes
EOF

# systemd-resolved 재시작
sudo systemctl restart systemd-resolved

# 현재 DNS 상태 확인
resolvectl status
# Global
# DNS Servers: 8.8.8.8 8.8.4.4
# Fallback DNS Servers: 1.1.1.1 9.9.9.9

# 테스트
resolvectl query google.com

방법 4: Netplan에서 DNS 설정 (Ubuntu Server)

Ubuntu Server에서 networkd가 렌더러일 때는 Netplan YAML로 DNS를 설정하고 netplan apply로 반영합니다.

위험 명령어

이 명령은 시스템 설정 파일을 변경합니다. 기존 파일 백업과 적용 후 검증 방법을 준비하지 않으면 재부팅이나 서비스 재시작 때 장애가 반복될 수 있습니다.

로컬 터미널
# /etc/netplan/01-netcfg.yaml 편집
sudo tee /etc/netplan/01-netcfg.yaml << 'EOF'
network:
  version: 2
  renderer: networkd
  ethernets:
    ens3:
      dhcp4: true
      nameservers:
        addresses: [8.8.8.8, 8.8.4.4, 1.1.1.1]
        search: [example.com]
EOF

sudo netplan apply

# 확인
cat /etc/resolv.conf
resolvectl status

트러블슈팅

증상

수동으로 /etc/resolv.conf를 수정하고 DNS가 잘 되다가, 서버를 재부팅하면 다시 빈 파일이나 엉뚱한 내용으로 돌아옵니다.

로컬 터미널
# 수정 후 잘 됨
cat /etc/resolv.conf
# nameserver 8.8.8.8  ← 내가 설정한 내용

# 재부팅 후
cat /etc/resolv.conf
# # Generated by NetworkManager
# search .                ← 초기화됨!
# nameserver 192.168.1.1  ← DHCP 서버가 준 DNS로 덮어써짐

ping google.com
# ping: google.com: Name or service not known

원인 파악

로컬 터미널
# 1. resolv.conf 관리 주체 확인
ls -la /etc/resolv.conf

# 2. NetworkManager가 관리 중인지 확인
cat /etc/resolv.conf | head -2
# "# Generated by NetworkManager" → NetworkManager가 덮어씀

# 3. DHCP 서버가 DNS를 보내주는지 확인
sudo journalctl -u NetworkManager | grep -i dns | tail -20
# "policy: set 'ens3' (ens3) as default for IPv4 routing and DNS"
# "dhcp4: option domain_name_servers => '192.168.1.1'"  ← DHCP DNS 수신

해결 — NetworkManager에서 영구 설정

위험 명령어

이 명령은 실행 중인 서비스 상태를 바꿔 순간적인 중단이나 설정 반영 실패를 만들 수 있습니다. 운영 트래픽 영향과 재시작 후 확인 명령을 먼저 준비하세요.

로컬 터미널
# 방법 1: nmcli로 DHCP DNS 무시하고 수동 DNS 설정
CONN=$(nmcli -t -f NAME con show --active | head -1)
echo "활성 연결: $CONN"

sudo nmcli con mod "$CONN" ipv4.dns "8.8.8.8 8.8.4.4"
sudo nmcli con mod "$CONN" ipv4.ignore-auto-dns yes
sudo nmcli con up "$CONN"

# 방법 2: 연결 설정 파일 직접 수정 (RHEL/CentOS)
ls /etc/sysconfig/network-scripts/
# ifcfg-ens3 → 해당 파일 편집

sudo tee -a /etc/sysconfig/network-scripts/ifcfg-ens3 << 'EOF'
DNS1=8.8.8.8
DNS2=8.8.4.4
PEERDNS=no
EOF

sudo systemctl restart NetworkManager

검증

로컬 터미널
# 재부팅 후에도 설정 유지 확인
sudo reboot

# 재접속 후
cat /etc/resolv.conf
# nameserver 8.8.8.8
# nameserver 8.8.4.4

ping google.com
# 성공!

증상

호스트에서는 DNS가 잘 되는데, Docker 컨테이너 안에서 DNS 해석이 실패합니다.

로컬 터미널
# 호스트에서는 잘 됨
ping google.com
# 정상

# 컨테이너 안에서는 실패
docker run --rm alpine ping google.com
# ping: bad address 'google.com'

docker run --rm alpine cat /etc/resolv.conf
# nameserver 127.0.0.11  ← Docker 내부 DNS

원인

Docker는 컨테이너의 /etc/resolv.conf를 자동 생성합니다. 호스트의 /etc/resolv.confnameserver 127.0.0.53(systemd-resolved 스텁)이 있으면, Docker가 이를 컨테이너에 그대로 복사하여 컨테이너 내부에서 127.0.0.53에 접근 시 실패합니다.

로컬 터미널
# 문제 확인
cat /etc/resolv.conf
# nameserver 127.0.0.53  ← 호스트 루프백, 컨테이너에서 접근 불가!

# Docker daemon.json에서 DNS 설정 없는지 확인
cat /etc/docker/daemon.json
# {} 또는 파일 없음 → DNS 설정 없음

해결

위험 명령어

이 명령은 실행 중인 서비스 상태를 바꿔 순간적인 중단이나 설정 반영 실패를 만들 수 있습니다. 운영 트래픽 영향과 재시작 후 확인 명령을 먼저 준비하세요.

로컬 터미널
# 방법 1: Docker daemon.json에 DNS 설정
sudo tee /etc/docker/daemon.json << 'EOF'
{
    "dns": ["8.8.8.8", "8.8.4.4"],
    "dns-search": []
}
EOF

sudo systemctl restart docker

# 테스트
docker run --rm alpine ping -c 2 google.com

# 방법 2: 컨테이너 실행 시 DNS 지정
docker run --rm --dns 8.8.8.8 alpine ping -c 2 google.com

# 방법 3: systemd-resolved 링크를 실제 파일로 변경
# (호스트 resolv.conf에서 127.0.0.53 제거)
sudo resolvectl dns ens3 8.8.8.8 8.8.4.4
sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
# /run/systemd/resolve/resolv.conf는 실제 DNS IP를 포함

쿠버네티스 CoreDNS 문제:

Kubernetes
# Pod에서 DNS 실패 시 CoreDNS 상태 확인
kubectl get pods -n kube-system | grep coredns
kubectl logs -n kube-system coredns-xxxxx

# Node의 resolv.conf 확인 (CoreDNS 설정에 영향)
# 각 노드에서:
cat /etc/resolv.conf

심화 — resolver가 조용히 만드는 비용: search 확장과 병렬 A/AAAA

💡개념

심화: nameserver 한 줄 뒤에 숨은 비용 — 질의 폭증과 병렬 질의 유실

nameserver 한 줄만 맞으면 될 것 같지만, 정작 부하와 지연은 리졸버가 '한 번의 조회'를 뒤에서 여러 질의로 바꾸는 데서 나옵니다. resolv.conf의 search·options가 그 뒷면입니다.

  • search 도메인 확장과 ndots: options ndots:N은 '이름의 점(.) 개수가 N 미만이면 search 도메인을 먼저 붙여 시도하라'는 뜻입니다. 쿠버네티스 기본값 ndots:5에서는 api.example.com(점 2개)조차 search 접미사(svc.cluster.local 등 45개)를 하나씩 다 붙여 NXDOMAIN을 받은 뒤에야 절대 이름을 질의합니다. 외부 도메인 한 번 부르는데 DNS 왕복이 56배로 늘어 지연·부하가 커집니다. 이름 끝에 점을 붙여 FQDN(api.example.com.)으로 쓰거나 ndots를 낮추면 이 확장을 건너뜁니다.
  • 병렬 A/AAAA 질의: glibc 리졸버는 IPv4(A)와 IPv6(AAAA)를 같은 소켓·같은 소스 포트로 거의 동시에 보냅니다. 여기에 NAT/conntrack이 끼면 두 질의의 conntrack 항목이 5-튜플 경쟁을 일으켜 한쪽 응답이 드롭될 수 있고, 리졸버는 잃은 응답을 options timeout(기본 5초)만큼 기다렸다 재시도합니다 — '가끔 정확히 5초 지연되는 DNS'의 정체입니다.
  • 그래서 '가끔 느린 DNS'는 nameserver가 틀린 게 아니다: (a) search 확장으로 질의 수가 폭증했거나 (b) 병렬 질의 중 하나가 유실돼 timeout을 기다리는 경우입니다. options single-request(-reopen), timeout/attempts 축소, ndots 조정, FQDN 사용이 이때 쓰는 도구입니다.

즉 resolv.conf는 'DNS 서버 IP를 적는 곳'을 넘어, 조회가 몇 배로 늘어나고 어디서 5초가 새는지를 결정하는 튜닝 지점입니다.

상황: 앱이 외부·내부 호스트명을 부를 때 대개 수 ms인데, 간헐적으로 정확히 5초 걸린 뒤 성공합니다. 5초라는 딱 떨어지는 숫자가 반복되고, nameserver와 레코드는 모두 정상이라 원인을 잡기 어렵습니다.

원인: glibc 리졸버가 A와 AAAA 질의를 같은 소스 포트로 동시에 UDP로 보내는데, NAT(conntrack) 경로에서 두 질의의 conntrack 항목이 경쟁하며 한쪽 응답이 드롭됩니다. 리졸버는 잃은 응답을 resolv.conf의 options timeout(기본 5초)만큼 기다렸다 재시도해 성공하므로, 지연이 '정확히 5초'로 반복됩니다.

진단: cat /etc/resolv.confoptions timeout 값이 5인지(지연 시간과 일치) 확인하고, 앱이 A와 AAAA를 함께 조회하는지 봅니다. dig는 기본이 A만 보내 재현이 안 될 수 있으니, 실제 앱 경로로 재현합니다. 노드의 conntrack insert_failed 카운터(conntrack -S)가 증가하는지도 확인합니다.

해결: resolv.conf optionssingle-request-reopen을 추가해 A/AAAA를 별도 소켓·포트로 보내 경쟁을 없앱니다(single-request도 유사). timeout을 1로 낮추면 지연 폭 자체가 줄어듭니다. IPv6를 쓰지 않는 환경이면 불필요한 AAAA 조회를 줄이는 것도 근본 완화책입니다(DNS 동작 과정과 A, CNAME, TXT 레코드 분석의 질의 흐름과 함께 이해).


실무 맥락

💼
실무 맥락
현업 패턴

DNS 장애가 전체 서비스를 멈추는 이유

DNS는 모든 서비스가 의존하는 인프라의 기반입니다. DNS가 느리거나 실패하면 예상치 못한 방식으로 장애가 연쇄됩니다.

DNS 장애 연쇄 효과 예시:

1. resolv.conf DNS 서버 다운 또는 네트워크 단절
   ↓
2. 애플리케이션이 DB 호스트명을 IP로 변환 실패
   ↓
3. DB 연결 타임아웃 (30초 기다리다 실패)
   ↓
4. 웹 요청 처리 지연/실패
   ↓
5. 사용자에게 503 Service Unavailable

실제 사례: DNS 서버 1개만 설정 → 해당 DNS 서버 재부팅 시
           모든 서비스가 30초씩 지연 후 연결 실패

예방책: DNS 서버를 2~3개 지정하고 타임아웃을 단축하면 단일 장애점을 제거할 수 있습니다.

로컬 터미널
# resolv.conf에 DNS 서버를 항상 2~3개 설정
nameserver 10.0.0.1    # 내부 DNS (주)
nameserver 10.0.0.2    # 내부 DNS (보조)
nameserver 8.8.8.8     # 외부 DNS (최후 수단)

options timeout:1 attempts:2
# timeout: 응답 대기 시간(초), 기본 5초
# attempts: 재시도 횟수, 기본 2회
# → 내부 DNS 응답 없으면 1초 후 다음 서버 시도

빠른 DNS 진단 명령어 모음

DNS 문제가 의심될 때 아래 순서로 확인하면 대부분 원인을 5분 안에 파악할 수 있습니다.

위험 명령어

이 명령은 실행 중인 서비스 상태를 바꿔 순간적인 중단이나 설정 반영 실패를 만들 수 있습니다. 운영 트래픽 영향과 재시작 후 확인 명령을 먼저 준비하세요.

로컬 터미널
# 현재 DNS 설정 한눈에 보기
resolvectl status 2>/dev/null || cat /etc/resolv.conf

# DNS 서버별 응답 시간 테스트
for dns in 8.8.8.8 8.8.4.4 1.1.1.1; do
    echo -n "$dns: "
    time nslookup google.com $dns > /dev/null 2>&1
done

# DNS 캐시 플러시 (이상한 결과 나올 때)
sudo systemd-resolve --flush-caches
# 또는
sudo resolvectl flush-caches
# 또는 NetworkManager 재시작
sudo systemctl restart NetworkManager

# 특정 도메인 DNS 추적
dig +trace google.com
# 루트 DNS → TLD DNS → 권한 DNS 전체 과정 보기

클라우드 환경에서의 DNS 특이점

클라우드 환경은 각 공급자가 제공하는 메타데이터 DNS 서버를 사용합니다. 온프레미스와 주소 체계가 다르므로 혼동하지 않도록 주의합니다.

AWS EC2:
- DHCP로 169.254.169.253 DNS 서버 자동 설정
- VPC DNS: 10.0.0.2 (VPC 기본 게이트웨이 +2 주소)
- Route 53 Resolver로 내부 도메인 해석

GCP GCE:
- 169.254.169.254 메타데이터 서버가 DNS 역할
- 내부 도메인: *.internal

Azure:
- 168.63.129.16 Azure DNS

클라우드에서 resolv.conf 직접 수정은 위험: cloud-init이 부팅 시 파일을 덮어쓰기 때문에 수동 수정은 재부팅 후 사라집니다.

로컬 터미널
# AWS EC2에서 resolv.conf 수정 시 주의
# cloud-init이 재부팅 시 resolv.conf를 원복할 수 있음

# AWS 권장 방법: DHCP 옵션 세트에서 DNS 서버 변경
# Console → VPC → DHCP option sets → DNS servers 수정

현업 팁 — 서버 프로비저닝 시 DNS 검증 자동화

서버를 새로 프로비저닝한 직후 DNS가 올바르게 동작하는지 확인하는 간단한 스크립트입니다. CI/CD 파이프라인의 헬스체크나 Ansible 후처리 단계에 넣어 쓸 수 있습니다.

로컬 터미널
# 서버 배포 후 DNS 검증 스크립트
#!/bin/bash
check_dns() {
    local domain="${1:-google.com}"
    local dns_server="${2}"

    if [ -n "$dns_server" ]; then
        result=$(nslookup "$domain" "$dns_server" 2>&1)
    else
        result=$(nslookup "$domain" 2>&1)
    fi

    if echo "$result" | grep -q "Address:"; then
        echo "✓ DNS 해석 성공: $domain"
        return 0
    else
        echo "✗ DNS 해석 실패: $domain"
        echo "  오류: $result"
        return 1
    fi
}

# 인터넷 도메인 확인
check_dns google.com

# 내부 도메인 확인
check_dns internal.company.com 10.0.0.1

# 역방향 DNS 확인
nslookup 8.8.8.8

정리

/etc/resolv.conf 핵심 지시어

  • nameserver: DNS 서버 IP (최대 3개, 순서대로 시도)
  • search: 짧은 호스트명에 자동으로 붙는 도메인
  • domain: 시스템 기본 도메인
  • options: timeout, attempts, ndots 등 세부 설정

DNS 문제 진단 흐름

  • ping 8.8.8.8 성공 → 네트워크 정상
  • ping google.com 실패 → DNS 문제
    • nslookup google.com 실패 + nslookup google.com 8.8.8.8 성공 → resolv.conf nameserver 설정 문제
  • cat /etc/resolv.conf로 nameserver 확인 및 수정

영구 설정 방법

  • nmcli: nmcli con mod <이름> ipv4.dns "8.8.8.8 8.8.4.4"
  • systemd-resolved: /etc/systemd/resolved.conf
  • Netplan: /etc/netplan/*.yaml의 nameservers
  • 재부팅 후 초기화되면 → NetworkManager/cloud-init 덮어쓰기가 원인

재부팅 후 초기화 문제 해결

  • ls -la /etc/resolv.conf → 심볼릭 링크 확인
  • cat /etc/resolv.conf 상단 주석 → 관리 주체 확인
  • nmcli con mod + ipv4.ignore-auto-dns yes → 영구 해결

명령어·단축키 빠른 참조

이 모듈에서 다룬 DNS 진단·설정 명령을 실전 옵션과 함께 모았습니다. "예" 열의 조합을 그대로 써도 됩니다.

명령어/단축키용도자주 쓰는 예
cat /etc/resolv.conf현재 nameserver·search·options 확인가장 먼저 — nameserver가 비었/틀렸는지
ls -la /etc/resolv.conf관리 주체(심볼릭 링크) 판별링크면 systemd-resolved가 덮어씀
ping (IP vs 도메인)DNS 문제 vs 네트워크 문제 분리ping -c2 8.8.8.8 성공 + ping -c2 google.com 실패 = DNS
nslookup <도메인> <서버>특정 DNS 서버로 직접 질의nslookup google.com 8.8.8.8 (성공=resolv.conf 문제)
dig질의 상세·특정 서버 지정dig @8.8.8.8 google.com
dig +trace루트→TLD→권한 위임 경로 추적dig +trace google.com (SERVFAIL 원인)
nmcli con mod ... ipv4.dns재부팅 후에도 유지되는 영구 DNSsudo nmcli con mod "ens3" ipv4.dns "8.8.8.8 8.8.4.4"
nmcli con mod ... ipv4.ignore-auto-dnsDHCP가 준 DNS 무시sudo nmcli con mod "ens3" ipv4.ignore-auto-dns yes
resolvectl statussystemd-resolved DNS 상태 확인적용된 nameserver·fallback 확인
resolvectl flush-cachesDNS 캐시 플러시이상한 해석 결과 나올 때
grep hosts /etc/nsswitch.conf이름 해석 순서(files/dns) 확인/etc/hosts가 DNS보다 우선하는지
netplan applyNetplan YAML DNS 반영(Ubuntu Server)sudo netplan applyresolvectl status

관련 모듈로 더 깊이:

다음 모듈에서는 서비스가 127.0.0.1에만 바인딩되어 외부에서 연결이 안 되는 상황을 진단하고, bind-address 설정으로 해결하는 방법을 다룹니다.

지식 확인

퀴즈 — 8문제

Q1

신규 서버를 셋업한 뒤 `ping 8.8.8.8`은 성공하지만 `curl https://github.com`은 'Could not resolve host: github.com' 오류가 납니다. 가장 먼저 확인해야 할 파일과 확인 내용은 무엇입니까?

Q2

ping 8.8.8.8은 성공하지만 ping google.com이 실패하며 'Name or service not known' 오류가 발생했습니다. 가장 가능성 높은 원인은?

Q3

재부팅 후 /etc/resolv.conf 설정이 초기화되는 주요 원인은?

Q4

/etc/resolv.conf의 search 지시어는 어떤 역할을 합니까?

Q5

nmcli를 사용하여 특정 네트워크 연결에 DNS 서버를 영구적으로 설정하는 올바른 명령어는?

Q6

/etc/resolv.conf에 nameserver를 두 줄(예: 10.0.0.53, 8.8.8.8) 적었을 때 리졸버의 동작은?

Q7

[심화] 쿠버네티스 파드(options ndots:5, search 도메인 4~5개)에서 외부 도메인 api.example.com(점 2개)을 조회하면 실제로 무슨 일이 일어나는가?

Q8

[심화] 호스트명 조회가 대부분 수 ms인데 가끔 정확히 5초 지연 후 성공한다(실패는 아님). nameserver와 레코드는 정상이다. 가장 유력한 원인은?

0 / 8 답변

🧪 실습으로 확인하기

포트는 열렸다는데 왜 안 되지? — ss/netstat/telnet으로 TCP 진단

초급

"포트 8080 열었는데요?"와 "왜 안 돼요?" 사이의 간극을 메우는 실습. ss로 바인딩 상태를 확인하고, telnet/nc으로 원격 연결을 테스트하고, iptables 방화벽을 진단하고, 바인딩 주소(0.0.0.0 vs 127.0.0.1)까지 수정하는 4단계 TCP 포트 진단 플로우를 완성한다.

35📋 4단계💻 직접 환경
실습 시작하기 →

이것도 배워보세요