infra
Platform

모듈 맵

[Infra Ops] A레코드/CNAME 운영과 /etc/hosts 활용 실무

0 / 52 완료

펼치기
0 / 52 완료0%

인프라 운영 & SRE · 20 / 52

[Infra Ops] A레코드/CNAME 운영과 /etc/hosts 활용 실무

A/CNAME/MX 레코드, 내부 DNS vs 공인 DNS, /etc/hosts 오버라이드, 도메인 변경 영향도 분석까지 — 서버 운영자가 반드시 알아야 할 DNS 실무

🚨INCIDENT ALERT
HIGH

서비스 도메인을 새 서버로 옮기는 작업을 맡았습니다. 작업은 간단해 보입니다 — DNS A 레코드의 IP만 바꾸면 됩니다. 변경을 완료했는데 다음 날 오전, 일부 사용자가 "저는 여전히 구 서버로 접속되는데요?"라고 합니다.

DNS 캐시 때문입니다. 그런데 어떤 캐시가, 어느 서버에 남아있는지 알아야 제대로 대응할 수 있습니다.

DNS는 인프라 운영의 가장 기초이자, 막히면 아무것도 안 되는 핵심 인프라입니다. A 레코드 하나만 바꾸는 것처럼 보여도 TTL, 캐시 전파, 내부 DNS, 연계 시스템 영향도를 모르면 작업이 사고로 바뀝니다.

이번 챕터에서 배울 것
  • 1A, AAAA, CNAME, MX, TXT 레코드의 역할과 사용 시점을 설명할 수 있다
  • 2/etc/hosts와 /etc/resolv.conf의 관계 및 우선순위를 설명할 수 있다
  • 3내부 DNS와 공인 DNS 분리 운영 구조를 이해하고 장애 시 어느 DNS가 문제인지 구분할 수 있다
  • 4DNS TTL 전략을 세워 도메인 변경 작업의 영향을 최소화할 수 있다
  • 5nslookup, dig, resolvectl 명령어로 DNS 조회 결과를 분석할 수 있다

DNS 레코드 종류와 역할

인터넷의 전화번호부가 DNS입니다. 도메인 이름을 IP 주소로 바꾸는 것이 핵심이지만, 실제로는 그보다 훨씬 많은 정보를 담습니다.

💡개념

DNS 레코드 타입 — 무엇이 언제 필요한가

도메인을 새 서버로 옮기는 작업 중 "A 레코드를 바꿨는데 왜 아직도 구 서버로 가냐"는 질문을 받습니다. TTL 때문인지, 캐시 때문인지, 아니면 다른 레코드 타입이 문제인지 — 레코드 종류를 모르면 원인을 좁힐 수 없습니다. 메일이 안 간다는 신고가 들어와도 MX 레코드를 모르면 어디를 봐야 할지 막막합니다.

DNS 레코드는 용도에 따라 타입이 나뉩니다. 서버 운영자가 직접 설정하고 조회하는 레코드는 주로 다음 여섯 가지입니다.

A 레코드 — 도메인을 IPv4 주소에 직접 연결

가장 기본적인 레코드입니다. example.com → 203.0.113.10처럼 도메인과 IP를 1:1로 매핑합니다. 같은 도메인에 여러 IP를 등록하면 DNS 레벨의 기본적인 부하 분산이 됩니다.

로컬 터미널
# A 레코드 조회
dig A example.com

AAAA 레코드 — 도메인을 IPv6 주소에 연결

IPv6 환경에서 사용합니다. 구조는 A 레코드와 동일하며 주소 체계만 다릅니다.

CNAME 레코드 — 도메인을 다른 도메인의 별칭으로 연결

www.example.com → example.com처럼 설정하면 www는 example.com이 가리키는 IP를 따라갑니다. IP가 바뀌어도 CNAME이 바라보는 원본 도메인의 A 레코드만 수정하면 됩니다.

주의 사항이 하나 있습니다. CNAME은 도메인 루트(Apex)에 설정할 수 없습니다. example.com 자체를 CNAME으로 설정하면 안 됩니다. 반드시 서브도메인(www, api, cdn 등)에만 사용해야 합니다.

MX 레코드 — 메일 서버를 지정

해당 도메인으로 오는 이메일을 어느 서버가 받을지 결정합니다. 우선순위(낮은 숫자가 높은 우선순위) 값을 함께 설정합니다. 메일 관련 장애 시 MX 레코드를 확인합니다.

