서버용, DB용으로 EC2를 분리하는 작업

Ziggy Stardust·2025년 1월 2일
0

현재 제가 운영 중인 서비스는 트래픽이 적어 EC2 t2.micro 하나에 백엔드, 프론트엔드 서버, DB를 다 띄우고 있습니다.

현재처럼 한 인스턴스에 서버와 DB를 모두 띄운 경우 다음과 같은 문제점을 가집니다.

한 인스턴스에 서버와 DB를 모두 띄울 시 문제점
1. 인스턴스 스케일아웃 시 DB도 같이 확장해야 합니다. (DB 동기화가 복잡할 수 있고 확장성에 좋지 못합니다.)
2. 트래픽이 몰려 서버에 장애가 발생할 시 인스턴스에도 장애가 전파되어 결국 같은 인스턴스에 있는 DB에도 영향을 줄 수 있습니다.
3. 인스턴스 간 이전 작업이 복잡합니다. (인스턴스 변경이 필요한 배포 같은 경우)

사실
현재 서비스에서 1, 2, 3 의 문제를 고려하기엔 이릅니다. 트래픽이 적어 1, 2 번 문제는 일어날 확률이 적고 3 번의 경우 Docker 컨테이너만 바꿔주면 됩니다. 그럼에도 다양한 배포 기법과 AWS 서비스를 공부한다는 취지에서 한 번 시도하려합니다.


본문

인프라 구축 (1차)

본격적인 ec2 분리를 시작하겠습니다. 우선 DB 전용 인스턴스는 보안적인 부분이 중요하니 서버 인스턴스와 같은 vpc 이되 private subnet 을 새로 만들어 그곳에 배치하겠습니다.

외부 인터넷에서 private subnet 접근을 위해 nat 을 둘 수 있지만 필요성을 느끼기 전까진 두지 않겠습니다.

private subnet 의 네트워크 범위는 cidr 기준 /28 로 주겠습니다. 해당 subnet 에 둘 기기가 적어보였습니다.

이렇게 구성했을 때 드는 비용은 얼마나 될까요.

비용 추산

위에 올려둔 시각자료를 보고 판단할 때 제가 사용하고 있는 AWS 자원은
Internet Gateway, VPC, Subnet 2, Instance 2 입니다.

  • Internet Gateway
    IGW 는 별도의 비용은 없는 것으로 보입니다. 역할 자체는 public ip 를 가진 트래픽을 VPC, 인터넷으로 라우팅 해주는 역할입니다.
    비용 : 0
  • VPC
    VPC 에도 별도의 비용은 부과하지 않는 것으로 보입니다.
    하지만 서버 인스턴스의 경우 public ip 가 필요한데
    이 때 비용이 발생합니다.
    비용 :
    시간 당 0.005 USD (시간 당 7.36 원 - 25.01.03 기준)
    하루 기준 0.12 USD (시간 당 176.41 원 - 25.01.03 기준)
    출처
  • subnet
    subnet 은 vpc 란 사설 네트워크를 논리적으로 나누는 행위라 별도의 비용이 발생하진 않습니다.
    비용 : 0
  • EC2 Instance t2.micro
    public ip 비용이 아닌 순수한 ec2 비용입니다.
    비용 :
    시간 당 0.0116 USD (시간 당 17.07 원 - 25.01.03 기준)
    하루 기준 0.2784 USD (시간 당 409.74 원 - 25.01.03 기준)
    출처

이러한 내용을 종합했을 때 (25.01.03 기준)

  • 한 시간 기준 :
    41.5 원 (public ip : 7.36 + t2.micro 두 대 : 2 * 17.07)
  • 하루 기준 :
    996 원 (한 시간 기준 : 41.5 * 24)
  • 한 달 기준 :
    30876 원 (하루 기준 : 996 * 31)
  • 일 년 기준 :
    363540 원 (하루 기준 : 996 * 365)

이렇게 정리하고 보니 365 일 운영한다는 가정 하에 적은 비용은 아닌거 같네요.. 대부분 사이트에서 수익내기는 힘드니.. (저의 낭만이 줄어들고 있습니다..)


애플리케이션

현재 백엔드, 프론트엔드 서버, DB는 도커로 패키징하여 구동 중입니다. github container registry 를 사용하고 있어 배포 과정도 비교적 단순합니다.

