[AWS] Aurora Serverless 소개 및 외부엑세스 구성하기

최근에 Amazon RDS Aurora의 타입 중 서버리스가 서울리전에 출시되었습니다. 기존의 Provisioned 타입은 예측할 수 있는 디비 접속 및 사용량을 기반으로 용량을 RDS 재시작 없이 사용자가 조정할 수 있습니다. 그런데, 부하가 간헐적으로 발생하여 예측이 어려운 경우가 있습니다. 예를 들어, 배치 작업의 경우는 하루에 몇 분 혹은 몇시간 정도만 사용량이 있고 나머지 시간은 아예 접속량이 없는 경우가 있습니다. 이러한 사용 패턴은 실제 사용 시간에 비해 불필요한 비용을 지불하게 됩니다.

Aurora Serverless는 사용자가 최소 및 최대 용량만 설정하면 용량 확장 조건에 따라 용량을 자동 조정해 주며, 용량이 조정되는 동안에도 연결이 끊기지 않고 유지됩니다. 또한 "웜"리소스 풀로 용량 확장을 준비하기 때문에 조정이 신속합니다. 더구나, 스토리지와 처리가 분리되어 있으므로 사용량이 없을 때 용량을 0까지 축소하여 스토리지 비용만 지불하면 됩니다.

<출처: https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/AuroraUserGuide/aurora-serverless.html>

Aurora Serverless의 동작, 특징, 장단점 및 제한사항은 Amazon Aurora문서를 참고하여 주시기 바랍니다. 이번 글에서는, 현재 Aurora Serverless에서는 퍼블릭 IP 주소를 지정할 수 없고 이로 인해 외부에서 직접 엑세스를 할 수 없는데, 이 구성이 반드시 필요한 경우 어떻게 구성하는지 알아보겠습니다.

개요

Aurora Serverless는 DB 클러스터의 엔드포인트가 VPC 내에서만 유효한 아이피이므로 AWS VPN이나 VPC 피어링 연결을 통해서는 엑세스할 수 없습니다. 또한 TCP 기반 로드밸런서에도 연결할 수 없습니다. 꼭 필요한 경우 EC2 인스턴스로 3306/tcp포트에 대한 Proxy 구성을 함으로써 외부에서 연결이 가능하도록 할 수 있습니다.

프락시 인스턴스 생성

먼저, 프락시를 구성할 서브넷과 보안그룹을 생성합니다. 외부엑세스를 허용할 Aurora Serverless의 보안그룹에 프락시 서버가 3306/tcp 접속을 할 수 있도록 허용합니다. 프락시 서버는 t2.micro정도의 저사양으로 Amazon Linux 2 AMI를 사용하여 퍼블릭 서브넷에 생성하고, 필요한 경우 정적 EIP를 연결합니다. 프락시 서버에 대한 보안그룹에는 Aurora Serverless에 접속할 외부아이피를 3306/tcp에 대해 허용해 줍니다.

HAProxy 설치 및 시작

프락시용 인스턴스를 포트포워딩 기능을 구성하기 위해 여기서는 HAProxy를 사용합니다. HAProxy는 1.6 이상에서 백엔드 노드에 대한 DNS resolver 기능을 지원하고 있어서 Aurora Serverless의 엔드포인트의 동적인 아이피들을 외부와 연결해줄 수 있습니다. 아래 방법으로 HAProxy 최신 버전을 설치하고 컨피그를 설정하여 서비스를 시작합니다.

yum install openssl-devel systemd-devel gcc
cd ~; wget https://www.haproxy.org/download/1.8/src/haproxy-1.8.3.tar.gz
tar xvfz haproxy-1.8.3.tar.gz
cd haproxy-1.8.3/
vi Makefile (PREFIX = /usr/local 을 /usr 로 수정 후 저장)
make TARGET=linux2628 USE_OPENSSL=1 USE_SYSTEMD=1
make install
cp contrib/systemd/haproxy.service.in /etc/systemd/system/haproxy.service
(HAProxy 서비스 기동 스크립트 /etc/systemd/system/haproxy.service에서 @SBINDIR@를 /usr/sbin으로 수정 후 저장)

ExecStartPre=/usr/sbin/haproxy -f $CONFIG -c -q
ExecStart=/usr/sbin/haproxy -Ws -f $CONFIG -p $PIDFILE
ExecReload=/usr/sbin/haproxy -f $CONFIG -c -q

systemctl enable haproxy
mkdir /etc/haproxy
HAProxy 컨피그 파일 /etc/haproxy/haproxy.cfg에 아래 내용으로 저장

global
log /dev/log syslog info

defaults
log global
mode tcp
timeout connect 3s
timeout client 30s
timeout server 30s

resolvers mydns
nameserver public-0 10.10.0.2:53
hold valid 3s

frontend aurora-proxy
bind *:3306
default_backend site-backend

backend site-backend
server aurora-sl sjkim-test.cluster-ckgbznranfhe.ap-northeast-2.rds.amazonaws.com:3306 resolvers mydns check inter 10s

systemctl start haproxy
HAProxy 서비스가 정상적으로 실행된 경우 아래와 같이 3306/tcp에 대한 바인딩 상태를 확인할 수 있습니다.

동작 확인

보안그룹에서 3306/tcp에 대한 접속을 허용한 곳에서 Aurora Serverless의 클러스터 노드로의 디비 접속을 확인해봅니다. 이 때, 접속할 디비호스트 이름은 Proxy인스턴스의 퍼블릭IP 혹은 퍼블릭DNS입니다.

mysql -h ec2-13-124-1-48.ap-northeast-2.compute.amazonaws.com -u'dbuser' -p'dbpass123'

정상접속이 될 때 netstat로 3306/tcp 상태는 아래와 같이 13.xxx.xxx.140 외부접속자의 IP로부터 10.10.0.240:3306 Proxy인스턴스의 내부IP로 맺어진 세션이 다시 10.10.100.69:3306 Aurora Serverless의 노드 IP 중 하나에 연결된 것을 확인할 수 있습니다. Aurora Serverless의 엔드포인트는 각 AZ에 하나의 CNAME으로 노드IP를 제공하는데 노드IP가 변경되어도 haproxy의 resolver에 의해서 자동으로 변경된 노드IP로 연결해 주도록 동작합니다

만약 Aurora Serverless를 외부서버와 연동하여 서비스를 하고자 할 때는, Proxy를 고가용성(HA)으로 구성해야 하는데, 이 때는 Proxy인스턴스를 각 AZ에 하나씩 구성하고, Classic Load Balancer로 외부접속을 구성하면 됩니다. 아래는 HA구성한 Classic Load Balancer를 통해 디비 접속을 했을 때 각Proxy인스턴스에서의 netstat이며 Load Balancer의 내부아이피 10.10.16.220로부터 접속이 됨을 확인할 수 있습니다.

맺음말

이상으로 Aurora Serverless의 간단한 소개와 외부엑세스 구성에 대해서 알아보았습니다. Aurora Serverless의 장점을 꼭 활용해 보고 싶으나 외부엑세스 구성을 할 수 없어서 고민하시는 분들에게 도움이 되길 바랍니다.