로컬 터미널
dig MX example.com

TXT 레코드 — 텍스트 데이터 보관

다목적 레코드입니다. 주로 세 가지 용도로 씁니다.

용도예시
SPF (스팸 발송 방지)v=spf1 include:_spf.google.com ~all
DKIM (이메일 서명 검증)v=DKIM1; k=rsa; p=MIIBIjANBg...
도메인 소유권 확인Google Search Console, AWS Certificate Manager 인증 시

NS 레코드 — 이 도메인을 관리하는 네임서버 지정

도메인 등록 시 설정하는 레코드입니다. 운영 중 변경하면 DNS 전파가 오래 걸리므로 일반적으로 건드리지 않습니다.

SOA 레코드 — 도메인의 기본 정보

Primary 네임서버, 관리자 이메일, 레코드 갱신 주기 등 DNS 영역(Zone)의 메타데이터를 담습니다. 직접 수정할 일은 거의 없지만 dig SOA로 조회해 Zone 기본 TTL을 확인할 때 씁니다.

/etc/hosts와 /etc/resolv.conf — 로컬 DNS 설정

외부 DNS 서버에 질의하기 전에 OS가 먼저 확인하는 두 파일이 있습니다.

DNS 조회 흐름과 우선순위 — 도메인 조회는 ① /etc/hosts(로컬 정적 파일) → ② 로컬 DNS 캐시 → ③ resolv.conf의 DNS 서버(리졸버) → ④ Root NS 순으로 진행. 리졸버가 Root→.com TLD→권한 NS로 재귀 질의해 IP를 받아 TTL 동안 캐시. /etc/hosts에 항목이 있으면 DNS 질의 자체를 건너뜀확대

💡개념

이름 하나가 IP로 풀리기까지 — 해석 6단계

curl yourdomain.com 한 줄을 치면 OS는 곧바로 DNS 서버에 묻지 않습니다. 로컬 파일부터 확인하고, 정해진 우선순위를 따라, 캐시를 거쳐, 그제야 외부 리졸버로 나갑니다. 이 순서를 알면 "hosts에 넣었는데 무시됨", "레코드 만들었는데 없다고 나옴", "나만 옛 IP로 감" 같은 증상이 어느 단계의 문제인지 바로 좁혀집니다. 이름 해석은 단순히 "DNS가 IP를 준다"가 아니라 아래 순서의 결과입니다.

TEXT
[앱]  getaddrinfo("yourdomain.com")
   │
   ① 애플리케이션 질의                 (앱·libc가 이름 해석 요청)
   │
   ② nsswitch 순서 결정                (/etc/nsswitch.conf: hosts: files dns ...)
   │
   ③ /etc/hosts 확인 (files)           (여기 있으면 → DNS 안 감, 즉시 반환)
   │    없으면 ↓
   │
   ④ 로컬 캐시 확인                     (systemd-resolved·nscd에 있으면 TTL 내 반환)
   │    없으면 ↓
   │
   ⑤ resolv.conf의 리졸버로 질의        (nameserver로 재귀 요청)
   │    → 리졸버가 루트 → TLD(.com) → 권한 NS 순으로 추적
   │
   ⑥ 응답 캐시 후 반환                  (TTL 동안 보관, 다음엔 ④에서 HIT)
   ▼
[앱]  203.0.113.10   (앞 단계에서 답이 나오면 이후 단계는 건너뜀)

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

단계하는 일여기서 막히면/틀어지면
① 앱 질의앱이 직접 DNS를 구현하는 게 아니라 libc의 getaddrinfo()(또는 자체 리졸버)에 이름 해석을 맡긴다앱이 자체 DNS 캐시를 가지면(예: JVM) OS 캐시를 flush해도 앱은 옛 IP 유지 → 앱 재시작 필요
② nsswitch 순서/etc/nsswitch.confhosts: 줄이 조회 순서를 정한다. 보통 files dns — 파일 먼저, DNS 나중순서가 dns files면 hosts가 후순위 → hosts에 넣어도 DNS 값이 이김
③ /etc/hosts (files)정적 매핑 파일을 본다. 항목이 있으면 DNS 질의 자체를 건너뛰고 그 IP를 반환(가장 강한 오버라이드)hosts 수정이 반영 안 되면 nscd 캐시가 잡고 있는 것 → nscd --invalidate=hosts
④ 로컬 캐시systemd-resolved · nscd가 최근 응답을 TTL 동안 보관. 있으면 외부로 안 나감변경 후에도 옛 IP면 캐시 만료 전 → resolvectl flush-caches / '없음'(NXDOMAIN)도 캐시됨(네거티브 캐싱)
⑤ 리졸버 재귀 질의/etc/resolv.confnameserver로 질의. 리졸버가 루트 → .com TLD → 권한 NS로 내려가며 답을 찾는다리졸버 무응답·타임아웃 → SERVFAIL / 이름 자체가 없으면 → NXDOMAIN
⑥ 캐시 후 반환받은 레코드를 TTL만큼 캐시하고 앱에 반환. 다음 같은 질의는 ④에서 HITTTL이 길면 변경 후에도 옛 IP가 오래 살아남음 → 변경 전 TTL 낮추기

