땃쥐네

[토이프로젝트] 게시판 시스템(board-system) 2. AWS 환경 구성 본문

Project/Board-System

[토이프로젝트] 게시판 시스템(board-system) 2. AWS 환경 구성

ttasjwi 2024. 9. 21. 23:04

 

일단 프로젝트는 대충 어떤 기능을 구현할 지 정했는데, 이것을 어디에 배포할 지가 문제입니다.

취준생 입장에서 비싼 돈을 지불해가면서 서비스를 배포하는 것은 감당이 안 되는 지라 AWS 프리티어 기능을 사용하기로 했습니다.

 

AWS 프리티어는 1년동안 일정 사용량 내에서 기능을 무료로 사용할 수 있기 때문에 취준생 입장에서 사용하는데 큰 부담이 안 되더라구요.

 

 

일단 배포 기본 아이디어는 VPC 를 준비하고, 퍼블릭 서브넷에 EC2 를 한 대 둔 뒤

EC2 내에 Nginx(도커 컨테이너)를 통해 들어오는 요청을 뒤의 스프링 서버(도커 컨테이너)로 포워딩 시키는 방식을 사용할 생각입니다.

 

 

첫번째로 구현할 스토리, 백엔드 인프라 구성(AWS EC2) 입니다.

 

대강 이 작업이 어떤 가치가 있는 지, 이 작업이 만족해야할 요구 조건은 무엇이 있는지, 구체적으로 어떤 작업을 하면 될 것 같다는 것을 적어갑니다.

 

근데 막상 이렇게 적어보면 할 일이 은근히 많아보입니다.

 

 

그래서 스토리를 서브태스크 단위로 좀 더 쪼갰습니다.

대충 이 정도로 쪼개보면 하나씩 차근차근 진행해나가면 전체 작업이 덜 복잡하게 느껴지죠.

 

참고로 여기서 백엔드 인프라 구성(AWS EC2)  옆에 숫자 1은 스토리 포인트라는 개념입니다.

사람 한명이 하루동안 노력했을 때 이 작업을 몇 일이면 끝낼 수 있을까 하는 관점에서 수치화하는 개념인데요.

아마 제가 노력해보면 하루정도면 할 수 있을 것 같아서 1을 잡았습니다.

 

협업을 한다면 팀의 구성원 수, 사용가능한 자원, 스토리 포인트를 기준으로 하여 일감 분배를 할 수 있기 때문에 이런 개념들을 이용해서 업무를 관리하면 좋을 것 같네요.

 

참고로 서브태스크 단위로는 스토리 포인트 지정이 안 되더라고요. 이 점을 참고하시면 될 것 같아요.


1. VPC 기본 구성요소 생성

1.1 [VPC] VPC 생성

 

VPC 부터 만들어보겠습니다.

 

 

VPC 는 가상 사설 네트워크로, 우리 서비스가 위치할 가상 사설망 영역을 지정하는 개념입니다.

앞으로 생성할 자원들은 이 VPC 위에서 놓여질 것입니다.

 

서울 리전에 생성할 것이고,

Name, Ipv4 CIDR 영역, Name 태그 설정 수준만 해주면 끝.

 

1.2 [VPC] 서브넷 생성

 

VPC 아래에, 서브넷을 세 개 정의합니다.

 

사용자들에게 노출될 영역인 퍼블릭 서브넷 1개

사용자들에게 노출되지 않을 영역인 프라이빗 서브넷 2개(2개를 정의하는 이유는 이후 사용할 서브넷 그룹에서 서브넷을 최소 2개를 필요로 하기 때문입니다.)

 

VPC 의 ipv4 cidr 블록이 10.0.0.0/16 이므로

하위 서브넷들은 각각 10.0.0.0/24, 10.0.1.0/24, 10.0.2.0/24 를 나눠서 쓰도록 했습니다.

 

(여기서 중요한건 az 설정인데 각각 다른 az를 쓰게 해야합니다. 저는 실수로 프라이빗 서브넷 두개를 같은 az에 뒀는데 이러면 잉후 생성할 서브넷 그룹 설정에서 예외가 발생하더라구요. 각각 다른 az에 둬야합니다.)

 

 

