AWS 다중 서버 배포
⚡️ 목표
✅ AWS VPC에 대해 알아봅니다.
✅ AWS CLI 사용법을 알아봅니다.
✅ 프라이빗 서브넷을 생성합니다.
✅ ALB를 생성합니다.
Awesome API
서비스는 점점 인기가 많아졌고 더 이상 t2.micro
한 대로 버티긴 어려울 것 같습니다. CPU 성능을 높이는 스케일 업Scale Up 방식도 생각했지만, 부하에 따라 서버의 개수를 유연하게 조정할 수 있는 스케일 아웃Scale Out 방식으로 결정했습니다.
AWS VPC
VPC(Virtual Private Cloud)는 AWS에서 제공하는 강력한 복잡한 가상 네트워크 환경입니다.
서울(ap-northeast-2), 도쿄(ap-northeast-1), N. Virginia(us-east-1)등 각 지역region마다 VPC가 있고 서울은 4개의 가용영역Availability Zone(A,B,C,D)이 있습니다. 처음 AWS 계정을 생성하면 가용영역별로 하나씩 퍼블릭 서브넷을 만들어 주는데, 원하는 만큼 서브넷을 추가할 수 있고 프라이빗 서브넷을 추가하여 보안을 강화할 수 있습니다.
그냥 적당히 설정하고 쓰면 안 될까 싶지만, 인터넷에서 바로 접근할 수 있는 퍼블릭 서브넷에 서버를 배치하는 건 위험하고, 비좁은 서브넷에 서버를 배치하다 보면 나중에 IP가 부족할 수도 있습니다. EKS 맛좀 보면.. 추후 VPC간 연결이나 VPN 사용을 고려하여 네트워크 대역을 변경할 필요도 있습니다.
일단 기본 설정을 유지하고 프라이빗 서브넷을 추가합니다. 서울 리전(ap-northeast-2) 가용영역 중 A와 C에 172.31.112.0/20
, 172.31.144.0/20
영역으로 생성하겠습니다.
CIDR(Classless Inter-Domain Routing)
CIDR(사이더)는 IP 주소를 할당하고 패킷을 라우팅하는 방식 중 하나입니다. 서버는 IP 주소(xxx.xxx.xxx.xxx)로 통신을 하는데 하나하나 경로를 지정하면 복잡하기 때문에 앞에 주소를 고정하고 뒤에 주소만 다르게 하여 블록 단위로 경로를 관리합니다.
CIDR 블록은 xxx.xxx.xxx.xxx(아이피)/xx(고정 비트 수)
와 같이 표기하며 영역이 서로 겹치지 않게 잘 관리해야 합니다.
AWS VPC 더보기
AWS CLI
서브넷은 AWS 관리자 화면에서 클릭클릭으로 만들 수 있지만, 이번엔 AWS CLICommand Line Interface를 이용합니다. AWS는 거의 모든 걸 CLI로 빠르고 간편하게 만들 수 있습니다.
- Access Key를 만들기 위해 Security Credentials 메뉴를 선택합니다.
- Access Keys 항목에서
Create New Access Key
를 누릅니다.
- Access Key ID와 Secret Access Key를 확인할 수 있습니다.
주의!!
Access Key ID와 Secret Access Key는 무지무지무지 중요한 정보입니다. 이 키만 있으면 AWS의 모든 리소스를 만들 수 있기 때문에 혹시나 유출되면 순식간에 채굴 서버가 생성되는 무시무시한 경험을 할 수 있습니다. 수백, 수천만원이 청구되길 원치 않는다면 키를 반드시 안전하게 보관하고 실습이 끝나고 필요하지 않은 키는 삭제하는 것이 좋습니다.
awscli를 설치하고 Access Key를 설정합니다.
aws configure
AWS Access Key ID [None]: AKIA61234567890ABCDE
AWS Secret Access Key [None]: thisissecretdonotusethis
Default region name [None]: ap-northeast-2
Default output format [None]:
설정을 완료하고 계정 정보를 확인합니다.
aws sts get-caller-identity
{
"UserId": "AIDAI1234567890ABCDEF",
"Account": "1234567890AB",
"Arn": "arn:aws:iam::1234567890AB:user/subicura"
}
준비가 완료되었으니, 한 땀 한 땀 리소스를 생성하고 연결해 보겠습니다.
cli_pager 옵션
AWS CLI의 실행 결과를 화면에 그대로 출력하려면 다음 명령어를 입력합니다.aws configure set cli_pager ""
AWS CLI 더보기
📔 AWS CLI 소개
📝 AWS Vault
프라이빗 서브넷 만들기
프라이빗 서브넷을 만들기 위해선 다음 리소스가 필요합니다.
- 서브넷
- NAT 게이트웨이 (+ 공인 IP / Elastic IP)
- 라우팅 테이블
- A 가용영역에 서브넷을 생성합니다.
서브넷이 퍼블릭 서브넷인지 프라이빗 서브넷인지는 연결된 라우팅 테이블에 따라 결정됩니다. 라우팅 테이블에 설정된 경로가 인터넷 게이트웨이를 바라보면 퍼블릭 서브넷, 그렇지 않으면 프라이빗 서브넷입니다.
기본 라우팅 테이블은 인터넷 게이트웨이를 바라보므로 새로 만들어야 합니다.
aws ec2 create-subnet --vpc-id <vpc-id> --cidr-block 172.31.112.0/20 --availability-zone=ap-northeast-2a
vpc-id
: 서브넷을 생성할 VPC ID를 입력합니다. VPC 메뉴에서 확인하거나aws ec2 describe-vpcs --query 'Vpcs[*].VpcId'
명령어를 이용합니다.availability-zone
: 가용영역을 입력합니다. 서울 지역의 A 가용영역인ap-northeast-2a
를 입력합니다.
- NAT 게이트웨이에 할당할 공인 IP를 생성합니다.
aws ec2 allocate-address --domain vpc
- 프라이빗 서브넷이 인터넷에 연결할 수 있도록 NAT 게이트웨이를 생성합니다.
aws ec2 create-nat-gateway --subnet-id <public-subnet-id> --allocation-id <elastic-ip-address-id>
subnet-id
: NAT 게이트웨이가 위치할 서브넷 ID를 입력합니다. A 가용영역에 있는 Public Subnet ID를 선택합니다. VPC > Subnets 메뉴에서 확인하거나aws ec2 describe-subnets --query 'Subnets[*].[SubnetId, AvailabilityZone, CidrBlock]'
명령어를 이용합니다.allocation-id
: 위에서 생성한 Elastic IP 정보를 입력합니다.
- 프라이빗 서브넷에 연결할 라우팅 테이블을 만듭니다.
aws ec2 create-route-table --vpc-id <vpc-id>
- 생성한 라우팅 테이블에 경로를 추가합니다.
aws ec2 create-route --route-table-id <route-table-id> --destination-cidr-block 0.0.0.0/0 --gateway-id <nat-gateway-id>
route-table-id
: 위에서 생성한 라우팅 테이블 ID를 입력합니다.destination-cidr-block
: 내부망을 제외한 모든 요청을 NAT 게이트웨이로 보내기 위해 '0.0.0.0/0'을 입력합니다.gateway-id
: 위에서 생성한 NAT 게이트웨이 ID를 입력합니다.
- 완성된 라우팅 테이블을 서브넷에 연결합니다.
aws ec2 associate-route-table --route-table-id <route-table-id> --subnet-id <private-subnet-id>
route-table-id
: 위에서 생성한 라우팅 테이블 ID를 입력합니다.subnet-id
: 위에서 생성한 서브넷 ID를 입력합니다.
🎉 조금(?) 복잡했지만 프라이빗 서브넷을 생성했습니다! 위 내용을 참고하여 C 가용영역에 하나 더 만듭니다. 숙제
EC2 여러개 만들기
지난번에 배포했던 방식은 다음과 같습니다.
퍼블릭 서브넷에 EC2를 배치하고 바로 요청을 처리하는 방식입니다. 방화벽을 설정했지만, 왠지 불안한 구성입니다.
이번에 구성할 방식은 프라이빗 서브넷에 EC2 2대를 배치하고 Load Balancer를 통해 요청을 처리합니다. 프라이빗 서브넷에 배치해서 안전하고 Load Balancer를 통해 여러 대의 서버에 요청을 할 수 있습니다.
지난번에 만들었던 방법과 비슷하게 EC2를 2대 생성합니다. 차이점은 Subnet, Auto-assign public IP, Security Group 입니다.
Subnet Private 영역 선택
- 앞에서 생성한 프라이빗 서브넷을 선택합니다.
Auto-assign public IP Disable
- 외부에 노출하지 않는 서버이므로 공인 아이피를 할당하지 않습니다.
Security Group 3000 포트를 전체(0.0.0.0/0) 허용
- Load Balancer가 80 포트로 요청을 받으면 뒤에 있는 서버는 꼭 80 포트가 아니여도 괜찮습니다. 기존 애플리케이션 설정인 3000 포트를 사용합니다.
Number of instances 2
- 동일한 설정으로 여러 대의 서버를 생성합니다.
서버가 생성되면, 지난번과 동일하게 서버에 접속하여 애플리케이션을 배포합니다. 3000포트 그대로 서비스하므로 iptables 설정은 제외해도 됩니다.
Elastic Load Balancer 만들기
로드 밸런서는 부하를 적절하게 분산해주는 장치입니다. 기본적인 동작 방식은 사용자가 로드 밸런서에 요청을 보내면 로드 밸런서가 여러대의 서버 중 한대에 요청을 전달하고, 서버가 응답한 결과를 다시 사용자에게 전달해줍니다.
Elastic Load Balancer는 Application Load Balancers, Network Load Balancers, Gateway Load Balancers, Classic Load Balancer 총 4가지 로드 밸런서를 제공하는데 여기선 ALB(Application Load Balancers)를 사용합니다. HTTP 통신을 할 때 가장 많이 사용하는 로드 밸런서입니다.
EC2 > Load Balancers 메뉴에서 새로운 로드 밸런서를 추가합니다.
- 여러 종류 중에 ALB를 선택합니다.
- 이름을 입력하고 Scheme와 IP address type은 기본값을 선택합니다. 내부망에서 사용하는 경우 Internal을 선택할 수 있습니다.
- 로드 밸런서를 배치할 서브넷을 선택합니다. 로드 밸런서는 인터넷 요청을 받아야 하므로 퍼블릭 서브넷에 배치하고 안정성을 위해 2개 이상의 가용 영역을 선택합니다.
- HTTP(80)를 허용하는 Security Group을 만듭니다.
- 로드 밸런서 HTTP(80) 요청을 전달할 Target Group을 생성합니다. 대부분 기본 설정을 그대로 사용하고 Port를 80에서 3000으로 변경합니다.
대상 인스턴스는 이전에 만든 EC2를 선택하고
Include as pending below
를 선택합니다.
- 생성한 Target Group을 선택합니다.
최종적으로 ALB가 생성되면, DNS name으로 접근하여 테스트합니다.
🎉성공! 정상적으로 응답을 확인했습니다. 이제 서버 한 대에 문제가 생겨도 서비스는 정상 작동하고 부하가 생겨도 손쉽게 확장할 수 있습니다.
Elastic Load Balancing 더보기
📔 Elastic Load Balancing 소개
📔 Application Load Balancer 알아보기
마무리
가장 일반적인 배포 방식을 알아보았습니다. 서비스마다 세부적인 차이는 있지만, 큰 틀은 동일하다고 보시면 됩니다.
Elastic Beanstalk도 EC2를 만들고, Target Group에 등록하고 ELB를 연결하는 동일한 방식을 사용합니다. 배포방식을 All at once
에서 Rolling with additional batch
로 변경하면, 배포할 때 새로운 EC2를 하나 더 만들고 애플리케이션을 배포한 다음 Target Group을 새로운 EC2를 바라보게 변경하고 이전 EC2를 제거하는 과정을 자동으로 해줍니다. 순간적으로 인스턴스가 2대 생기기 때문에 서비스가 중단되지 않겠죠?
그럼 도메인을 연결하고 HTTPS 보안을 적용하는 방법을 알아보겠습니다.