즉 이름 해석은 "파일(③) → 캐시(④) → 외부 리졸버(⑤)" 순서로, 앞 단계에서 답이 나오면 뒤 단계는 아예 실행되지 않습니다. 그래서 진단도 위에서부터 내려갑니다 — getent hosts yourdomain.com으로 OS의 최종 결과(①~④ 반영)를 보고, 값이 이상하면 grep hosts /etc/nsswitch.conf(②)와 /etc/hosts(③)를 확인하고, 그래도 안 맞으면 dig @8.8.8.8 yourdomain.com으로 캐시를 우회해(④를 건너뛰고) 리졸버·권한 서버(⑤)의 실제 응답을 봅니다. digstatus:NXDOMAIN이면 '없음'까지 캐시된 네거티브 캐싱을 의심합니다.

💡개념

/etc/hosts — 가장 강력한 로컬 오버라이드

신규 도메인을 DNS에 올리기 전에 특정 서버에서만 먼저 동작을 확인해야 합니다. DNS를 건드리면 전체 환경에 영향이 가므로 이 서버에서만 해당 도메인을 테스트 IP로 연결하고 싶습니다. DNS 캐시가 오염돼 특정 도메인이 해석이 안 될 때 임시로 우회하는 방법도 필요합니다. 이 모든 상황에 /etc/hosts가 답입니다.

/etc/hosts는 OS가 도메인 이름을 조회할 때 가장 먼저 참조합니다. 여기에 항목이 있으면 DNS 서버로 질의를 보내지 않습니다.

로컬 터미널
# /etc/hosts 형식
# IP주소    도메인명 [별칭...]
127.0.0.1   localhost
::1         localhost ip6-localhost

# 내부 서비스
192.168.10.20   internal-api.company.com api
192.168.10.30   db-primary.internal

# 개발 환경에서 신규 도메인 미리 연결
10.0.1.50   new-service.company.com

실무에서 /etc/hosts를 쓰는 세 가지 상황이 있습니다.

첫째, DNS 등록 전 사전 테스트입니다. 새 도메인을 DNS에 올리기 전에 특정 서버에서만 해당 도메인을 먼저 연결해 동작을 검증합니다.

둘째, 내부 서비스 접근입니다. 사내 DNS가 없거나 구축하기 어려울 때 서버마다 /etc/hosts로 내부 서비스 도메인을 관리합니다. 다만 서버가 많아지면 관리가 어려워집니다.

셋째, 장애 우회입니다. DNS 서버 문제로 특정 도메인이 해석되지 않을 때 임시로 /etc/hosts에 직접 IP를 넣어 서비스를 이어갑니다.

/etc/hosts가 우선 적용되는 이유는 /etc/nsswitch.conf에 있습니다.

로컬 터미널
# /etc/nsswitch.conf — 이름 해석 우선순위
hosts: files dns myhostname
#      ^^^^^ ^^^
#      files = /etc/hosts 먼저
#      dns = 그 다음 DNS 서버

이 설정이 없으면 순서가 달라질 수 있습니다. 실무에서 /etc/hosts가 적용 안 되는 것처럼 보이면 /etc/nsswitch.conf를 확인하세요.

💡개념

/etc/resolv.conf — DNS 서버 지정

서버 내부에서 외부 도메인 조회가 갑자기 안 됩니다. ping google.com은 실패하는데 ping 8.8.8.8은 됩니다. DNS 쿼리가 어디로 가는지 — 즉 어떤 DNS 서버를 사용하는지 모르면 이 문제를 진단할 수 없습니다. /etc/resolv.conf를 보면 이 서버가 어떤 DNS를 쓰는지 즉시 알 수 있습니다.