1.3 [VPC] 라우팅 테이블 생성

 

라우팅 테이블 세 개를 정의합니다.

 

퍼블릭 서브넷에서 사용할 라우팅 테이블

프라이빗 서브넷 1, 2 에서 사용할 라우팅 테이블

 

1.4 [VPC] 서브넷과 라우팅 테이블 연결

 

각각의 서브넷에서, 라우팅 테이블 연결 편집을 통해 라우팅 테이블을 각각 연결해줍니다.

 

1.5 [VPC] 인터넷 게이트웨이 생성 및 VPC 연결

 

인터넷 게이트 웨이를 생성하고, vpc 에 연결해줍니다.

여기까지 하면 VPC에 IGW가 연결됐지만, 각 서브넷 관점에서 인터넷 구간으로 향하는 라우팅 경로가 없기 때문에 인터넷 통신은 불가능합니다.

 

1.6 [VPC] 퍼블릭 라우팅 테이블 - 인터넷 게이트웨이 라우팅 편집

 

여기서 퍼블릭 라우팅 테이블의 연결 규칙을 수정하여, 0.0.0.0/0(인터넷) 으로 향하는 라우팅 규칙을 인터넷 게이트 웨이를 통하도록 합니다. 이제 퍼블릭 서브넷의 요소들은 인터넷 게이트 웨이를 통해 외부와 통신할 수 있는 상태가 됩니다.

 

이렇게 하면 VPC 를 구성하는 기본 요소에 대한 설정은 끝났습니다. 다음은 EC2 를 설정해볼게요.


2. EC2 인스턴스 생성 및 초기화 작업

 

EC2 인스턴스 생성 과정에서 해야할 작업들입니다.

 

이 작업만 하고 끝날거라면 이렇게 적는건 큰 의미가 없지만 향후 동일한 작업을 한다면 이런 기록들을 남겨두고 참고하는 것은 큰 도움이 되기 때문에 적어뒀어요.

 

처음엔 간단하게 적는 것으로 시작해서 요구사항이나, 메모해둘 것이 있다면 그때그떄 추가로 구체화해서 덧붙이면 좋습니다.

 

 

2.1 [EC2] EC2 보안그룹 생성

 

우선 보안그룹 설정입니다.

 

AWS 의 여러가지 인스턴스들은 그 인스턴스에 들어오고 나가는 트래픽들에 대한 규칙을 지정해야하는데 이것을 '보안그룹'이라고 합니다.

 

EC2 용으로 보안그룹을 하나 정의해둡니다. HTTP, HTTPS, SSH 를 열어둡니다.

(실무에서는 SSH 는 특정 ip에서만 접근 가능하게 하는게 좋습니다. 저는 이번 글에서는 AnyWhere 로 해뒀는데 접속 환경에서 그떄그때 현재 ip 기준으로 접근 가능하게 바꾸도록 할 예정이에요.)

 

 

2.2 [EC2] EC2 키 페어 생성

 

EC2 접근용 키 페어를 생성합니다. 여기서 생성하면 비밀키를 받게 되는데 이 비밀키를 사용해서 이후 EC2에 접근할 것입니다.

 

 

2.3 [EC2] EC2 인스턴스 생성

EC2 를 생성하겠습니다.

간단하게 이미지는 Amazon Linux 를 사용할 예정입니다.

인스턴스는 프리티어에서 사용 가능한 t2.micro (다만 한달 750 시간을 준수해야합니다)

키 페어는 아까 생성해둔 키 페어를 씁니다.

 

 

우리가 정의한 VPC, 퍼블릭 서브넷에 연결하고

퍼블릭 IP 를 자동할당 시킵니다. (이것이 없으면 공개 IP 를 받지 못 해서 외부에서 접속하지 못 합니다.)

보안그룹은 아까 생성한 EC2 보안그룹을 설정합니다.

 

 

스토리지는 대략 15기가 정도까지면 괜찮을 것 같아서, 이 정도로 할당했습니다.

 

ec2 인스턴스를 이 상태로 실행합니다.

 

 

