토이 프로젝트로 [선착순 쿠폰 발급 시스템]을 만들어보고 AWS 배포를 해보았다.
도메인 발급은 하지 않고, 단순하게 개발 용도로 VPC, Subnet 구성하고 연결했던 내용을 기록으로 남긴다.
VPC
- Virtual Private Cloud, 가상 네트워크로 격리된 네트워크 환경에서 운영할 수 있도록 해준다
- *RFC 1918 국제 규격에 따라 IP 설정 (위키백과)
AWS 웹 콘솔에서 커스텀 VPC 생성 (10.0.0.0/16) 한다.
커스텀 VPC 생성시 라우팅 테이블, 기본 NACL(네트워크 ACL), 기본 보안 그룹(default) 만들어진다. 알기로는 네트워크 ACL은 stateless라서 인바운드, 아웃바운드를 둘 다 설정해야 하는 것으로 알고 있다.
반면 보안 그룹은 stateful로 인바운드 규칙 설정하면 알아서 상태를 기억하고 있어 아웃바운드 처리해주는 걸로 알고 있다.
라우팅 테이블도 기본 생성되는데 vpc내 서브넷 생성하는 경우 자동 연결된다.
Subnet
VPC 내부에 있는 IP 주소 블록으로, VPC 내에서 네트워크를 더 세분화하여 퍼블릭 서브넷과 프라이빗 서브넷을 구성할 수 있다. 퍼블릭 서브넷은 인터넷과 연결될 수 있는 반면, 프라이빗 서브넷은 내부적으로만 사용된다.
- 퍼블릭 서브넷: 인터넷 게이트웨이와 연결되어 인터넷 접근이 가능한 서브넷
- 프라이빗 서브넷: 인터넷 게이트웨이와 연결되지 않아 외부에서 접근할 수 없는 서브넷
- 서브넷은 가용 영역(AZ: Availability Zone)에 종속적이며, 리소스의 가용성과 성능을 높이기 위해 여러 가용 영역에 분산 배치할 수 있다
hello-vpc에 소속된 서브넷 총 3개를 신규 생성한다.
① hello-public-subnet : 10.0.0.0/24
② hello-private-subnet : 10.0.1.0/24
③ hello-db-subnet : 10.0.2.0/24
*각 서브넷별 호스트 수는 2^8 - 5 개이다
*네트워크 주소, 브로드 캐스트 주소 외에 AWS에서 자체 점유하고 있는 기본 주소 3개가 있어서 총 5개를 제외한 나머지 할당 가능
참고. CIDR 설정을 시각화하여 확이할 수 있는 유용한 사이트
참고. CIDR 표기법, 서브넷팅 이해가 안 될 경우
https://dev-ljw1126.tistory.com/388
Internet Gateway
- VPC와 인터넷 간의 통신을 가능하게 하는 컴포넌트로, 퍼블릭 서브넷에 있는 리소스들이 인터넷과 통신할 수 있도록 해준다
- VPC에는 단 하나의 Internet Gateway만 생성 가능하고, 직접 생성 후 연동해줘야 한다
특징
- VPC와의 양방향 인터넷 연결을 제공합니다
- 퍼블릭 IP가 할당된 리소스만 인터넷 게이트웨이를 통해 접근할 수 있습니다
- 인터넷 게이트웨이는 VPC당 하나씩만 생성할 수 있습니다
NAT Gateway ?
- 프라이빗 서브넷에 있는 리소스들이 인터넷에 접근할 수 있도록 해주는 게이트웨이입니다.
- NAT Gateway를 사용하면 외부에서 프라이빗 리소스에 직접 접근할 수 없으면서도 인터넷을 통한 업데이트나 패치 다운로드가 가능합니다.
- 외부에서 프라이빗 리소스로의 직접적인 접근을 허용하지 않아 보안성이 높습니다.
- NAT Gateway는 퍼블릭 서브넷에 배치되며, 인터넷 게이트웨이를 통해 외부와 통신합니다.
- 고가용성을 위해 여러 가용 영역에 배치할 수 있습니다.
생성한 hello-ig와 hello-vpc를 연결해준다
라우팅 테이블 설정
라우팅 테이블은 네트워크 트래픽이 목적지까지 가는 경로를 정의하는 규칙의 집합이다. 각 서브넷은 하나의 라우팅 테이블과 연결되며, 이 테이블은 트래픽이 특정 목적지로 갈 때 사용할 경로를 결정한다.
특징:
- 라우팅 테이블은 VPC 내의 리소스가 서로 통신하거나 외부 네트워크와 통신할 수 있도록 한다
- 기본적으로 VPC의 라우팅 테이블에는 VPC 내 모든 서브넷의 통신을 허용하는 로컬 경로(10.0.0.0/16)가 추가되어 있다
- 추가적으로 인터넷 게이트웨이나 NAT 게이트웨이를 통해 외부와의 통신을 위한 경로를 설정할 수 있다
총 3개의 라우팅 테이블을 생성하고, 각 subnet을 연결한다.
① public-subnet-rt : hello-public-subnet 연결
② private-subnet-rt: hello-private-subnet 연결
③ db-subnet-rt : hello-db-subnet 연결
라우팅 테이블 할당하기 전에는 "명시적 연결이 없는 서브넷(3)"으로 표시되어 있었는데, 각 라우팅 테이블 생성하고 서브넷 연결하면 아래와 같이 "명시적 연결이 없는 서브넷(0)"으로 표기된다.
외부 접속을 허용할 *public-subent 라우팅 테이블에 I.G를 연결한다.
인스턴스 생성
EC2
총 3개의 ubuntu 인스턴스 생성하였다
① coupon-api : 쿠폰 발급 요청받는 api 서버
② coupon-consumer : 쿠폰 발급 처리하는 api 서버
③ redis-test(*BastionHost) : private subnet 인스턴스 접속 용도
Bastion host(베스천 호스트)
- 외부와 내부 네트워크 간의 보안 접속을 위한 중계 서버
- 퍼블릭 서브넷에 위치하여 내부 프라이빗 네트워크의 리소스에 안전하게 접근할 수 있도록 돕는 역할을 합니다
- 보안 관리와 접근 통제가 중요한 인프라 환경에서 필수적인 컴포넌트입니다
coupon-api, coupon-consumer 서버 둘 다 동일한 스펙으로 생성한다
- 인스턴스 유형 : t2.medium(2vCPU, 4GiB 메모리)
- 보안 그룹 : 기본 defualt (*따로 관리할 필요 있으면 보안 그룹 개별 관리)
외부에서 접근할 수 있도록 hello-vpc, *public-subnet 설정하고, 퍼블릭 IP 자동 할당 활성화한다
로컬에서 AWS EC2 인스턴스 접속하는 방법은 아래와 같다.
$ mv helloAWS.pem ~/.ssh/
$ ssh -i ~/.ssh/helloAWS.pem ubuntu@<ec2 instance public ip>
- 외부 접근이 안된다면 보안 그룹 설정과 *public-subnet 라우팅 테이블에 I.G가 연결되어 있는지 확인한다.
참고. JAVA_HOME 설정
# ssh 접속 후
$ sudo apt update
$ sudo apt install -y openjdk-17-jre-headless
$ update-alternatives --config java
# 설정 추가
$ vim ~/.bashrc
# 맨 하단에 추가
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
export PATH=$JAVA_HOME/bin:$PATH
# 설정 반영
$ source ~/.bashrc
# 최종 확인
$ echo $JAVA_HOME
Bastion host 인스턴스의 경우 t2.micro 최소 사양으로 생성한다
EC2 인스턴스 목록에서 bastion host 선택하고 우측 상단 [연결]버튼을 누른다. 그리고 웹 콘솔로 연결시 보안그룹 설정이 추가로 필요하다고 친절하게 알려준다. (ex. 13.209.1.56/29, 22/tcp 추가)
[연결] 버튼을 누르면 아래와 같이 터미널이 출력된다.
bastion host 에서 redis, mysql 접속하는 방법은 아래와 같다.
$ apt update && apt install -y redis-tools mysql-client
# redis 접속
$ redis-cli -h <redis 엔드 포인트> -p 6380
# mysql 접속
$ mysql -h <mysql 엔드 포인트> -uadmin -p
- AWS에서는 같은 VPC내에 있다면 따로 보안 그룹 설정하지 않고도 private subnet 인스턴스 접근이 가능하였다.
- 반면 NHN Cloud 경우 private subnet 보안 그룹 설정하지 않으면 public subnet에서 접근이 불가했던 것으로 기억한다.
ElasticCache
[선착순 쿠폰 발급 시스템] 개발시 N명의 요청에 대해 N개의 트랜잭션이 발생했고, 이로인해 MySQL CPU 과부하를 확인했다. 이를 개선하기 위해 캐시 도입하기로 했고, 아래와 같이 대기열 큐를 인터페이스로 하여 쿠폰 발급 서버/처리 서버가 의존하는 형태로 개발하였다. (결과적으로 load test시 RPS 5.4배 향상, 평균 응답 시간 26.7배 단축)
우선 ElasticCache 서브넷 그룹 생성을 한다. 고가용성을 위해 다중 AZ를 사용하여 여러 서브넷을 설정하는 것을 권장하고 있지만, 테스트 용도이기 때문에 *private-subnet(10.0.1.0/24)만 설정하였다.
이제 ElasticCache 인스턴스(Redis)를 생성한다. 인스턴스 사양은 cache.t3.micro, 서브넷 그룹은 앞서 생성한 coupon-subnet-group을 설정한다. 생성 버튼을 누르고 5분 정도 기다리면 활성화된다.
RDS
마찬가지로 RDS 서브넷 그룹을 먼저 생성한다. 이번에는 *private-subnet(10.0.1.0/24)와 *db-subnet(10.0.2.0/24) 두 개를 설정해보았다. (테스트 용도이기 때문에 *private-subnet 하나만 설정해도 상관없지 않았나 싶다)
그리고 MySQL 인스턴스를 생성한다. MySQL 8.0.35 버전에 프리 티어 템플릿을 선택한다
인스턴스 사양은 db.t4g.micro(2vCPU, 1GiB RAM) 선택
생성해둔 hello-vpc에 연결, 퍼블릭 액세스는 "아니오", 그리고 보안 그룹은 default로 설정한 후 생성한다.
(마찬가지로 보안 그룹 정책을 따로 관리한다면 신규 생성하여 연결한다)
보안 그룹 설정
부하 테스트이기 때문에 간단하게 default 보안 그룹에 아래와 같이 인바운드 규칙을 설정했다. ( 처리한 부분은 집 ip)
- ssh 연결 위한 22/tcp 포트 설정
- 8080/tcp, 8081/tcp의 경우 톰캣 서버 포트
최종 결과
*Locust 부하 테스트
*Prometheus, Grafana 모니터링
*AWS CloudWatch
Reference
https://www.youtube.com/watch?v=WY2xoIClOFA&list=PLfth0bK2MgIaDVJNfMrAo1tKEYAHgSJO6&index=2
https://www.youtube.com/watch?v=LK4qInHjGzg&list=PLORxAVAC5fUWw7jkwvsCloI9qU9Hs-zHA&index=3
'공부 > DevOps' 카테고리의 다른 글
[AWS]서버리스 기반 URL 주소 단축 서비스 구현 - (2) 포워딩 람다 구현 (0) | 2024.09.24 |
---|---|
[AWS] 서버리스 기반 URL 주소 단축 서비스 구현 - (1) 키 생성 람다 구현 (0) | 2024.09.24 |
[NHN Cloud] 컨테이너 기반 Prometheus, Grafana 모니터링 환경 구성(by 오픈 소스 툴) (0) | 2024.09.02 |
[NHN Cloud] 기본적인 웹 서버, DB 인프라 구축 (vpc, subnet, floating ip, ..) (5) | 2024.08.30 |
Jenkins 빌드 배포시 Slack 알림 설정 (5) (0) | 2023.07.16 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!