/etc/hosts에 항목이 없으면 /etc/resolv.conf에 기록된 DNS 서버로 질의합니다.

로컬 터미널
# /etc/resolv.conf
nameserver 10.0.0.53       # 내부 DNS 서버 (첫 번째)
nameserver 8.8.8.8         # 공인 DNS (첫 번째 실패 시 대체)
search company.com internal.company.com  # 짧은 호스트명 자동 보완
domain company.com

search 옵션이 중요합니다. curl api를 실행하면 OS는 api.company.com, api.internal.company.com 순으로 자동으로 도메인을 붙여 질의합니다. 짧은 호스트명만으로 내부 서비스에 접근할 수 있게 해주는 기능입니다.

주의할 점이 있습니다. systemd-networkd나 NetworkManager가 관리하는 환경에서는 /etc/resolv.conf가 자동으로 덮어쓰입니다. 직접 수정해도 재부팅이나 네트워크 재시작 시 초기화됩니다. 이 환경에서는 NetworkManager 설정이나 resolvectl로 DNS를 변경해야 합니다.

로컬 터미널
# 현재 사용 중인 DNS 서버 확인 (systemd-resolved 환경)
resolvectl status

# DNS 서버 및 search domain 일시 변경
resolvectl dns eth0 10.0.0.53
resolvectl domain eth0 company.com

내부 DNS vs 공인 DNS 분리 운영

💡개념

왜 내부 DNS를 별도로 운영하는가

기업 환경에서 DB 서버나 내부 API의 IP를 공인 DNS에 등록하면 외부에 내부 인프라 구조가 노출되는 보안 위험이 생깁니다. 반면 내부 DNS를 별도로 운영하면 db-primary.internal 같은 짧고 의미 있는 이름으로 내부 서버에 접근하면서, 공인 도메인 조회는 외부 DNS로 포워딩하는 이중 구조를 만들 수 있습니다. 새 서버 추가, IP 변경, 서비스 이전 시에도 각 서버의 설정 파일을 건드리지 않고 DNS 레코드 하나만 수정하면 되므로, 내부 DNS는 규모가 커질수록 관리 효율이 더욱 높아집니다.

내부 DNS vs 공인 DNS 분리 구조 — 내부 서버 IP를 공인 DNS에 올리면 내부 인프라 구조가 외부에 노출됨. 내부 DNS를 별도 운영하면 db-primary.internal 같은 이름으로 내부 서버에 접근하면서 공인 도메인은 외부 DNS로 조회. split-horizon DNS로 같은 도메인도 내·외부에 다른 응답을 줄 수 있음확대

내부 WAS 서버에서 db-primary.internal로 접속하는 코드가 있습니다. 외부 DNS에는 등록되지 않은 도메인입니다. 외부에서는 DB IP가 보이면 안 되고, 내부에서는 짧은 이름으로 접근해야 합니다. 이 요구사항을 해결하기 위해 기업 환경에서는 내부 DNS와 공인 DNS를 분리해서 운영합니다.

공인 DNS에는 외부 사용자가 접근해야 하는 도메인만 등록합니다. 내부 서버(db-primary.internal, app-server-01.internal)는 공인 DNS에 올리지 않습니다. 내부 IP를 외부에 노출하면 보안 위험이 생기기 때문입니다.

내부 DNS 서버는 두 가지 역할을 합니다. 첫째, 내부 도메인(*.internal, *.company.com)을 내부 IP로 해석합니다. 둘째, 공인 도메인 질의는 공인 DNS 서버(8.8.8.8 등)로 포워딩합니다.

서버 운영자 관점에서 실무 포인트가 있습니다. 새 서버를 추가하면 내부 DNS에 A 레코드 등록 요청이 필요합니다. 내부 DNS가 다운되면 내부 서비스 간 통신이 전부 끊깁니다. /etc/resolv.conf에 내부 DNS를 첫 번째 nameserver로, 공인 DNS를 두 번째로 설정하는 것이 기본 구성입니다.

스플릿 DNS (Split-horizon DNS)

같은 도메인이지만 내부에서는 내부 IP, 외부에서는 공인 IP로 해석되길 원할 때 씁니다. api.example.com에 내부 접속 시 10.0.1.10을, 외부 접속 시 203.0.113.10을 반환하는 식입니다. 내부/외부 뷰를 분리한 BIND나 클라우드 Route53의 Private Hosted Zone으로 구현합니다.