이제 여기까지 하면 ec2에 퍼블릭 ip도 생겼고, 우리는 ssh 비밀키를 가지고 있으니 ec2에 접속할 준비가 됐습니다.

windows 를 사용하는 입장에서 ec2 에 접속하는 여러가지 방법이 있긴한데 제 기준으로 편리한 방법을 사용하겠습니다.

 

2.4 [EC2] EC2 인스턴스 접속

 

 

홈 경로 아래에, .ssh 폴더를 두고 여기에 pem 파일을 옮겨둡니다. 그리고 config 이란 이름의 파일을 생성합니다.

 

# board-ec2
Host board-ec2
  HostName ec2 ip 주소
  User ec2-user
  IdentityFile ~/.ssh/board-ec2-key.pem

 

config 파일에 이렇게 정의해두고 저장합니다.

 

 

git bash 를 사용해서 ssh 명령을 입력하면 같은 폴더의 config 파일을 참조하는데요.

여기서 config 파일의 Host 에 정의한 이름으로 ssh board-ec2 와 같이 입력하면 해당 config 을 읽게됩니다.

이렇게 바로 ec2 에 접속할 수 있습니다. 위의 메시지가 뜨면 yes 를 입력하면 됩니다.

 

EC2 접속 끝!

 

2.5 [EC2] EC2 인스턴스 설정

# 현재 시간 확인
$ date
Sat Sep 21 11:11:19 UTC 2024

# 시간대 목록에서 Asia/Seoul 이 있는 지 확인
timedatectl list-timezones | grep Seoul
Asia/Seoul

# 시간대를 Asia/Seoul 로 변경
$ sudo timedatectl set-timezone Asia/Seoul

$ date
Sat Sep 21 20:11:44 KST 2024

 

그리고 EC2 인스턴스의 시간대 설정을 변경해줍시다. 기본적으로 UTC 기준으로 되어 있는데 우리 한국은 UTC+0900 인 KST 로 변경해야합니다.

 

 

2.6 [EC2] EC2 에 도커 및 도커 컴포즈 설치

# 인스턴스에 설치한 패키지 및 패키지 캐시를 업데이트
sudo yum update -y

# 최신 Docker Community Edition 패키지를 설치
sudo yum install -y docker

# ec2-user를 사용하지 않고도 docker 명령을 실행할 수 있도록 Docker 그룹에 sudo를 추가
sudo usermod -aG docker ec2-user

# docker 서비스 시작
sudo systemctl enable --now docker

exit

 

그 다음은 도커 설치입니다.

 

도커를 설치하고 sudo 키워드 없이 docker 를 사용할 수 있도록 설정한 뒤 터미널을 빠져나갑니다.

다시 ssh 를 통해 ec2에 접속해보고 docker images 명령어 같은 명령어를 쳤을 때 docker 명령어가 잘 입력되면 성공입니다.

 

sudo mkdir -p /usr/local/lib/docker/cli-plugins/
sudo curl -SL "https://github.com/docker/compose/releases/latest/download/docker-compose-linux-$(uname -m)" -o /usr/local/lib/docker/cli-plugins/docker-compose
sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose

docker compose version

 

다음은 도커 컴포즈 설치입니다.

 

도커 컴포즈는 여러 개의 도커 컨테이너를 정의하고 동시에 관리할 수 있게 해주는 도구입니다.

주로 복잡한 애플리케이션이 여러 컨테이너로 구성될 때 사용되며, 각 컨테이너 간의 네트워킹, 볼륨 관리, 환경 변수 설정 등을 쉽게 설정할 수 있도록 해줍니다.

 

여기까지 하면 EC2 기본 설정은 거의 끝났습니다. 


3. RDS 생성 및 초기화 작업

 

다음은 RDS 설정을 해보도록 하죠.

RDS 는 관계형 데이터베이스를 담당하는 AWS의 서비스입니다.

 

3.1 [RDS] RDS 용 서브넷 그룹 생성

 

 

우선 rds 를 위치시킬 서브넷 그룹입니다.

서브넷 그룹에는 2개 이상의 서브넷이 포함되어야하는데요. (AZ 역시 두군데 이상이여야합니다.)

여기서는 private-subnet1 및 private-subnet2 를 설정했습니다.

 