따라서 각 컨테이너를 띄우는 건 간단한 일이지면 다음과 같은 어려움이 남아있습니다.

  1. 기존에 있던 DB 데이터는 어떻게 이전할 것인가?
  2. 유저들이 올린 이미지를 서버 컨테이너 내부에서 저장하는데 컨테이너를 바꾸게 될 때 어떻게 대처할 것인가?
  3. 기존처럼 서버 컨테이너 내부에서 이미지를 저장할 때 서버 컨테이너 다중화 시 어떻게 컨테이너끼리 이미지 데이터를 동기화할 것인가?

현재 고려 중인 방안은 다음과 같습니다.

  1. 기존에 있던 DB 데이터는 어떻게 이전할 것인가?
    이 문제를 좀 더 세부화하자면 DB 이전 방식과 private subnet 의 DB에 어떻게 접근할 것인가 로 나눌 수 있습니다.
    1. DB 이전 방식으로는 mysqldump 를 사용할 것입니다.
    2. private subnet 접근 방식으로는 Bastion Host 를 둬서 접근하려 합니다. 일반적인 방법이라 먼저 적용해보고 이후에 AWS SSM 방식으로 바꿔보려 합니다.
  2. 유저들이 올린 이미지를 서버 컨테이너 내부에서 저장하는데 컨테이너를 바꾸게 될 때 어떻게 대처할 것인가?
    이 문제는 스크립트를 통해서 Docker Host 에 이미지들을 백업하고 새로운 컨테이너에 복원시켜낼 계획이었습니다만 3번 문제를 고려하니 쉽게 결정하기 힘들었습니다.
  3. 기존처럼 서버 컨테이너 내부에서 이미지를 저장할 때 서버 컨테이너 다중화 시 어떻게 컨테이너끼리 이미지 데이터를 동기화할 것인가?
    더 나아가 인스턴스 자체를 바꾸는 배포전략의 경우 어떻게 이미지를 관리할 것이라고 문제를 확대할 수 있습니다.
    단순히 간단한 시스템 운영이라면 2번 문제의 결론처럼 스크립트를 통해 백업을 다뤄 해결했겠지만 롤링, 블루그린 배포, cloud front, beanstalk 를 다루는게 확정된 상태라 인스턴스에 이미지들을 두는 것이 어려워졌습니다.
    그래서 이미지 같은 정적 파일들은 aws s3 라는 외부 장치에 둘 계획입니다.

결론
1. MariaDB 에서 제공하는 기능을 통해 DB 이전
2. Image 저장 공간 변경 (Server 내부 -> AWS S3)

인프라 구축 (2차)

S3 는 private 하게 관리되며 vpc endpoint 를 통해 S3 에 저장하며 presigned url 을 통해서 조회할 예정입니다.

AWS S3 가 추가되었으니 추가 비용이 발생하네요.

아래서 말하는 이미지의 평균 크기는 1MB 로 가정합니다.
현재 서비스의 일 평균 업로드되는 이미지 수는 10으로
한 달(31일) 기준으로 실행되는 PUT 작업수는 310 입니다.

PUT 비용
310 S3 Standard 스토리지에 대한 PUT 요청 x 0.0000045 USD 요청당 = 0.0014 USD (S3 Standard PUT 요청 비용)
2.06 원 (25.01.03 기준)

일 평균 조회되는 이미지 수는 100으로
한 달(31일) 기준으로 실행되는 GET 작업수는 3100 입니다.

GET 비용
3,100 한 달 동안의 GET 요청 x 0.00000035 USD 요청당 = 0.0011 USD (S3 Standard GET 요청 비용)
1.62 원 (25.01.03 기준)

스토리지 비용
첫 한 달 310MB(0.31 GB)
0.31 GB x 0.025 USD = 0.01 USD (0.00775 인데 최소 비용이 적용된 듯 하다)
14.71 원 (25.01.03 기준)

첫 한 달 예상 비용 (25.01.03 기준) :
18.39 원 (스토리지 비용 : 14.71 + PUT 비용 : 2.06 + GET 비용 : 1.62)
일 년간 예상 비용 (25.01.03 기준) :
864.77 원 (스토리지 비용 : 820.61 + PUT 비용 : 24.72 + GET 비용 : 19.44)


정리

DB 인스턴스를 Private Subnet 에 따로 둘려합니다.
그리고 여러 배포 전략에 유리하게끔 이미지 파일을 S3에서 다루도록 할 계획입니다.

그 과정에서 Mysqldump, Bastion Host, AWS S3 등 기술과 기능 등을 사용할 것입니다.

profile
spider from mars

0개의 댓글