이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.
- DNS TTL이 “전파 시간”이 아니라 resolver cache 만료 시간에 가까운 이유는 무엇인가?
- 도메인 이전, LB 교체, CDN 전환, 장애 failover에서 TTL을 어떻게 낮추고 되돌리는가?
- TTL이 끝났는데도 일부 사용자가 옛 IP를 보는 상황을 어떻게 설명하고 대응하는가?
개요
DNS TTL은 record가 recursive resolver나 클라이언트 cache에 머물 수 있는 시간이다. 실무에서 흔히 “DNS 전파”라고 부르지만, 정확히는 authoritative DNS의 새 값이 여러 cache에서 언제 관찰되기 시작하는가의 문제다.
- TTL은 record가 resolver cache에 머물 수 있는 시간이다.
- 서비스 이전 전 TTL을 낮추고, 이전 후 안정화되면 다시 올리는 전략이 필요하다.
- 일부 클라이언트는 OS, 브라우저, JVM, container DNS cache 때문에 기대보다 오래 이전 IP를 볼 수 있다.
왜 백엔드 개발자가 알아야 하는가
도메인 이전과 failover는 인프라 작업처럼 보여도 백엔드 운영에 직접 영향을 준다. TTL을 모르면 “새 서버 배포 완료”라고 생각한 뒤에도 옛 서버로 요청이 들어오는 이유를 설명하지 못한다.
- old/new origin을 동시에 운영해야 하는 기간을 산정할 수 있다.
- TTL을 낮추는 시점, 실제 변경 시점, TTL을 다시 올리는 시점을 변경 계획에 넣을 수 있다.
- 일부 사용자만 옛 IP를 보는 장애를 앱 배포 실패로 오해하지 않을 수 있다.
- rollback이 DNS만 되돌리면 끝인지, old 서버와 인증서와 DB 호환성도 살아 있어야 하는지 판단할 수 있다.
요청 흐름에서의 위치
TTL은 DNS 조회 결과와 실제 traffic 전환 사이의 시간차를 만든다.
T-48h TTL 3600 → 60으로 낮춤
T record old LB → new LB 변경
T+0m 일부 resolver는 새 값
T+60s 대부분의 정상 cache는 새 값
T+? OS/JVM/브라우저/비정상 resolver는 더 오래 old 값 가능
T+1h old LB/origin 제거 가능 여부 판단TTL 전략은 “DNS만 바꾸는 일”이 아니라 old/new 양쪽을 얼마 동안 동시에 정상 운영할지 정하는 작업이다.
원리
authoritative DNS가 새 값을 들고 있어도 recursive resolver가 이전 값을 cache하고 있으면 사용자는 옛 값을 받을 수 있다. TTL은 이 cache가 유효하다고 여길 수 있는 시간이다.
다만 현실은 더 복잡하다.
- 일부 resolver는 최소 TTL을 적용하거나 너무 낮은 TTL을 존중하지 않을 수 있다.
- negative caching 때문에
NXDOMAIN도 일정 시간 cache될 수 있다. - 앱 프로세스나 JVM은 OS resolver와 별도로 DNS 결과를 cache할 수 있다.
- connection pool이 이미 열린 TCP 연결을 계속 쓰면 DNS가 바뀌어도 즉시 새 IP로 가지 않는다.
- CDN이나 managed LB의 DNS 이름은 provider가 내부에서 IP를 계속 바꾸므로 직접 IP를 고정하면 안 된다.
핵심 판단 기준
- DNS 이전 전에는 TTL을 낮추는 작업을 “충분히 이전 TTL만큼” 먼저 해 둔다.
- old와 new가 동시에 요청을 처리해도 같은 사용자 경험이 나오는지 확인한다.
- DB schema, session, cookie, OAuth redirect, callback URL이 old/new 양쪽에서 호환되는지 본다.
- rollback record와 rollback 대상 인프라가 살아 있는지 확인한다.
- 변경 후에는 authoritative DNS가 아니라 여러 recursive resolver와 실제 client location에서 관찰한다.
실무에서 자주 만나는 문제
- DNS 변경 직후 모든 traffic이 새 LB로 갈 것이라고 생각한다.
- JVM DNS cache와 container DNS cache를 잊는다.
- rollback 값을 미리 준비하지 않는다.
- old origin을 너무 빨리 내려 일부 사용자가 502/connection refused를 만난다.
- TTL을 60초로 낮췄지만 하루 전에 낮추지 않아 이전 1시간 TTL cache가 남아 있다.
- health check는 new LB만 보고 있고 old LB의 인증서 만료를 놓친다.
- DNS failover를 HA 전략으로 쓰면서 RTO를 초 단위로 기대한다.
- CDN 앞단에서 origin DNS를 바꿨는데 CDN cache와 origin keepalive가 남아 있어 전환이 늦게 보인다.
TTL 문제는 배포 직후보다 “전환이 끝났다고 생각한 시점”에 터지는 경우가 많다. 특히 old 인프라 제거, 인증서 폐기, firewall rule 삭제, DB 호환성 제거가 너무 빠르면 늦게 도착한 요청이 실패한다.
디버깅 방법
- 여러 resolver에서
dig @8.8.8.8,dig @1.1.1.1로 비교한다. - old/new IP 모두에서 health와 TLS를 확인한다.
- 배포 기간 동안 old origin도 일정 시간 유지한다.
- authoritative DNS와 recursive resolver 결과를 분리한다.
- 앱 outbound DNS라면 프로세스 재시작 전후, connection pool 재생성 전후를 비교한다.
- access log를 old/new 양쪽에서 보며 실제 traffic 비율을 확인한다.
# authoritative DNS가 이미 새 값을 들고 있는지 확인
dig +trace api.example.com
# 주요 public resolver의 cache 상태 비교
dig @1.1.1.1 api.example.com A +noall +answer
dig @8.8.8.8 api.example.com A +noall +answer
# old/new 주소가 모두 서비스 가능한지 확인
curl -v --resolve "api.example.com:443:OLD_IP" https://api.example.com/health
curl -v --resolve "api.example.com:443:NEW_IP" https://api.example.com/health전환 중에는 “새 IP가 보인다”보다 “옛 IP로 가도 아직 정상이다”가 더 중요할 때가 많다.
코드로 확인하기
도메인 이전 전후 smoke test는 old/new 양쪽을 모두 때려야 한다.
#!/usr/bin/env bash
set -euo pipefail
HOST="api.example.com"
OLD_IP="203.0.113.10"
NEW_IP="203.0.113.20"
for IP in "$OLD_IP" "$NEW_IP"; do
echo "== $HOST via $IP =="
curl -fsS --resolve "${HOST}:443:${IP}" "https://${HOST}/health" \
-w "\nstatus=%{http_code} connect=%{time_connect} tls=%{time_appconnect} total=%{time_total}\n"
done이 스크립트가 통과해야 DNS 전환 중 traffic split을 견딜 수 있다. 실패하면 DNS 변경보다 먼저 old/new 환경의 TLS, Host routing, health, 데이터 호환성을 맞춘다.
주니어가 자주 하는 오해
- DNS record를 바꾸면 바로 모든 사용자가 새 서버를 본다고 생각한다.
- resolver와 client cache가 이전 값을 들고 있을 수 있다.
- TTL을 낮추면 과거 cache도 즉시 짧아진다고 생각한다.
- 이미 긴 TTL로 cache된 값은 그 TTL이 끝날 때까지 남을 수 있다.
- DNS rollback은 항상 빠르다고 생각한다.
- rollback record도 다시 cache를 거치므로 old/new 양쪽 운영이 필요하다.
- DNS failover로 애플리케이션 장애를 즉시 숨길 수 있다고 생각한다.
- DNS는 초 단위 health routing 도구가 아니라 cache가 있는 이름 해석 계층이다.
시니어의 설계 판단 기준
- DNS 전환은
prepare → lower TTL → dual-run → switch → observe → restore TTL → retire old단계로 운영한다. - 전환 중 old/new 양쪽의 인증서, WAF rule, rate limit, log, alert를 유지한다.
- low TTL은 빠른 변경에 유리하지만 authoritative DNS와 resolver query load를 늘릴 수 있다.
- session affinity, sticky cookie, OAuth callback, webhook endpoint는 traffic split에 특히 취약하므로 별도 검증한다.
- 전환 종료 조건은 시간이 아니라 old/new traffic 비율, error rate, resolver 샘플, 고객 영향으로 정한다.
인프라 협업 포인트
- DNS 변경 요청에는 현재 record, 목표 record, 현재 TTL, 낮출 TTL, 변경 시각, rollback 값, old 제거 시각을 포함한다.
- 인프라 팀에는 old/new IP나 LB DNS 이름, health endpoint, Host header, 인증서 범위를 같이 전달한다.
- 장애 중에는 “어떤 resolver에서 어떤 값이 보이는지”와 “그 값으로 접속하면 어떤 응답이 나는지”를 나눠 공유한다.
- 인프라 담당자는 DNS 변경이 작아 보여도 provider 장애, 권한 DNS 부하, CDN origin, 인증서 자동화 영향을 같이 봐야 한다.
실전 팁
- DNS 전환 전에는 access log에 서버 식별자나 deployment id가 보이게 해 두면 traffic split을 확인하기 쉽다.
- old 인프라는 “TTL의 몇 배 + 실제 traffic 0 확인” 뒤에 내린다.
- outbound dependency의 DNS가 바뀌는 경우 HTTP client connection pool 재생성이나 앱 재시작이 필요한지 확인한다.
- 개인 프로젝트에서도 도메인 이전은 야간에 혼자 하지 말고 rollback record와 old 서버 유지 시간을 정해 둔다.
위험 신호!
- DNS 변경 계획에 old 인프라 유지 시간이 없다.
- TTL을 낮추는 작업과 record 변경을 같은 시각에 한다.
- rollback record가 문서에 없다.
- old/new 중 한쪽만 health check와 인증서가 정상이다.
- “TTL 60초니까 1분 뒤에 끝”이라고 선언한다.
확인 질문
확인 질문
- DNS TTL을 낮추는 작업은 왜 실제 변경보다 먼저 해야 하는가?
- 이미 긴 TTL로 cache된 값은 TTL이 끝날 때까지 남으므로, 변경 전에 낮은 TTL이 resolver에 퍼질 시간을 줘야 하기 때문이다.
- DNS 전환 중 old 서버를 바로 내리면 위험한 이유는 무엇인가?
- 일부 resolver나 client가 여전히 old IP를 볼 수 있어 connection refused, TLS 실패, 502가 발생할 수 있기 때문이다.
- TTL이 낮아도 DNS failover가 즉시 장애 조치가 되지 않는 이유는 무엇인가?
- resolver cache, client cache, connection pool, provider 정책 때문에 모든 요청이 즉시 새 값으로 이동하지 않기 때문이다.