도메인 이름을 IP 주소로 바꾸는 분산 데이터베이스. 인터넷에서 가장 많이 쓰이는 조회 시스템이다.
계층적 위임
. (루트 — 13개 논리 서버)
│ "com 은 저기에 물어봐"
com (TLD 네임서버)
│ "example.com 은 저기에 물어봐"
example.com (권한 네임서버 — 실제 답을 안다)
│
www.example.com → 93.184.216.34
한 곳이 전부를 알지 않는다 — 자기 아래 구역을 누가 아는지만 알려 준다. 이 위임 구조 덕분에 전 세계 도메인을 나눠 관리할 수 있다.
누가 발품을 파나
[클라이언트] ──재귀 질의──→ [재귀 리졸버] ──반복 질의──→ 루트
"IP 알려줘" (ISP · 8.8.8.8) ←── "com 에 물어봐"
├──반복 질의──→ com
│ ←── "example.com 에 물어봐"
└──반복 질의──→ example.com
←── "93.184.216.34"
[클라이언트] ←──── 최종 답 ────
클라이언트는 한 번만 묻는다 (재귀)
리졸버가 대신 여러 번 묻는다 (반복)
캐싱과 TTL
매번 루트부터 물으면 루트 서버가 감당하지 못한다
- 각 단계가 결과를 TTL 동안 캐시한다
- 실제로 루트까지 가는 질의는 극소수다
dig example.com # ANSWER SECTION 에 TTL 이 초 단위로 나온다
dig +trace example.com # 루트부터 따라가는 전 과정을 본다
TTL이 만드는 실무 문제
서버를 옮기며 IP 를 바꿨다
- TTL 이 86400(하루) 이면, 캐시가 만료될 때까지 옛 IP 로 가는 사용자가 남는다
- "일부 사용자만 접속이 안 된다" 는 증상
처방: 변경 예정일 며칠 전에 TTL 을 60초로 낮춰 둔다 → 변경 → 다시 올린다
TTL 변경은 미리 해야 효과가 있다 — 바꾸는 시점에 낮춰 봐야 이미 퍼진 캐시에는 옛 TTL이 적용된다.
레코드 종류
- A 도메인 → IPv4
- AAAA — 도메인 → IPv6
- CNAME — 도메인 → 다른 도메인 (별칭). 루트 도메인에는 쓸 수 없다
- MX — 메일 서버
- NS — 이 구역의 권한 네임서버
- TXT — 임의 텍스트 (SPF · 소유권 검증)
보안
-
DNS 는 원래 평문이고 인증이 없다
- 캐시 포이즈닝 · 도청 · 변조가 가능하다
-
DNSSEC — 응답에 서명을 붙여 위조를 막는다 (기밀성은 아니다)
-
DoH/DoT — HTTPS·TLS 위로 질의해 도청을 막는다
면접 함정
- ❌ "DNS는 TCP를 쓴다" → 기본은 UDP 53이다. 응답이 크거나 영역 전송일 때 TCP로 넘어간다.
- ❌ "CNAME은 아무 데나 쓸 수 있다" → 루트 도메인(
example.com)에는 쓸 수 없다.
조회 과정 전체 보기
dig +trace www.example.com
# . NS a.root-servers.net.
# com. NS a.gtld-servers.net.
# example.com. NS ns1.example.com.
# www.example.com. A 93.184.216.34
dig +short www.example.com
dig @8.8.8.8 example.com MX # 특정 리졸버·레코드 타입 지정
nslookup -type=NS example.com
로컬 캐시도 있다
# 브라우저 · OS · 리졸버 세 단계로 캐시된다
sudo systemd-resolve --flush-caches # 리눅스
sudo dscacheutil -flushcache # macOS
ipconfig /flushdns # 윈도우
"DNS 를 바꿨는데 반영이 안 된다" 면 어느 단계 캐시인지부터 가른다
DNS 기반 로드밸런싱의 한계
같은 이름에 여러 A 레코드를 두면 라운드로빈처럼 동작한다
한계
-
서버가 죽어도 TTL 동안 그 IP 로 계속 보낸다 (헬스체크가 없다)
-
캐시 때문에 분배가 고르지 않다
-
클라이언트마다 캐시 상태가 달라 예측이 어렵다
-
정밀한 분배는 로드밸런서가 맡고, DNS 는 지역 단위 분배에 쓴다