DNS TTL과 전파 전략

💡개념

TTL 전략 — 도메인 변경 작업의 핵심

서비스를 새 서버로 이전하면서 DNS A 레코드를 변경했습니다. 변경 직후 일부 사용자는 새 서버로, 일부는 구 서버로 접속됩니다. 몇 시간이 지나도 구 서버로 가는 사용자가 있습니다. TTL을 3600초(1시간)로 방치했기 때문입니다. 이 문제를 작업 전에 막을 수 있는 방법이 있습니다.

TTL(Time To Live)은 DNS 캐시 서버가 레코드를 보관하는 시간(초 단위)입니다. TTL이 3600이면 한 번 조회한 결과를 1시간 동안 사용합니다.

DNS TTL 무중단 서버 이전 순서 — ① 변경 48시간 전 TTL을 3600에서 300(5분)으로 낮춤 → ② 48시간 대기(기존 3600초 캐시가 전부 만료) → ③ 변경 당일 A 레코드 IP 변경(전파 최대 5분) → ④ dig로 여러 DNS 서버에서 새 IP 검증(문제 시 롤백도 5분) → ⑤ TTL을 300에서 3600으로 복원. TTL 값이 곧 최대 전파 시간이라, 미리 낮추면 컷오버·롤백이 빠르다. 안 낮추고 바꾸면 일부 사용자가 최대 1시간 구 IP로 접속해 접속이 오락가락한다확대

도메인 변경 시 TTL 낮추기

IP를 변경하거나 도메인을 이전할 때 TTL이 높으면 변경 후에도 오랫동안 구 IP로 접속하는 사용자가 생깁니다. 작업 계획은 다음과 같습니다.

변경 작업 48시간 전:  TTL을 3600 → 300 (5분)으로 낮춤
     ↓ 48시간 대기 (기존 3600초 캐시가 전부 만료되길 기다림)
변경 작업 당일:       A 레코드 IP 변경
     ↓ 300초(5분) 대기
변경 완료 확인:       nslookup, dig로 여러 DNS 서버에서 새 IP 조회 확인
     ↓ 안정 확인 후
TTL 복원:            300 → 3600 (운영 안정화)

TTL을 낮추는 이유는 만약 새 IP에 문제가 생겼을 때 다시 구 IP로 롤백해도 최대 5분이면 전파되도록 하기 위함입니다.

TTL과 전파 시간의 관계

"DNS 전파"는 전 세계 캐시 서버가 새 레코드를 갱신하는 데 걸리는 시간입니다. TTL 설정값이 최대 전파 시간을 결정합니다. TTL 300이면 최대 5분, TTL 3600이면 최대 1시간을 기다려야 합니다.

DNS 조회 실습

DNS 레코드 조회
1

기본 A 레코드 조회

nslookup example.com
2

상세 DNS 조회 — 위임 경로 추적

dig +trace example.com
3

MX 레코드 조회

dig example.com MX
4

특정 DNS 서버로 직접 질의

dig @8.8.8.8 example.com
🔍실행 후 확인할 것
  • dig 출력에서 먼저 status: 줄로 정상 여부 확인, 그 다음 ANSWER SECTION에서 반환된 IP와 TTL 확인 — status가 NOERROR여야만 ANSWER SECTION의 IP를 신뢰할 수 있음
  • Query time 기준: 1ms 미만=DNS 캐시에서 반환(실제 전파 여부 확인 불가), 50ms 이상=DNS 서버에 직접 질의(전파 상태 확인 가능) — DNS 변경 직후에는 dig @8.8.8.8 도메인 으로 외부 DNS 서버에 직접 질의해야 전파 확인 가능
  • status: NOERROR인데 ANSWER SECTION이 비어 있으면 → A 레코드가 없는 것(CNAME만 존재하거나 레코드 삭제됨) / status: NXDOMAIN이면 도메인 자체가 없는 것 — 두 경우 모두 DNS 레코드 설정 점검 필요
/etc/hosts 활용 실습
1

/etc/hosts에 테스트 도메인 등록

sudo vi /etc/hosts
2

hosts 등록 확인

getent hosts new-service.company.com
3

curl로 도메인 연결 테스트

