sol 개발 블로그 로고
Published on

AWS Route 53 정리

Authors
  • avatar
    Name
    Chan Sol OH
    Twitter

목차

이번 포스팅을 보기 앞서 미리 작성한 DNSAWS HTTPS 연결 설정를 보는 것을 추천한다. DNS, https 개념과 AWS Route 53에서 도메인을 사서 HTTPS 연결하는 과정을 볼 수 있다.

Route 53 개요

DNS에 대한 완전한 제어를 할 수 있다. 클라이언트다 public ip의 EC2 인스턴스에 접근할 때 Route53에 도메인 이름에 맞는 IP 주소를 물어봐서 EC2에 접속할 수 있다. Route 53은 로드밸런서처럼 자원의 health 체크할 수 있다.

Route 53 - 레코드

각 레코드에는 아래 내용이 포함된다.

  1. 도메인,서브 도메인 이름 (ex, example.com)
  2. 레코드 타빙 (ex A, AAAA, CNAME, NS)
  3. value (ex 123.455.754.113)
  4. 라우팅 정책 : Route 53이 쿼리에 응답하는 방식
  • A : IPv4 IP와 호스트 이름을 단순 맵핑
  • AAAA : IPv6 IP와 호스트 이름을 단수 맵핑
  • CNAME : 호스트 이름을 다른 호스트 이름에 맵핑, 대상 호스트 이름은 A,AAAA 레코드이고, top node에는 CNAME을 쓸 수 없다. 예를 들어 example.com에 대한 CNAME은 생성할 수 없지만, www.example.com은 생성할 수 있다.
  • NS : 호스팅 존의 이름 서버. 도메인에 트래픽이 어떻게 라우팅되어야하는지 제어한다.

Hosted Zones

Hosted Zone은 도메인과 서브 도메인으로 가능 트래픽의 라우팅 방식을 정의한다.

  • Public Hosted Zone
    • public 도메인을 구매했다면 public hosted zone을 만들 수 있다.
    • Public hosted zone의 도메인은 쿼리로 IP 주소를 얻을 수 있다.
  • Private Hosted Zone
    • 공개되지 않는 도메인 이름 지원
    • VPC 내부에서만 URL을 해석할 수 있다.
    • 비공개 URL이기 때문에 회사 내부에서만 사용할 수 있다.

Route 53에서 제공하는 모든 hosted zone은 매달 0.5$씩 지불해야한다.

DNS 쿼리 캐싱을 위한 TTL

TTL은 ElastiCache에서 소개한 것처럼 캐싱 데이터가 유효한 기간을 정하고 그 기간 안에선 별다른 쿼리 없이 캐싱 데이터를 사용할 수 있게한다. 처음 클라이언트가 DNS에 IP 주소를 쿼리했다면 TTL 동안 클라이언트에 도메인에 맞는 IP 주소가 저장된다. 이러면 DNS에 다시 쿼리하지 않아도 된다.

TTL이 너무 길면 레코드가 바뀌었을 때 바로바로 업데이트가 안되고 오래된 IP 주소에 사람들은 요청할 것이다. 반대로 너무 짧으면 Route53에 요청이 자주 일어나서 비용이 발생할 것이다. 그래서 보통 레코드를 바꿀 때 TTL을 짧게하고 사람들이 다 업데이트했다고 하면 TTL을 다시 늘리는 방식의 전략을 사용한다.

여러 Region에서 EC2

