도메인과 DNS가 등장한 이유
-
인터넷 초창기에는 모든 컴퓨터가 IP 주소로만 통신했다.
-
IP 주소는 숫자 나열이라 사람이 기억하기 어렵고, 서버 이전 시 주소가 바뀌면 모든 사용자가 새 주소를 다시 알아야 했다.
-
이 문제를 해결하기 위해 사람이 읽을 수 있는 이름을 IP 주소로 변환하는 시스템이 필요해졌다.
-
초기엔 ARPANET이
hosts.txt파일 하나로 이름-IP 매핑을 관리했지만, 호스트 수가 폭발적으로 늘면서 중앙 파일 방식은 한계에 부딪혔다. -
1983년, Paul Mockapetris가 이를 분산형 계층 구조로 해결한 DNS(Domain Name System)를 설계했다.
도메인의 계층 구조
-
도메인은 오른쪽에서 왼쪽으로 읽는 계층 구조를 가진다.
-
blog.example.com.에서 가장 오른쪽.은 루트(root)이고, 그 다음이 TLD(Top-Level Domain)인com, 그 다음이 SLD(Second-Level Domain)인example, 마지막이 서브도메인인blog다. -
이 계층은 단순한 표기 규칙이 아니라, DNS 질의가 실제로 탐색하는 물리적 경로이기도 하다.
-
루트 서버는 13개의 "논리적 이름(A~M)"으로 정의되어 있으며, 실제로는 전 세계에 수백 개 이상의 Anycast 인스턴스로 분산되어 운영된다.
-
TLD 서버는
.com,.kr같은 최상위 도메인 하위의 권한 있는 네임서버 위치를 알고 있다. -
도메인을 구매하면 도메인 등록 기관이 TLD 서버에 "이 도메인의 권한 있는 네임서버는 여기"라고 등록하는 과정이 자동으로 이루어진다.
서브도메인
-
서브도메인은 루트 도메인 앞에 점(
.)으로 구분된 레이블을 붙인 것이다. -
www,api,blog,dev처럼 기능이나 환경을 구분하는 용도로 흔히 쓰인다.www.example.com // 메인 웹사이트 api.example.com // 데이터 통신용 백엔드 서버 blog.example.com // 블로그 혹은 콘텐츠 페이지 shop.example.com // 쇼핑몰/커머스 기능 -
만드는 방법은, 네임서버에 새 A 레코드나 CNAME을 추가하면 그 순간 서브도메인이 생긴다.
-
특정 서브도메인의 DNS 권한을 아예 다른 네임서버로 위임하는 것도 가능하며, 이를 Zone Delegation이라 한다.
-
별도 구매가 필요 없고, 루트 도메인만 있으면 서브도메인은 무제한으로 만들 수 있다.
-
예를 들어
internal.example.com의 NS 레코드를 사내 네임서버로 지정하면, 해당 서브도메인 하위의 모든 레코드를 사내에서 독립적으로 관리할 수 있다. -
와일드카드 서브도메인(
*.example.com)을 A 레코드나 CNAME으로 설정하면, 정의되지 않은 모든 서브도메인 질의를 하나의 IP나 도메인으로 수렴시킬 수 있다. -
이는 SaaS 서비스에서 고객별 서브도메인(
customer1.saas.com)을 동적으로 처리할 때 자주 활용된다.
네임서버란 무엇인가
-
네임서버는 특정 도메인에 대한 정보를 갖고 있는 서버다.
-
쉽게 말해, 누군가
example.com의 IP가 뭐냐고 물어봤을 때 "그건 내가 대답할 수 있어"라고 하는 서버가 네임서버다. -
도메인을 Gabia나 Namecheap 같은 곳에서 구매하면, 그 업체가 기본 네임서버를 제공한다.
-
예를 들어 Cloudflare로 옮기면
ns1.cloudflare.com같은 네임서버가example.com에 대한 모든 질문에 답하게 된다. -
즉, 네임서버를 바꾼다는 건 "이 도메인에 대한 답변 권한을 다른 서버로 넘긴다"는 뜻이다.
권한 있는 네임서버란
-
DNS 서버에는 종류가 여럿 있는데, 그 중에서 "최종 정답을 갖고 있는 서버"를 권한 있는 네임서버라고 한다.
-
다른 서버들은 중간에서 길을 안내하는 역할이지만, 권한 있는 네임서버만이 실제 레코드를 보유하고 응답한다.
루트 서버와 TLD 서버가 "알고 있는 것"
-
루트 서버와 TLD 서버는 실제 IP 주소를 알고 있는 게 아니다.
-
이들이 알고 있는 건 딱 하나, "다음에 누구한테 물어봐야 하는가"다.
-
구체적으로, 루트 서버는
.com을 담당하는 TLD 서버가 어디 있는지만 알고 있다. -
TLD 서버는
example.com의 권한 있는 네임서버가 어디 있는지만 알고 있다. -
권한 있는 네임서버에 도달해야 비로소 실제 IP 주소를 얻을 수 있다.
DNS 질의의 실제 흐름
-
브라우저에
blog.example.com을 입력하면, 운영체제는 먼저 로컬 캐시와/etc/hosts를 확인한다. -
캐시에 없으면 리졸버에 질의를 위임한다.
-
리졸버는 보통 ISP나
8.8.8.8같은 공개 DNS 서버가 담당하며, 대신 재귀적으로 답을 찾아주는 역할이다. -
리졸버는 루트 서버 → TLD 서버 → 권한 있는 네임서버 순으로 탐색해 최종 IP를 가져온다.
-
예를 들어, 루트 서버는 "나는
.comTLD 서버 주소만 알아, 거기 가봐"라고 응답하고, TLD 서버는 "example.com의 네임서버는ns1.cloudflare.com이야, 거기 물어봐"라고 응답한다. -
마지막으로 리졸버가
ns1.cloudflare.com에 물어보면, 이 서버가 드디어 "IP는93.184.216.34야"라고 최종 답변을 준다. -
이 전체 탐색 과정을 재귀 질의라 하며, 최종 답을 찾으면 리졸버는 결과를 캐싱하고 클라이언트에 반환한다.
-
이후 동일 도메인 질의는 캐시에서 바로 응답되므로, 루트까지 올라가지 않는다.
네임서버와 도메인 위임
-
네임서버는 특정 도메인 영역에 대한 DNS 레코드를 보관하고 응답하는 서버다.
-
도메인을 구매한 뒤 가장 먼저 해야 할 설정이 "어떤 네임서버를 쓸 것인가"를 지정하는 것이다.
-
예를 들어 Cloudflare로 네임서버를 바꾸면,
example.com에 대한 DNS 응답 권한이 Cloudflare 서버로 위임된다. -
이를 NS(Name Server) 레코드라 하며, TLD 서버에도 동일하게 등록되어야 위임이 완성된다.
-
네임서버 변경은 전파에 시간이 걸리고, 잘못 설정하면 도메인 전체가 응답 불가 상태가 되므로 가장 신중하게 다뤄야 할 설정이다.
레코드란 무엇인가
-
레코드는 권한 있는 네임서버 안에 저장된 "한 줄짜리 정보"다.
-
엑셀 시트에 비유하면, 도메인이 시트 이름이고 레코드는 그 안의 각 행이다.
-
각 레코드는 "이름 / 타입 / 값 / TTL" 네 가지 정보를 담고 있다.
-
예를 들어 A 레코드는 도메인 이름을 IPv4 주소로 연결하는 타입이다.
이름 타입 값 example.com A 93.184.216.34 blog.example.com A 93.184.216.99 -
이 레코드가 있으면
example.com으로 접속할 때93.184.216.34로 연결된다.
DNS 레코드의 종류와 역할
-
권한 있는 네임서버 안에는 실제 응답 데이터가 레코드 형태로 저장된다.
-
A 레코드는 도메인을 IPv4 주소로 매핑하는 가장 기본적인 레코드다.
-
AAAA 레코드는 동일한 역할을 IPv6 주소에 대해 수행한다.
-
CNAME(Canonical Name) 레코드는 도메인을 IP가 아닌 다른 도메인 이름으로 매핑한다.
-
CNAME을 쓰면 실제 IP를 몰라도 되고, 대상 도메인의 IP가 바뀌어도 CNAME은 수정할 필요가 없다는 장점이 있다.
-
다만 CNAME은 루트 도메인(
example.com자체)에는 사용할 수 없고, 반드시 서브도메인에만 사용해야 한다는 제약이 있다. -
이는 RFC 1912 스펙으로, 루트 도메인에 CNAME을 두면 같은 이름의 다른 레코드(MX, NS 등)와 충돌이 발생하기 때문이다.
-
일부 DNS 제공자(Cloudflare 등)는 이를 우회하기 위해 CNAME을 내부적으로 A 레코드로 자동 변환하는 CNAME Flattening을 지원한다.
-
MX(Mail Exchange) 레코드는 해당 도메인으로 오는 이메일을 어느 메일 서버로 전달할지 지정한다.
-
TXT 레코드는 임의의 문자열을 저장하며, 도메인 소유권 인증이나 SPF/DKIM 같은 이메일 보안 설정에 주로 쓰인다.
-
예를 들어 Google Search Console이나 AWS ACM이 도메인 소유를 확인할 때 특정 값의 TXT 레코드를 추가하라고 요구하는 것이 대표적인 사례다.
CNAME 레코드란 무엇인가
-
A 레코드는 "도메인 → IP"로 연결하지만, CNAME은 "도메인 → 다른 도메인"으로 연결한다.
-
왜 그럴까?
-
예시를 들어보면, AWS나 Vercel 같은 서비스에 배포하면 그 서비스가 이미 자기들 도메인을 갖고 있다.
Vercel이 준 주소: my-app-xyz.vercel.app 내가 쓰고 싶은 주소: blog.example.com -
이때 Vercel이 준 주소의 IP는 Vercel이 언제든 바꿀 수 있어서, 내가 직접 IP를 A 레코드로 등록하면 언젠가 연결이 끊긴다.
-
대신 CNAME으로 아래처럼 설정하면, IP가 바뀌어도 내가 수정할 게 없다.
이름 타입 값 blog.example.com CNAME my-app-xyz.vercel.app -
브라우저가
blog.example.com에 접속하면 DNS는 "저건my-app-xyz.vercel.app을 봐"라고 알려준다. -
그러면 다시
my-app-xyz.vercel.app의 IP를 찾아 최종 연결한다. -
결국 CNAME은 "나는 여기로 포워딩해줄게, IP는 저 친구한테 물어봐"라는 역할이다.
CNAME을 루트 도메인에 쓸 수 없는 이유
-
blog.example.com에는 CNAME을 써도 되지만,example.com자체에는 쓸 수 없다. -
이유를 이해하려면 먼저 루트 도메인엔 반드시 다른 레코드들이 함께 있어야 한다는 걸 알아야 한다.
-
example.com에는 이메일을 받기 위한 MX 레코드, 네임서버를 지정하는 NS 레코드가 반드시 존재한다.example.com NS ns1.cloudflare.com example.com MX mail.example.com example.com A 93.184.216.34 ← 이 자리에 CNAME을 넣으면 문제 -
DNS 스펙상, CNAME이 있는 이름에는 다른 레코드가 공존할 수 없다.
-
왜냐하면 CNAME은 "이 이름 자체를 다른 이름으로 대체해라"는 의미이기 때문이다.
-
example.com이 CNAME이라면 "이 이름은 실제로 다른 이름이야"가 되는데, 동시에 NS나 MX도example.com이름으로 존재하면 어떤 게 진짜 이름인지 모순이 생긴다. -
그래서 루트 도메인에는 CNAME을 허용하지 않는 것이 DNS 표준이다.
-
Cloudflare는 이 한계를 CNAME Flattening으로 우회하는데, 겉으로는 CNAME처럼 설정하지만 내부적으로 IP를 미리 조회해 A 레코드처럼 응답한다.
TTL과 캐싱 전략
-
TTL(Time To Live)은 DNS 레코드가 리졸버나 클라이언트 캐시에 얼마나 오래 유지될지를 초 단위로 지정하는 값이다.
-
즉, "이 레코드 정보를 몇 초 동안 믿어도 되는가"를 알려주는 숫자이다.
-
TTL이 3600이면 해당 레코드는 최대 1시간 동안 캐싱되며, 그 사이에 레코드를 변경해도 캐싱된 곳은 변경 사실을 모른다.
-
TTL이 낮을수록 변경이 빠르게 반영되지만, 리졸버가 네임서버에 더 자주 질의하므로 트래픽과 응답 지연이 늘 수 있다.
DNS 전파
-
전 세계 리졸버들이 각자의 캐시에 보관하던 구 레코드가 TTL 만료 후 새로운 레코드를 다시 질의하는 과정이 시차를 두고 일어나는 것이다.
-
따라서 전파 시간은 TTL에 직접 종속되며, 레코드 변경 직전 TTL이 높았다면 전파가 오래 걸릴 수밖에 없다.
-
내 컴퓨터에서 이미 반영됐어도 다른 리졸버에는 아직 구 레코드가 캐싱되어 있을 수 있어, 지역마다 다른 IP로 응답받는 상황이 발생한다.
-
그래서 도메인 설정을 바꾸기 전에 TTL을 300(5분)으로 낮춰두면, 변경 후 빠르게 반영되게 할 수 있다.
-
dig @8.8.8.8 example.com처럼 특정 리졸버를 지정해 질의하면 어느 리졸버에서 무슨 값을 보고 있는지 직접 확인할 수 있다. -
권한 있는 네임서버에 직접 질의하면 TTL이나 리졸버 캐시와 무관하게 현재 실제 레코드 값을 즉시 확인할 수 있다.