왜 문제가 되는가
글로벌 사용자를 대상으로 하는 서비스에서 단일 리전 DNS와 유니캐스트 구성은 물리적 거리에 비례한 지연을 그대로 노출한다. 서울 사용자가 버지니아 리전의 권한 있는 네임서버(authoritative NS)에 질의하면 RTT만 수백 ms가 추가되고, 이는 첫 페이지 로딩의 체감 속도를 좌우한다. 또한 특정 노드에 장애가 나면 해당 NS를 바라보던 사용자 전체가 해석 실패를 겪는다. Anycast와 지리 기반 라우팅은 이 두 문제(지연, 가용성)를 네트워크 계층에서 동시에 완화하려는 접근이다.
Anycast의 동작 원리
Anycast는 동일한 IP 프리픽스를 여러 지리적 위치의 노드에서 BGP로 광고하는 방식이다. 라우터는 BGP 최적 경로 선택 로직(AS-path 길이, local-pref 등)에 따라 가장 가까운 노드로 패킷을 전달한다. 즉 사용자는 하나의 IP만 알면 되고, 실제 도달 지점은 네트워크 토폴로지가 결정한다. DNS 질의처럼 짧고 상태 없는(stateless) UDP 트래픽에 특히 적합하다.
# 각 PoP의 라우터에서 동일 프리픽스를 광고 (예: BIRD)
protocol bgp upstream {
local as 65010;
neighbor 203.0.113.1 as 64500;
ipv4 {
import none;
export filter {
if net = 192.0.2.0/24 then accept; # Anycast VIP
reject;
};
};
}
노드가 죽으면 BGP 세션이 끊기며 해당 프리픽스 광고가 철회되고, 트래픽은 자동으로 차선 노드로 수렴한다. 이 헬스체크-철회 연동이 Anycast 가용성의 핵심이다.
지리 기반 라우팅과의 차이
Anycast가 "네트워크 거리" 기준이라면, GeoDNS는 질의 출발지의 지리 정보(주로 EDNS Client Subnet, ECS)를 보고 응답 레코드 자체를 다르게 준다. 둘은 배타적이지 않고 보완적으로 쓰인다.
| 구분 | Anycast | GeoDNS (지리 기반) |
|---|---|---|
| 기준 | BGP 경로 | 클라이언트 위치/ECS |
| 제어 단위 | 라우팅 계층 | 레코드 응답 |
| 장애 절체 | 초 단위(BGP 수렴) | TTL에 종속 |
| 정밀도 | 토폴로지 의존 | 국가/리전 단위 정책 |
GeoDNS 설정 예시
PowerDNS의 geoip 백엔드는 클라이언트 위치별로 다른 백엔드 IP를 반환한다. ECS를 신뢰할지 여부를 명시하는 것이 중요하다.
# pdns geoip domains.yaml
domains:
- domain: api.example.com
ttl: 60
records:
api.example.com:
- a: "%co.address" # 국가별 매핑 결과 치환
services:
"api.example.com":
default: "us-east.backends"
"kr,jp,sg": "ap-northeast.backends"
"de,fr,nl": "eu-central.backends"
TTL을 60초 수준으로 낮추면 정책 변경과 장애 절체 반영이 빨라지지만, 캐시 리졸버의 질의 부하와 미스율이 올라간다. 지연에 민감한 A/AAAA 레코드는 30~60초, 안정적인 NS/MX는 길게 가져가는 분리 전략이 실무적이다.
헬스체크와 자동 절체
지리 라우팅만으로는 특정 리전 백엔드가 죽었을 때 사용자를 죽은 리전에 계속 보낼 수 있다. 헬스체크 결과를 레코드 풀에 반영하는 로직이 반드시 필요하다.
import requests
POOLS = {
"ap-northeast": ["10.1.0.10", "10.1.0.11"],
"us-east": ["10.2.0.10"],
}
def healthy(ip):
try:
r = requests.get(f"http://{ip}:8080/healthz", timeout=1.5)
return r.status_code == 200
except requests.RequestException:
return False
def active_pool(region):
alive = [ip for ip in POOLS[region] if healthy(ip)]
# 리전 전체 다운이면 상위 폴백 리전 반환
return alive or POOLS["us-east"]
운영 시 주의점
- ECS 신뢰 문제: 공용 리졸버(8.8.8.8 등)는 ECS를 붙이지만, 미지원 리졸버는 리졸버 위치 기준으로 판단되어 오분류가 생긴다. GeoIP DB는 부정확할 수 있으므로 국가 단위 이상으로 세분화하지 않는 편이 안전하다.
- BGP 절체 지연: Anycast 수렴은 초 단위지만 진행 중인 TCP 세션은 다른 노드로 옮겨가면 끊긴다. 상태 없는 DNS엔 문제없지만 Anycast를 TCP 서비스에 쓸 땐 세션 유지 설계가 필요하다.
- 관측성: 어느 PoP가 어떤 트래픽을 받는지 로그에 노드 식별자를 남겨야 한다. Anycast 특성상 문제 재현이 위치에 종속되므로, PoP별 질의량·NXDOMAIN·응답 지연을 분리 수집한다.
- TTL과 캐시: 절체 속도와 캐시 효율은 상충한다. 정책상 반드시 필요한 만큼만 TTL을 낮춘다.
정리하면 Anycast는 가용성과 네트워크 지연을, GeoDNS는 정책적 라우팅을 담당하고, 헬스체크가 둘을 실제 운영 가능한 시스템으로 묶는다. 세 요소를 각각의 역할대로 조합하되 TTL과 ECS의 한계를 전제로 설계하는 것이 핵심이다.