ec2-user-data.sh
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
# updated script to make it work with Amazon Linux 2023
CHECK_IMDSV1_ENABLED=$(curl -s -o /dev/null -w "%{http_code}" http://169.254.169.254/latest/meta-data/)
if [[ "$CHECK_IMDSV1_ENABLED" -eq 200 ]]
then
    EC2_AVAIL_ZONE="$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)"
else
    EC2_AVAIL_ZONE="$(TOKEN=`curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` && curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/placement/availability-zone)"
fi
echo "<h1>Hello world from $(hostname -f) in AZ $EC2_AVAIL_ZONE </h1>" > /var/www/html/index.html

위와 같은 user-data를 설정한 Ec2를 3개의 서로 다른 region에 설정했다. 나는 서울, 도쿄, 캐나다 3곳에서 EC2를 생성했다. 다음으로는 로드밸런서를 생성한다. 로드밸런서를 생성할 때 인스턴스들의 대상그룹을 생성해야한다.

3개의 EC2와 캐나다 EC2와 연결한 ALB의 공인 ip와 AZ를 나타낸 표는 다음과 같다. ALB는 캐나다 EC2와 연결했기 때문에 EC2의 AZ가 나타나는 것을 볼 수 있다.

route 53 다중 ec2

TTL로 인한 문제 만들어 보기

TTL이 만료되지 않으면 이전 IP 주소를 캐싱하고 사용하기 때무에 아래처럼 레코드를 바꿔도 동일한 AZ의 EC2로 이동할 수 있다. 실험에서 a.epicktrees.net의 TTL은 100초다.

ttl 이내 상황

위 그림에서 레코드를 수정한 후 100초 후 아래 그림으로 바뀐다. 서비스를 하는 동안이라면 100초 동안 클라이언트들은 오래된 IP에 접근해서 다른 사이트에 접속하게 될 것이다.

ttl 이후 상황

CNAME vs Alias

  • CNAME

    • CNAME은 루트 도메인에 쓰지 못하지만 호스트 이름에 다른 도메인을 포인팅할 수 있다.
    • epicktrees.net의 앞에 뭔가 붙여야한다.
  • Alias (별칭 레코드)

    • 호스트 이름에 AWS 자원(ELB의 DNS 같은 것)을 포인팅할 수 있다.
      • ELB, CloudFront, API GateWay, Elastic Beanstalk, S3 Websites(버킷 X), VPC, Global Accelerator, Route 53 Recode
      • EC2 DNS 이름에 대해선 Alias를 설정할 수 없다.
    • 또한 AWS 자원의 IP가 바뀌면 별칭 레코드는 이걸 바로 인식한다.
    • 루트, 비루트 도메인 모두 가능! epicktrees.net에도 적용가능하다.
    • 무료!, Native 상태 확인 가능, TTL 설정할 수 없이 AWS가 자동으로 설정한다.

아래 이미지는 alias(별칭)를 이용해 ALB로 라우팅하는 설정이다.

alias를 이용한 elb 라우팅

Route53 라우팅 정책

여기서 라우팅은 트래픽 라우팅이 아닌 DNS 관점의 라우팅이다. DNS는 DNS 쿼리에만 반응하고 클라이언트는 HTTP 쿼리를 어떻게 처리해야하는지 알 수 있다. Route53의 라우팅 정책은 다음과 같다.

  • Simple
    • 트래픽을 단일 리소스로 보내는 방식. Alias를 사용하면 오직 한 AWS 서비스로만 설정 가능
    • IP와 도메인 이름을 N 대 1 맵핑
    • 클라이언트가 IP를 여러개 받으면 아무거나 고른다.
  • Weighted (가중치 기반 규칙)
    • 요청의 일부를 특정 리소스로 보낼 수 있다. 각 레코드로 보내지는 트래픽의 비율은 모든 레코드의 가중치특정 레코드의 가중치를 나눈 값이다. 그래서 합이 100이 아닐 수 있다. 또한 특정 레코드의 가중치가 0이면 그 레코드론 라우팅하지 않고, 전부 0이 되면 동일한 가중치로 전부 보낸다.
    • DNS 레코드들은 동일한 이름과 유형을 가져야한다. 이렇게 동일 이름, 유형을 가진 여러 레코드를 만들고 각 가중치마다 라우팅을 분산한다.
    • 다른 지역의 로드밸런서들을 사용하거나 새로운 애플리케이션을 적은 트래픽으로 테스트하는 경우에 사용한다.
  • Failover (장애 조치 규칙)
    • Primary EC2와 Secondary EC2(재해 복구용)이 있을 때, Route 53은 Primary EC2에 Health Check를 의무적으로 한다.
    • 재해가 일어나면 자동으로 Secondary EC2로 장애조치하며 결과를 보낸다. 이때 Primary와 Secondary는 1대1로 짝지어진다.
    • 클라이언트가 DNS 쿼리를 Route53에 날리면 정상으로 판단되는 리소스를 보내준다.
  • Latency based (지연 규칙)
    • 지연 시간이 가장 짧은, 가장 가까운 리소스로 리다이렉팅하는 정책
    • 지연 시간은 유저와 AWS region 사이 트래픽이 걸리는 시간을 기반으로 측정. 예를들어 독일 유저와 미국 리전 사이가 가장 가깝다면 미국 리전으로 리다이렉트된다.
    • 마치 CDN처럼 유저와 가까운 리소스로 Route53이 리다이렉팅해준다.
  • Geolocation (지리 위치 규칙)
    • Latency based와 달리 사용자의 실제 위치를 기반으로 라우팅한다.
    • 위치에 맞는 레코드가 없을 수 있기에 기본 레코드를 생성해야한다.
    • 콘텐츠 분산, 웹 사이트 로컬라이즈, 로드 밸런싱 등이 있다.
    • Latency based로 하면 한국인데 일본이 더 가까우면 일본 리소스로 라우팅될 수 있기에 로컬라이즈가 중요하면 좋은 정책이다.
  • Multi-Value Answer (다중 응답 규칙)
    • Rotue 53은 다중 값과 정상상태의 다중 리소스를 응답한다.
    • 한 다중 값 쿼리에 최대 8개의 정상 레코드가 반환된다.
    • 클라이언트 측면의 로드 밸런싱이다. 여러 리소스로 라우팅하는데 ELB와 유사해보이지만 ELB를 대체할 수 없다.
    • 다중 값 응답 규칙에서 제공하는 리소스는 정상상태임을 보장하지만, Simple(단순 라우팅 정책)에서 제공하는 리소스는 상태 검사를 안하기 때문에 비정상일 수 있다.
  • Geoproximity (지리 근접 규칙) (using Route 53 Traffic Flow feature)
    • 리소스와 사용자의 지리적 위치를 기반으로 트래픽을 라우팅
    • 편향(bias가 양수면 터 많은 트래픽 라우팅, 음수면 더 적게)에 따라 리소스가 커버하는 범위가 결정된다.
    • 리소스가 AWS 서비스라면 Region을 지정(자동으로 라우팅), 프라이빗 온프레미스 데이터 센터라면 위도와 경도를 지정해서 AWS가 리소스의 위치를 알도록해야한다.
  • IP-based Routing
    • 클라이언트 IP 주소 기반으로 라우팅 정의
    • Route53에서 CIDR 목록을 지정하는데 이는 클라이언트의 IP 범위다. IP에 따라 어느 지역으로 라우팅할지 정할 수 있다.
    • 예를 들어 특정 ISP(인터넷 제공자)의 IP 범위를 알면 특정 엔드포인트로 라우팅할 수 있다.
    • 레코드에는 범위에 따라

근접 라우팅 정책

근접 라우팅 정책1
근접 라우팅 정책2

Geoproximity 정책은 여러 리소스가 있을 때 Bias를 기준으로 더 넓은 범위를 커버하고 그 범위 안에서 발생하는 트래픽을 라우팅한다. 특정 지역의 리소스가 다른 지역의 리소스를 받게하고 싶을 때 사용한다.

IP 기반 라우팅

ip 기반 라우팅

Route53 상태 검사

Route53에서 지원하는 라우팅 정책 중 상태 검사를 해주는 정책은 Weighted와 Latency가 있다.

Simple 정책은 단순한 맵핑이라서 상태 검사 없이 유저에게 단순 라우팅한다.

지역 레벨의 고가용성을 원하는 Multi-Region 상황에서 각 region마다 ALB가 있고 그 뒤에 ASG가 있어서 EC2 그룹이 있다고 가정하자. 지연시간 기반 정책에서 epicktrees.net에 유저가 접속하면 Route53은 유저를 가장 가까운 ALB로 리다이렉팅할 것이다. 한 지역의 리소스가 다운되면 그쪽으로 라우팅을 하지 않아야하고 이를 위해선 인스턴스의 Health Check해야한다. DNS Failover를 자동화하기 위한 기본 셋팅

  1. 공용 엔드 포인트(서버, app, or 다른 AWS 서비스)를 모니터링
  2. Calculated Health Checks - 다른 상태 확인을 모니터링하는 상태 확인
  3. CloudWatch 경보의 상태를 모니터링하는 상태 확인

공용 엔드 포인트 상태 검사 과정

  1. 전 세계 15개의 상태 확인이 엔드 포인트의 상태값을 확인
  2. 임계값을 기준으로 정상 혹은 비정상으로 설정. 상태 확인 주기는 기본 30초, (비용을 더 내면 빠른 상태 확인으로 10초마다 가능)
  3. 18% 이상의 상태 확인기가 정상이라고하면 Route 53도 정상으로 판단
  4. 상태 확인기는 로드밸런서로부터 2xx, 3xx 응답을 받아야 정상으로 판단한다. 텍스트 기반 응답일 경우 상태 확인기는 처음 5,120byte를 확인하고 응답 자체에 해당 텍스트가 있는지 확인.
  5. 상태 확인기가 리소스에 접근할 수 있도록 인바운드 정책을 설정해야한다.

Calculated Health Checks

여러 상태 검사를 계산해서 하나의 상태 검사로 합쳐주는 기능이다. Route 53이 라우팅하는 리소스를 체크하는 하위 Health Checker의 결과 값을 하나로 합쳐서 상위 Health Checker를 확인할 수 있다. 하위 상태 확인을 합치는 조건은 AND, OR, NOT이다. 하위 상태 확인을 256개까지 모니터링할 수 있다.

Private hosted zones를 모니터링 with CloudWatch

모든 Route 53의 Health Checker는 공용 웹에 있기 때문에 VPC에 있는 리소스를 접근할 수 없다. 그래서 CloudWatch 지표를 연결시켜서 CloudWatch 경보를 Route53 상태 확인에 할당할 수 있다. VPC 내부 인스턴스를 CloudWatch로 모니터하고 지표에 문제 생기면 CloudWatch 알람을 생성한다. 상태 확인은 알람을 보고 Route 53은 해당 인스턴스에 라우팅을 멈춘다.

Route 53 Traffic Flow

Geoproximity(지리 근접성) 뿐만 아니라 모든 것에 적용된다. 복잡한 라우팅 의사 결정 트리를 관리한다. DNS 관리 정책을 인라인트로 관리하지 않고 UI로 편하게 관리할 수 있다. Traffic Flow Policy로 관리되는 설정은 버전을 지정하고 호스팅 영역을 적용할 수 있다.

traffic flow 실험

위 그림처렁 Traffic Flow Policy를 통해 UI 상에서 복잡한 정책들을 설정하고 연결할 수 있다. Geoproximity(지리 근접 규칙)은 리전을 선택하는데 사용자 지정(위도, 경도 입력)이나 AWS Region을 설정할 수 있다. 그리고 Bias를 통해 특정 리소스의 범위를 더 넓힐 수 있다.

정책을 다 생성하면 호스트 영역(api.epicktrees.net)으로 배포해야하고 정책 레코드 이름을 작성해야한다. 유료라서 때문에 프리티어로만 진행하면 불가능하다. 버전 관리를 할 수 있기 때문에 새로운 버전의 Traffic Flow Policy를 생성해서 적용할 수 있다.

Domain Registar vs DNS Service

Domain Registar를 통해 도메인 이름을 구매할 수 있다. (매년 비용 발생) 지금까지는 Route 53 콘솔을 통한 Amazon Registar를 이용했다. 다른 Domain Registar를 이용해도 괜찮다. DNS 레코드를 관리하는 것은 도메인을 등록하는 것과 별개의 서비스기 때문에 GoDaddy를 통해 example.com 도메인을 구매하고 Amazon Route53을 통해 DNS 레코드를 관리하는 것은 좋은 사용법이다.

사용방법은 AWS에서 공용 호스팅 영역을 생성하고 그 상세 페이지에서 Name servers를 확인한다. GoDaddy에서 Nameservers 설정에 route53의 Name servers를 작성한다. 이러면 GoDaddy가 쿼리에 응답하면 Name Server가 Amazon Route53의 Name server를 가리키고 Route53이 모든 DNS recode를 관리할 수 있게된다. 정리하면 다음과 같다.

  1. 타사에서 도메인
  2. Route 53에서 공용 호스팅 영역을 생성
  3. 도메인을 구해한 타사 웹사이트에서 Name server를 Route 53의 Name server(NS)로 업데이트