3.2 [RDS] RDS 보안그룹 생성

 

RDS 를 위한 보안그룹 생성입니다. 이 작업은 EC2 페이지쪽에서 하셔야합니다.

인바운드 규칙은 MySQL/Aurora 로 들어오는 요청을 EC2 보안그룹에 대해서만 허용하게 합니다.(사용자 지정 - 보안그룹 선택)

 

3.3 [RDS] RDS 파라미터 그룹 생성

 

DB 의 설정을 위한 파라미터 그룹입니다.

MySQL 8.0 을 쓸 예정이므로 MySQL 8.0 용으로 설정했습니다.

 


character_set 관련 설정은 utf8mb4 로 설정합니다.

  • utf8 는 가변3바이트를 사용하는데 반해서, utf8mb4는 내부적으로 한문자를 표현하는데 4바이트를 사용합니다.
  • 대신 이모지를 사용 가능합니다.

 

 

collation 관련 설정은 utf8mb4_general_ci 로 설정합니다.

 

이와 관련해서는 다른 분 블로그에 글이 있으셔서, 링크를 드립니다.

이렇게 설정하지 않으면 기본값  utf8mb4_0900_ai_ci 는 ㄱㅏ 와 가 를 같은 문자로 인식하는 문제가 있다고 하네요.

 

 

time_zone 설정은 Asia/Seoul 로 설정합니다.

여기까지 하면 데이터베이스 파라미터 그룹 설정 끝

 

3.4 [RDS] RDS 생성

 

 

 

 

이제 RDS 생성을 합니다.

MySQL 로 생성할게요. Aurora 와 같은 것들은 프리티어로 할 수 없더라구요.

 

 

템플릿은 프리티어 사용.

가용성, 내구성 설정을 넣기 시작하면 요금이 발생할 여지가 생깁니다.

 

 

식별자 적당히지어주고, 마스터 암호를 설정합니다.

저는 대충 구글에서 암호생성기 검색을 해서 아무 암후 생성해주는 사이트에서 암호 생성해서 썼어요.

어디 잘 보관해서 관리하셔야합니다.

 

인스턴스 구성에 있어서는

 

인스턴스 클래스 : db.t3.micro

스토리지 : ssd(gp2) / 20GB

스토리지 자동 조정은 비활성화 시켰습니다. (혹시 모를 요금 추가 발생 고려)

 

 

연결 설정입니다. EC2 리소스에 직접 연결은 하지 않고 우리가 설정한 값을 기반으로 할거에요.

 

VPC 에 연결하고, 아까 생성해둔 보안그룹 및 서브넷 그룹을 잘 연결해줍니다.

중요한 점은 여기서 퍼블릭 액세스를 허용하지 않도록 합니다. 외부에서 DB에 직접 접근할 수 있는 것은 보안상 매우 위험하거든요. EC2 를 통해서 간접적으로 할 수 있게만 합시다.

 

 

가용영역은 저는 private-sn1 이 위치한 2b az 로 지정했습니다.

rds 프록시는 별도로 설정하지 않았어요.

 

 

Name 은 저는 보통 AWS 자원을 생성할 때마다 항상 꼬박꼬박 챙겨주는 편이에요. Name 을 지정하면 AWS 화면에서 내가 찾고자 하는 요소를 찾을 때 찾기 편하더라구요.

 

데이터베이스 인증은 암호 인증을 쓰도록 했고

 

모니터링은 활성화하지 않았습니다.

 

기본 데이터베이스 하나 생성해둡니다.

파라미터 그룹은 아까 지정한 파라미터를 그대로 쓸거구요.

자동 백업은 비활성화하고 암호화는 활성화해놨습니다.

 

그 외 유지 관리 부분은 별도로 건들지 않았습니다.

이렇게 RDS 생성 끝

 

3.5 [RDS] EC2에서 RDS 접속

 

 

시간이 좀 지나면 rds 구성이 완료되는데 밑에 가보시면 엔드포인트가 있을겁니다.

엔드포인트 값을 복사해두고

 

# mysql 이미지 가져오기
docker pull mysql