curl -v http://new-service.company.com/health
🔍실행 후 확인할 것
  • getent hosts new-service.company.com 으로 OS 이름 해석 결과 먼저 확인, 그 다음 curl -v 첫 줄 "Trying IP..." 로 실제 연결 IP 확인 — getent는 /etc/hosts와 DNS 우선순위를 적용한 최종 결과를 보여줌
  • getent 결과 기준: /etc/hosts에 등록된 IP가 나오면 hosts 우선 적용 중(정상), DNS 서버의 다른 IP가 나오면 /etc/nsswitch.conf에서 hosts 항목 순서가 dns가 files보다 앞에 있는 것 — 테스트 환경에서 hosts 파일이 우선해야 하면 files dns 순서 확인
  • getent에서 등록 IP가 나오는데 curl에서 다른 IP에 연결되면 → 애플리케이션이 자체 DNS 캐시를 사용 중 — Java 앱은 JVM 레벨 DNS 캐시(networkaddress.cache.ttl)가 별도 존재하므로 JVM 재시작 필요

도메인 변경 시 영향도 분석

💡개념

A 레코드 하나 바꿀 때 연쇄 영향을 확인하라

도메인 변경 후 SSL 인증서 오류가 납니다. 다른 팀에서 CORS 오류가 난다고 연락이 옵니다. SSO 로그인이 안 된다는 신고도 들어옵니다. A 레코드 하나를 바꿨을 뿐인데 연쇄적으로 문제가 터집니다. 변경 전 어떤 시스템이 이 도메인에 의존하는지 파악하지 않으면 이런 장애를 피할 수 없습니다.

도메인 변경은 단순해 보이지만 연결된 시스템이 많습니다. 변경 전 다음 항목을 점검합니다.

SSL/TLS 인증서

인증서는 도메인 이름 기반으로 발급됩니다. 도메인이 바뀌거나 서브도메인이 추가되면 인증서를 새로 발급해야 합니다. 기존 인증서를 그대로 쓰면 브라우저에서 인증서 오류가 납니다.

SSO Entity ID와 SAML 설정

사내 SSO(Single Sign-On)를 사용하는 서비스라면 IdP(Identity Provider)에 등록된 Entity ID가 도메인 기반인 경우가 많습니다. 도메인이 바뀌면 IdP 설정도 함께 수정해야 합니다.

서비스 간 내부 참조

다른 서비스가 변경 대상 도메인을 설정 파일이나 환경변수에 하드코딩하고 있을 수 있습니다. 변경 전 grep -r "old-domain.company.com" /etc/ 또는 코드베이스 전체를 검색합니다.

모니터링과 알림 설정

Prometheus 타겟, Grafana 데이터소스, 외부 업타임 모니터링에 도메인이 등록돼 있으면 함께 업데이트해야 합니다.

CORS 허용 목록

API 서버의 CORS 설정에 프론트엔드 도메인이 등록돼 있을 때 도메인이 바뀌면 CORS 오류가 발생합니다.

A 레코드 하나를 바꿀 때의 연쇄 의존성 — 도메인(app.company.com)의 A 레코드를 새 IP로 바꾸면 여러 시스템이 연쇄적으로 영향을 받는다. ① SSL/TLS 인증서는 도메인 기반으로 발급돼 재발급하지 않으면 브라우저 인증서 오류, ② SSO Entity ID/SAML은 IdP에 등록된 Entity ID가 도메인 기반이라 IdP 설정도 수정 필요, ③ 서비스 간 내부 참조는 설정·환경변수에 도메인이 하드코딩돼 있을 수 있어 grep -r로 전체 검색, ④ 모니터링/알림은 Prometheus 타겟·Grafana·업타임 모니터에 등록돼 업데이트 필요, ⑤ CORS 허용 목록에 프론트 도메인이 등록돼 있으면 안 바꾸면 CORS 오류. A 레코드 하나 바꿨을 뿐인데 SSL·CORS·SSO가 연쇄로 터지므로 변경 전 "무엇이 이 도메인에 의존하나"를 파악하고, TTL 때문에 서버마다 캐시 만료 시점이 달라 과도기에 일부만 새 IP로 조회되는 점도 관리한다확대

장애 시나리오

심화 — 없는 레코드도 캐시된다(네거티브 캐싱)

💡개념

심화: 네거티브 캐싱과 SOA minimum — 포지티브 TTL만 보면 놓치는 것

