Introduction
- 로컬 데이터 센터에서 여러 서비스를 관리하려면 가상화 플랫폼을 위한 가상화 팀, 데이터센터 운영 팀, 모니터링 팀 등 많은 인력과 시간이 필요할 것이다.
- 또한 서비스가 복잡해질수록 scale up, down이 자주 될 것이다. 대부분 이러한 작업들은 수동으로 진행된다.
- 이러한 문제를 해결하기 위해 프로젝트를 클라우드에 배포하고 관리하는 연습을 한다.
목표
- 가상 머신에 배포 했던 것과 다르게 클라우드에 도메인을 연결하여 프로젝트를 배포한다.
- 로컬에 있는 애플리케이션을 lift and shift 방법으로 클라우드에 마이그레이션 한다.
- lift and shift는 코드 수정을 하지 않은 채 전체 시스템을 새롭게 사용자에게 배포할 환경으로 통째로 복사하는 것이다. 보통은 마이그레이션에 드는 비용과 시간을 최소화하고 싶은 경우, 오래된 인프라 유지 비용을 즉시 절감하려는 경우, 코드를 변경하는 것이 특성상 불가능한 상용 애플리케이션을 이전해야 하는 경우 등에서 이 방법을 사용한다.
배포할 서비스
- 배포할 Demo Project는 Mysql, Memcached, RabbitMQ를 사용한 Spring Project이다.
기술 및 환경
- PC : M1 pro Macbook
- AWS
- EC2 - Tomcat, Mysql, Memcached, RabbitMQ
- Route 53 - DNS (가지고 있는 도메인에 연결)
- S3 - 로컬에서 프로젝트를 빌드하여 war 파일을 s3에 다운로드한다.
- ELB
- AutoScaling
- IAM, ACM, EBS ...
아키텍처
- 사용자가 URL을 통해 웹 사이트에 접근한다.
- URL이 DNS endpoint를 가리킨다.
- 이 endpoint를 이용하여 브라우저나 애플리케이션에 접근하면 로드밸런서에 https 인증서를 통해 연결될 것이다.
이 과정으로 사용자는 애플리케이션 로드 밸런서 endpoint에 접근할 수 있다. - 로드 밸런서는 보안 그룹에 있으며 https 트래픽만을 허용할 것이다.
- 로드 밸런서가 tomcat 인스턴스에 대한 요청을 route 한다.
- tomcat이 auto scaling group에 의해 관리되고 있는 인스턴스들을 실행할 것이다.
- 로드의 양에 따라 인스턴스들의 사용량을 scal out, in 할 것이다.
- tomcat ec2 인스턴스는 분리되어 있는 보안 그룹에서 실행되고, 로드밸런서로부터 8080 포트로 오는 트래픽만 허용한다.
- 백엔드 서버의 IP 주소는 Route 53으로 연결될 것이다.
- tomcat은 route 53에서 정해주는 이름으로 백엔드 서버에 접근한다.
- 백엔드 ec2 인스턴스들은 보안 그룹에 분리되어 있다.
실행 순서
- Key Pair 생성
- Security Group 생성
- Instance 설치하기
- Route 53으로 IP DNS 매핑
- 애플리케이션 빌드
- S3 bucket 업로드
- Tomcat EC2 인스턴스에 artifact 다운로드
- https 연결을 위한 로드 밸런서 setup
- ELB Endpoint를 DNS 호스팅에 매핑
- 검증하기
보안 그룹, Key Pair 생성
각 인스턴스에 대한 보안 그룹들을 먼저 설정한다.
로드 밸런서
Tomcat
BackEnd
배포할 Production의 설정 파일인 application.properties를 보면
#JDBC Configutation for Database Connection
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://db01:3306/accounts?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
jdbc.username=admin
jdbc.password=admin123
#Memcached Configuration For Active and StandBy Host
#For Active Host
memcached.active.host=mc01
memcached.active.port=11211
#For StandBy Host
memcached.standBy.host=127.0.0.2
memcached.standBy.port=11211
#RabbitMq Configuration
rabbitmq.address=rmq01
rabbitmq.port=5672
rabbitmq.username=test
rabbitmq.password=test
memcache의 port : 11211
rabbitmq의 port : 5672
백엔드 서비스들이 tomcat에 접근할 때 위 포트를 사용하므로 인바운드 규칙에 추가해 준다.
- backend 보안 그룹에 3개의 서비스를 설정했다.
- 이 서비스들은 서로 데이터를 주고받을 수 있으므로 자신의 보안 그룹인 Backend를 추가한다.
Key Pair
- Key는 터미널에서 인스턴스에 생성, 접속할 때 필요하다.
EC2 인스턴스 생성
https://sg-dev.tistory.com/202
[Vagrant] Vagrant를 사용하여 가상 머신에 Web 배포하기 (IaC)
Introduction 목표 여러 서비스로 구성된 웹을 가상머신으로 로컬에서 환경을 구성하고 배포할 것이다. 수동으로 서비스들을 각각 provisioning한다. 수동으로 provisioning한 과정을 쉘 스크립트를 작성
sg-dev.tistory.com
- 가상 머신에서 bash 파일을 이용하여 Provisioning 했듯이, EC2 인스턴스가 생성될 때 각 서비스들을 생성하기 위해 사용자 데이터에 각 서비스를 위한 명령어들을 작성하여 생성한다.
MySQL
- free tier를 사용하고 있어서 t2.micro를 사용한다.
- 기존에 생성했던 보안 그룹을 선택한다.
- 고급 세부 정보에서 아래로 내리면 사용자 데이터가 나온다.
- Vagrant로 provisioning 하기 위해 사용했던 bash script파일을 여기에 작성한다.
- EC2 가상 머신이 생성되면서 이곳에 작성된 명령어들을 수행하며 provisioning 된다.
- 생성된 인스턴스에 ssh로 로그인하기 위해 보안 그룹에서 22번 port를 인바운드 규칙에 추가해 준다.
Mysql 인스턴스 로그인
ssh -i [Key pair file] [name]@[public IP]
- 다운로드한 key를 이용하여 ssh 로그인
- key의 권한 에러가 발생하면 권한을 수정하고 다시 실행하면 정상적으로 로그인된다.
- 정상적으로 Mysql 인스턴스가 bash script에 따라 Provisioning 된 것을 확인했다.
이와 같은 방식으로 다른 서비스인 Memcached, RabbitMQ 인스턴스를 생성한다.
Memcached
RabbitMQ
Route 53
- Backend 인스턴스들의 Private IP를 도메인 네임을 생성하여 연결한다.
각 인스턴스의 Private IP
- db01 : 172.31.39.31
- mc01 : 172.31.42.227
- rmq01 : 172.31.37.153
Route 53에서 호스팅 영역 생성
레코드 생성
- IP 주소로 접근하는 것이 아니라 Route 53에서 DNS 레코드를 추가하여 주소로 백엔드 서버에 접근할 수 있도록 한다.
Tomcat
프로젝트 빌드, 배포
private IP를 DNS로 매핑하였으므로 application.properties 파일을 수정해야 한다.
기존
#JDBC Configutation for Database Connection
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://db01:3306/accounts?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
jdbc.username=admin
jdbc.password=admin123
#Memcached Configuration For Active and StandBy Host
#For Active Host
memcached.active.host=mc01
memcached.active.port=11211
#For StandBy Host
memcached.standBy.host=127.0.0.2
memcached.standBy.port=11211
#RabbitMq Configuration
rabbitmq.address=rmq01
rabbitmq.port=5672
rabbitmq.username=test
rabbitmq.password=test
수정
#JDBC Configutation for Database Connection
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://db01.production.com:3306/accounts?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
jdbc.username=admin
jdbc.password=admin123
#Memcached Configuration For Active and StandBy Host
#For Active Host
memcached.active.host=mc01.production.com
memcached.active.port=11211
#For StandBy Host
memcached.standBy.host=127.0.0.2
memcached.standBy.port=11211
#RabbitMq Configuration
rabbitmq.address=rmq01.production.com
rabbitmq.port=5672
rabbitmq.username=test
rabbitmq.password=test
local에서 build
mvn install
- build 된 war 파일을 S3에 올리고 awscli로 다운로드한다.
S3만 관리하는 IAM 사용자 추가
- IAM 사용자에게 S3 권한 부여
- awscli에서 인증할 액세스 키 생성
- awscli에서 IAM 사용자 추가
- S3 버킷 생성
- war 파일을 s3에 복사
tomcat에서 war 파일을 다운로드하기 위해 역할 추가
- tomcat 인스턴스 IAM 역할 수정
Tomcat 접속
- Tomcat 보안 그룹에 ssh 추가
- tomcat이 정상적으로 실행되고 있다.
- war 파일을 s3에서 다운로드하기 전에 tomcat의 기본 html 파일을 삭제한다.
- s3에서 war 파일을 다운로드 받기 위해 awscli를 설치해야 한다.
- s3에서 tomcat 인스턴스로 war를 다운로드한다.
- 다운로드한 war 파일을 tomcat의 기본 폴더인 webapp 하위로 복사한다.
로드 밸런서
대상 그룹 생성
로드 밸런서 생성
- 많은 가용영역을 선택할수록 가용성이 높아진다.
- 보안 그룹에서 만들었던 ELB 보안그룹 선택
- HTTPS, HTTP 모두 추가
- 만든 대상 그룹으로 선택
- 이전에 만들었던 인증서 선택
- 생성된 DNS name을 구매한 도메인 업체의 DNS 레코드에 추가하기.
- aws-production.psg-dev.com으로 들어가면 프로젝트가 정상적으로 동작하고 있는 것을 확인할 수 있다.
- 로드밸런서가 요청을 tomcat으로 라우팅 한다.
Auto Scaling
tomcat 인스턴스에 대해 auto scaling group을 적용한다.
먼저, tomcat 인스턴스의 AMI를 만들어야 한다.
- 특이 사항이 없는 한 이미지 이름만 작성하고 생성한다.
Auto scaling 탭의 시작 구성 - 시작 구성 생성
- 생성한 AMI를 선택
- 인스턴스 유형은 free tier를 사용하고 있으므로 t2.micro 선택 IAM 추가
- IAM 사용자 선택
- 기존 보안 그룹 선택
- 키페어 선택
Auto Scaling Group 생성
Auto Scaling Group 탭 선택 -> 생성
- 시작 구성 선택
- 서브넷 추가
- 이후 기본 선택으로 하여 생성
Tomcat 인스턴스가 강제로 종료되면 Auto Scaling Group에 의해 Tomcat과 같은 인스턴스가 생성된다.
마치며
AWS에 프로젝트 전체를 그대로 옮겨보았다. 생각보다 간단하게 진행되어서 다행이다.
EC2 인스턴스는 가상 머신일 뿐이므로 프로비저닝 하는 과정이 로컬에서 가상 머신으로 프로비저닝 할 때와 매우 비슷했다.
크게 과정을 나누면 다음과 같다.
- 보안 그룹 생성
- 인스턴스 생성
- DNS 레코드 생성
- 프로젝트 빌드, 배포 -> S3에 다운로드
- Tomcat에 S3 권한을 가진 IAM 추가
- Tomcat에 S3에 다운로드했던 war 파일을 다운로드
- war 파일을 Tomcat의 webapps으로 이동
- 로드 밸런서 생성 -> 도메인 네임을 호스팅 관리 페이지에서 DNS 레코드에 추가 -> 여기까지 나의 도메인에 프로젝트 배포 완료.
- 오토 스케일링 그룹 생성 -> 인스턴스에 이상이 생길 경우 인스턴스 자동으로 추가
단순하게 진행되었고, 큰 문제는 없었던 것 같다.
lift and shift 또는 Regost 방식으로 클라우드에 마이그레이션을 마쳤다.
다음에는 Refactoring 방식으로 마이그레이션을 해볼 것이다.