# 1회용 mysql 컨테이너 띄우기(종료하면 사라짐)
docker run -it --rm mysql mysql -h [rds 주소] -P 3306 -u admin -p

# 패스워드 입력

 

이렇게 하면 ec2 인스턴스에 mysql 을 설치하지 않고 rds 의 mysql 에 접속이 가능해집니다.

 

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| board_db           |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.01 sec)

 

접속하고 데이터베이스 목록을 확인해보면 아까 생성해둔 기본 데이터베이스가 있어요.

이렇게 EC2 에서 RDS 에 접속까지 성공!


4. ElastiCache(Redis) 생성 및 초기화 작업

이제 다음은 ElastiCache 입니다.

인메모리 캐시인 Redis 를 이것을 통해 생성하실 수 있어요.

 

4.1 [ElastiCache] ElastiCache 서브넷 그룹 생성

 

 

 

먼저 ElastiCache 의 서브넷 그룹 설정입니다.

프라이빗 서브넷 2개를 연결해서 생성해줬어요.

 

4.2 [ElastiCache] ElastiCache 보안 그룹 생성

 

그리고 ElastiCache 를 위한 보안그룹을 생성합니다.

6379 포트로 들어오는 TCP 요청에 대해, EC2 보안 그룹에 대해서만 허용하도록 설정했어요.

 

4.3 [ElastiCache] ElastiCache 파라미터 그룹 생성

 

파라미터 그룹을 생성했습니다. 당장 변경할 일은 없는데, 혹시 몰라서 이렇게 생성해뒀어요.

 

4.4 [ElastiCache] ElastiCache 생성

 

그 다음은 ElastiCache 생성입니다.

Redis OSS 캐시 생성을 통해 생성할거에요.

 

자체 캐시 설계 / 클러스터 캐시 / 클러스터 모드 비활성화

 

 

클러스터는 AWS 클라우드에 두고, 다중 AZ / 자동장애 조치는 사용하지 않습니다.

 

 

노드 유형은 cache.t2.micro 를 선택합니다. 프리티어에서 허용한 노드기 때문입니다. 이 부분을 특히 주의하세요.

파라미터그룹은 아까 생성한 파라미터 그룹을 연결하고, 복제본은 0개로 지정합니다.

 

 

서브넷 그룹은 아까 생성해둔 서브넷 그룹을 지정하고

private 서브넷 1이 위치한 2b az에 가용영역 배치를 했습니다.

 

 

보안 부분은 EC2 에서만 접근 가능하게 할 예정이라 일단 특별히 걸진 않았습니다.

근데 다시 보니 보안 그룹 설정을 여기서 안 했군요. 아까 만든 보안그룹 연결을 해주세요!

저는 이후 추가로 연결해줬습니다.

 

 

 

백업 및 유지관리는 요금이 추가로 부과될 가능성이 있어서 하지 않았습니다.

 

 

 

로그 설정도 별도로 하지 않았고, Name 태그 설정은 해둡니다.

이렇게 ElastiCache 설정까지 끝!

 

4.5 [ElastiCache] EC2 에서 ElastiCache 접속

docker pull redis
docker run --rm -it redis redis-cli -h redis주소 -p 6379

 

ElastiCache 에 할당된 기본 엔드포인트 주소 및 포트를 잘 지정해서 전달하면 ElastiCache 접속에 성공합니다.

 

> set hello 1
OK
> get hello
"1"
> del hello
(integer) 1

 

간단한 명령을 입력해도 잘 되는걸 볼 수 있어요.

 


정리

 

 

 

여기까지 하면 일단 EC2에 도커 환경을 구축하고, 여기서 도커 컨테이너를 띄워서 RDS 와 ElastiCache 에 접속하는게 가능하다는 것도 확인했어요. 하지만 우리 서비스의 목적은 여기서 끝이 아닙니다.

 

 

여기서 더 발전시켜서, Nginx 도커를 두고, 스프링 서버 두대를 띄워서 무중단으로 스프링 서버를 배포하면서,

RDS 와 ElastiCache 에 접근 가능하게 하는게 핵심 목적인데요. 이 부분은 이어지는 글에서 다뤄보겠습니다.

 

Comments