지금까지의 TTL은 모두 '존재하는 레코드'를 캐시하는 시간이었습니다. 그런데 '존재하지 않는 이름'에 대한 응답, 즉 NXDOMAIN(도메인 없음)도 캐시됩니다 — 이것을 네거티브 캐싱이라 합니다(RFC 2308).

  • 얼마나 캐시되나: 레코드가 없으니 그 레코드의 TTL도 없습니다. 대신 그 존(zone)의 SOA 레코드 마지막 필드인 minimum 값이 네거티브 TTL이 되어, NXDOMAIN을 그 시간만큼 보관합니다. SOA minimum이 3600이면 '없음' 응답이 최대 1시간 캐시됩니다.
  • 왜 함정인가: 새 서브도메인을 만들기 전에 미리 dig나 브라우저로 그 이름을 조회하면, 리졸버가 NXDOMAIN을 네거티브 TTL만큼 캐시합니다. 그 뒤에 레코드를 만들어도, 이미 '없음'을 캐시한 리졸버는 네거티브 TTL이 끝날 때까지 계속 없다고 답합니다. '레코드를 분명히 만들었는데 아직도 not found'의 전형적 원인입니다. 포지티브 레코드 TTL을 아무리 낮춰도 소용없습니다 — 캐시된 건 레코드가 아니라 '없음'이니까요.
  • 왜 앞 모듈 내용으로는 안 잡히나: 앞의 'TTL을 미리 낮춘다' 전략은 이미 존재하는 레코드를 바꿀 때의 이야기입니다. 새로 만드는 레코드에는 낮출 TTL 자체가 없었고, 작동하는 것은 SOA minimum이라는 다른 값입니다.

핵심 설계: (1) 레코드를 먼저 만든 뒤에 조회합니다(만들기 전에 조회해 NXDOMAIN을 캐시시키지 않습니다). (2) 이미 캐시됐고 급하면 해당 리졸버 캐시를 flush하거나 네거티브 TTL이 끝나길 기다립니다. (3) 컷오버가 잦은 존은 SOA minimum을 낮게 유지합니다. 진단은 dig 응답의 status: NXDOMAIN과 AUTHORITY SECTION의 SOA, 그리고 남은 네거티브 TTL로 합니다.

상황: 레코드를 만들었고 권한 네임서버에는 반영됐습니다 — 권한 서버에 직접 dig @ns1.example.com api-v2.example.com으로 물으면 정상 응답이 옵니다. 그런데 사내·공용 리졸버로 조회하면 여전히 NXDOMAIN이고, 레코드 TTL을 낮춰도 효과가 없습니다.

원인: 레코드를 만들기 전에 누군가(모니터링·동료·혹은 나 자신)가 그 이름을 조회했고, 리졸버가 NXDOMAIN을 존의 SOA minimum(네거티브 TTL)만큼 캐시했습니다. 캐시된 것은 '없음'이라, 새로 만든 레코드의 60초 TTL과 무관하게 네거티브 TTL이 끝날 때까지 계속 없다고 답합니다.

진단: 권한 네임서버에 직접 물어 정상이면(→ 레코드 자체는 정상) 문제는 리졸버 캐시입니다. 리졸버로 dig api-v2.example.com을 하면 status: NXDOMAIN과 AUTHORITY SECTION의 SOA, 그리고 카운트다운되는 네거티브 TTL이 보입니다. 권한 서버 응답(정상)과 리졸버 응답(NXDOMAIN)을 나란히 비교하면 '레코드는 있는데 리졸버가 옛 없음을 캐시 중'이 확정됩니다.

해결: 급하면 해당 리졸버의 캐시를 flush하거나 네거티브 TTL 만료를 기다립니다. 재발 방지로 '레코드를 먼저 만들고 나서 조회'하는 순서를 지키고, 컷오버가 잦은 존은 SOA minimum을 낮게 유지합니다. 포지티브 TTL만 챙기다 네거티브 TTL(SOA minimum)을 잊는 것이 이 사고의 핵심입니다. 이 도메인을 L4/L7 로드밸런서와 VIP 기반 이중화 구성의 VIP나 인증서와 함께 신설할 때도 같은 순서 원칙이 적용됩니다.

💼
실무 맥락
현업 패턴

서비스 도메인 변경 작업 표준 절차

실제 운영 도메인 변경은 다음 순서로 진행합니다.

D-2 (작업 2일 전): TTL 낮추기

현재 TTL 값을 확인합니다.

로컬 터미널
dig example.com | grep -A1 'ANSWER SECTION'

DNS 관리 콘솔에서 TTL을 3600 → 300으로 낮춥니다. 그 후 현재 TTL 시간(최대 3600초)만큼 대기합니다. 이 시간이 지나야 모든 캐시 서버에서 300초 TTL이 적용됩니다.

D-Day: 레코드 변경

새 IP로 A 레코드를 수정합니다. 변경 즉시 여러 지점에서 조회합니다.

로컬 터미널
# 공인 DNS로 직접 질의해 변경 확인
dig @8.8.8.8 example.com
dig @1.1.1.1 example.com

# 내부 서버에서도 확인
dig example.com

새 서버 접속 확인 후 모니터링을 15분간 유지합니다.

작업 완료 후: TTL 복원

이상 없음을 확인한 뒤 TTL을 300 → 3600으로 복원합니다. 롤백이 필요할 때 TTL이 낮으면 구 IP로 빠르게 되돌릴 수 있으므로 안정 확인까지는 낮게 유지합니다.

명령어·단축키 빠른 참조

이 모듈에서 다룬 DNS 조회·캐시 진단 명령을 모았습니다. 변경 직후에는 캐시를 우회해 여러 리졸버로 교차 확인합니다.

명령어/단축키용도자주 쓰는 예
dig <도메인> <타입>레코드 조회dig A example.com, dig MX example.com
dig +trace <도메인>루트→권한 위임 경로 추적위임이 어디서 끊기는지 확인
dig @<서버> <도메인>특정 DNS에 직접 질의dig @8.8.8.8 example.com (전파 확인)
dig SOA <도메인>존 SOA·네거티브 TTL 확인NXDOMAIN 캐시 시간 = SOA minimum
nslookup <도메인>간단 조회응답의 Server(어느 DNS로 조회됐는지)
getent hosts <도메인>OS 최종 이름 해석hosts+DNS 우선순위 반영 결과
grep hosts /etc/nsswitch.conf해석 우선순위 확인files dns 순서여야 hosts 우선
resolvectl status현재 DNS 서버·도메인systemd-resolved 환경
systemd-resolve --flush-cachesDNS 캐시 비우기변경 후 새 IP 즉시 확인
nscd --invalidate=hostsnscd hosts 캐시 무효화systemctl restart nscd 로도
curl -v http://<도메인>/실제 연결 IP 확인Trying <ip> 로 hosts 적용 검증
host <도메인>짧은 레코드 조회빠른 확인용

관련 모듈로 더 깊이:

다음 모듈에서는 DNS가 반환하는 IP — VIP(Virtual IP)를 관리하는 로드밸런서의 동작 원리와 L4/L7 이중화 구성을 다룹니다.

지식 확인

퀴즈 — 8문제

Q1

AWS ALB를 도입하면서 도메인을 ALB 주소(긴 AWS 도메인명)로 연결해야 합니다. example.com의 루트 도메인에 ALB를 연결할 때 어떤 DNS 레코드를 사용해야 하는가?

Q2

/etc/hosts가 DNS 서버보다 먼저 적용되는 이유와 실무 활용 사례로 가장 적절한 것은?

Q3

DNS TTL이 300초인 레코드를 변경했을 때, 모든 DNS 캐시가 완전히 교체되기까지 걸리는 최대 시간은?

Q4

nslookup과 dig 중 더 상세한 DNS 정보를 얻을 수 있는 명령어와 그 이유는?

Q5

DNS 레코드 타입 A / CNAME / MX / TXT 는 각각 무엇을 위한 것인가?

Q6

다음 주에 서버 IP를 옮기는 도메인 변경 작업이 예정돼 있다. 작업을 매끄럽게 하려고 '미리' 해두면 좋은 것은?

Q7

[심화] 존재하지 않는 도메인(NXDOMAIN) 응답이 리졸버에 캐시되는 시간(네거티브 TTL)을 결정하는 것은?

Q8

[심화] 새 서브도메인 A 레코드를 방금 만들었는데 리졸버로는 계속 NXDOMAIN이다(권한 네임서버에 직접 물으면 정상, 레코드 TTL은 60초). 원인으로 가장 정확한 것은?

0 / 8 답변

🧪 실습으로 확인하기

Nginx 설치 및 기동

초급

Linux 서버에 Nginx를 설치하고 systemd 서비스로 등록하여 80포트에서 응답하는 상태까지 만든다.

40📋 3단계💻 직접 환경
실습 시작하기 →

이것도 배워보세요