개요
- 지금까지 배운 기술들이 어떻게 서로 맞아 들어가는지에 대해 알아보는 글이다.
- 각 서비스들이 어떻게 협력하여 솔루션 아키텍처가 되는지 알아본다.
- 예시 사례들을 보면서 어떤 서비스가 쓰이는지에 대해 숙지할 것이다.
첫번째 아키텍처(Stateless Web App : WhatIsTheTime.com)
전제 조건
- 해당 웹 사이트는 사람들에게 시간을 알려주는 사이트이다.
- 너무 단순하기 때문에 데이터베이스가 필요 없는 상황이다.
- 각각의 인스턴스와 서버는 시간이 몇 시인지 알고 있는 상태이다.
- 해당 사이트는 소규모에서 시작하기 때문에 downtime을 허용한다
- t2.micro 인스턴스로 시작한다
- 추후에는 인기를 얻어 수직,수평 확장을 해야하며, 다운타임을 허용하지 않는다.
흐름
1.Starting Simple
- 원하는 기능
- 사용자가 시간을 물어볼 경우 현재 시각을 반환해준다.
- 공용 EC2 인스턴스가 존재하고, 무슨 일이 생기면 재시작할 수 있도록 EC2 인스턴스가 고정 IP 주소를 갖도록 하고 싶다.
- 그렇기에 탄력적 IP 주소를 연결할 것이다.
2. Scaling vertically
- 애플리케이션이 점점 더 많은 트래픽을 갖게 되면서 t2.micro 인스턴스로 충분하지 않다는 것을 깨닫게 된다.
- 부하를 처리하기 위해 t2.micro 인스턴스를 m5.large 유형의 인스턴스로 교체하려고 한다.
- 인스턴스를 중지 시키고 인스턴스 유형을 바꾸고 그 후에 다시 인스턴스를 시작할 수 있다.
- 이는 탄력적 IP를 가지고 있기 때문에 동일한 공용 IP를 가지게 되고 사람들은 여전히 애플리케이션에 접근할 수 있다.
3. Scaling horizontally
- 애플리케이션에 더욱 많은 인기를 끌게 되어 수평 확장을 해야할 때가 왔다.
- 해당 m5 애플리케이션은 하나의 공용 Ip를 가지고 있고, 탄력적 IP가 연결되어 있다는 것을 고려해야 한다.
- EC2 인스턴스들을 추가한 뒤 (모두 m5.large로 확장), 이들 모두가 탄력적 IP를 갖게 된다.
- 인스턴스가 늘어나고 각각의 고정 IP가 할당될수록 관리하기 어려워지는 문제를 갖게됐고, 탄력적 IP를 제거하게 됐다.(또한 한 계정에서 리전마다 Elastic IP를 최대 5개까지 밖에 갖지 못한다.)
- 이를 해결하기 위해 Route 53을 설정하고, 웹사이트 URL은 api.whatisthetime.com이 된다.
- 이를 통해 탄력적 IP를 더 이상 관리하지 않아도 된다.
- 하지만 이러한 방식 또한 문제가 존재한다. 일부 인스턴스를 종료 했을 경우 해당 인스턴스의 IP를 사용하고 있던 사용자들은 TTL 시간이 끝날 때까지 종료된 인스턴스에 접근하려고 한다.
4. Scaling horizontally, with a load balancer
- 이제 더이상 공용 인스턴스를 사용하지 않는 대신 사설 EC2 인스턴스를 제작한다.
- 이들을 같은 가용 영역에서 실행한다.
- 로드 밸런서를 공개 사용함으로써 사설 EC2 인스턴스들은 뒤에 숨어 있을 수 있게됐다.
- 로드 밸런서가 IP 주소를 지속적을 바꾸기 때문에 이번에는 A 레코드를 사용할 수 없게 됐다.
- 대신, 별칭 레코드를 사용할 수 있다.(로드 밸런서 이기 때문에 사용할 수 있다)
- Route 53으로부터 ELB를 가리키게 한다.
- 결과적으로 DNS는 바꾸지만 사용자들은 이제 로드 밸런서에 접속한다. 그리고 로드 밸런서는 EC2 인스턴스로 리디렉션하고 트래픽의 균형을 잡는다.
- 또한 상태 확인 기능 덕분에 사용자들에게 다운타임도 존재하지 않는다.
- 그러나 아직 수동으로 인스턴스를 추가하고 제거하는 것은 어려운 이라는 점이 남아있다.
5.Scaling horizontally, with an auto-scaling group
- 오토 스케일링 그룹을 활용하여, 요청에 따라 확장과 축소를 할 수 있게 구성한다.
- 이제 정말 안정적인 아키텍처를 완성하였다.
- 하지만 이번에는 지진이 발생하였다.
6. Making our App Multi-AZ
- ELB를 활용하여 상태 확인 뿐만 아니라, 다중 AZ도 추가한다.
- 오토 스케일링 그룹 역시 다중 AZ에 걸쳐 존재할 수 있게 한다.
- 이로써 AZ-1이 다운되더라도, AZ-2와 AZ-3가 있기 때문에 사용자를 귀한 트래픽을 처리할 수 있다는 장점이 생기게 됐다.
- 이제 남은건 비용적 측면에서 개선을 하는 것이다
7.Discount Cost
- 각각의 AZ에는 최소 하나 이상의 인스턴스가 실행 중일 것이기 때문에 용량을 예약하는 것이 기본적으로 애플리케이션의 비용을 줄이는 작업이 될 수 있다.
최종 복습
- EC2 인스턴스는 공용IP와 사설 IP를 갖는 목적에 대해 생각해보자
- 애플리케이션에 탄력적 IP vs Route 53, Load Balancer를 사용할 때의 장점에 대해 생각해보자
- Route 53 TTL 때문에 A 레코드를 사용할 수 없었고, 따라서 로드 밸런서와 별칭 레코드를 사용해야 한다는 것에 대해 생각해보자.
- EC2 인스턴스를 수동으로 관리하는 방법과 그에 대한 유지 보수가 어렵기에 오토 스케일링 그룹을 사용할 수 있다(또한 비용 절감에도 도움을 준다.)
- 다중 가용영억을 통해 재난 발생을 극복한 것에 대해 생각해보자
- 정확히 응답하는 인스턴스만 트래픽을 받도록 하기 위해 ELB 상태 확인을 활성화 한 것에 대해 생각해보자
- 항상 실행되어 하는 최소한의 인스턴스 갯수가 존재한다면 예약을 통해 비용을 절감할 수 있는 것에 대해 생각해보자
두번째 아키텍처(Statful Web App : MyCLothes.com)
전제 조건
- 온라인으로 옷을 살 수 있게 해주고, 장바구니 기능을 지원한다.
- 수백명의 사용자가 있고, 모든 사용자들이 웹사이트를 둘러본다.
- 확장을 할 수 있어야 하고, 수평 확장성을 유지한다.
- 애플리케이션의 Web Tier를 최대한 무상태로 유지하고 싶어한다.
- 비록 장바구니 기능이 존재하지만 이는 사용자들이 웹사이트를 둘러볼 때 유지가 되어야 한다.
- 주소 등의 사용자 정보를 효과적으로 보관하고 어디에서나 접근할 수 있는 데이터베이스에 저장할 것이다.
현재 아키텍처의 구조도
- Route 53와 다중 AZ ELB가 있으며, 오토 스케일링 그룹과 세 개의 AZ가 기본적으로 존재한다.
- 애플리케이션이 ELB에 접근하고 각 인스턴드 중에 한개로 로드 밸런싱된다.
- 하지만 여기에는 사용자가 이용 중에 인스턴스가 변경되면 기존의 장바구니 정보들이 사라진다는 치명적인 오류가 존재한다.
Introduce Stickiness(Session Affinity)
- ELB의 기능 중 하나인 ELB Stickiness를 활성화한다.
- 이를 통해 사용자가 이용 도중 다른 인스턴스로 가게되는 것을 방지할 수 있다.
- 하지만 해당 EC2 인스턴스가 어떤 이유로든 종료되면 장바구니를 잃어버리게 된다.
Introduce User Cookies
- 쿠키를 사용하여 EC2 인스턴스가 장바구니 내용을 저장하는 대신 사용자쪽에서 장바구니 내용을 저장하도록 하는 것이다.
- 이를 통해 서버는 Stateless 속성을 가질 수 있게 된다.
- 그러나 HTTP 요청이 점점 더 무거워지는 문제가 있다.
- 또한 쿠키가 공격자에 의해 변경됨으로써 사용자의 장바구니가 갑자기 수정될 수 있기 때문에 보안의 위험도 존재한다.
- 따라서 이러한 종류의 아키텍처에서는 EC2 인스턴스가 반드시 사용자 쿠키의 내용을 검증해야 한다.
- 또한 전체 쿠키의 크기는 4KB 이하까지만 가능하기 때문에 쿠키 내에는 매우 작은 정보만 저장할 수 있다.
Introduce Server Session
- 전체 장바구니를 웹 쿠키로 보내는 대신에 단순히 세션 ID만 보내는 것이다.
- 해당 세션 ID는 사용자에 대한 세션ID이다.
- 백그라운드에는 ElastiCache 클러스터가 존재하여 세션 ID를 보낼 때 EC2 인스턴스에게 장바구니 내용을 ElastiCache에 추가하고, 이 장바구니 내용을 불러올 수 있는 ID가 바로 세션 ID가 된다.
- 이를 통해 ELB의 Stickiness 또는 User Cookie를 사용하지 않고 세션 데이터를 불러올 수 있게 되어 사용자가 특정 인스턴스나 쿠키에 의존하지 않아도 되는 이점을 얻을 수 있다.
- 해커들이 ElastiCache의 내부를 수정할 수 없기 때문에 훨씬 안전해졌다.
- 또한 ElastiCache의 빠른 속도를 얻을 수 있다.
- 참고로 세션 데이터 저장의 또 다른 방식으로는 DynamoDB가 있다.
Storing User Data in a Database
- 사용자 데이터를 데이터베이스에 저장하려고 한다. 이를 위해 RDS 인스턴스와 통신해야 한다.
- 다중 AZ에 있는 각각의 인스턴스가 RDS와 통신할 수 있기 때문에 일종의 다중 AZ 무상태 솔루션을 효과적으로 얻을 수 있다.
Scaling Reads
- 웹 사이트의 운영이 잘되면서 사용자가 늘어나고, 그들은 대부분의 시간을 웹사이트 둘러보기에 사용한다는 것을 인지했다.
- 이를 고려해 읽기 전용 복제본을 생성한다.
- RDS에서는 다섯 개의 일기 전용 복제본을 가질 수 있다.
Scaling Reads(Alternative) - Write Through
- 읽기 관련 성능을 향상 시키기 위해 캐시를 사용하는 쓰기 모드라는 선택지도 존재한다.
- 사용자가 EC2 인스턴스와 통신하는 방식으로 작동한다.
- 찾고자 하는 정보를 캐시에서 탐색한 뒤 존재하지 않는다면 RDS로부터 읽어 들여서 ElastiCache에 집어넣는다.
- 이 패턴을 통해 RDS 상의 트래픽을 줄일 수 있다. 그러나 캐시는 유지보수가 필요하다.
- 이는 꽤 어려운 일이고, 애플리케이션 쪽에서 이루어져야 한다.
Multi AZ - Survive Disasters
- 재해에 대비하여 Route 53와 통신하는 다중 AZ ELB를 도입한다.
- 또 다른 방법으로는 재해가 발생할 경우 인계 받을 있는 대기 복제본을 만들어둔다.
- Redis를 사용한다면 ElastiCache도 다중 AZ 기능을 갖을 수 있다.
Security Groups
- ELB쪽 어디에서나 HTTP, HTTPS 트래픽을 열 수 있다.
- EC2 인스턴스 측면에서는 로드 밸런서로부터 오는 트래픽만 받아들일 수 있도록 제한한다.
- ElastiCache 측면에서는 EC2 보안 그룹으로부터 오는 트래픽만 받아들 일 수 있게 제한한다.(RDS도 마찬가지)
최종 복습
- ELB Stickiness 도입 시 고려 사항.
- 쿠기 저장을 위한 웹 클라이언트 웹 앱을 무상태로 만드는 법.
- ElastiCache를 위한 세션 ID와 세션 캐시의 사용
- 세션 ID의 대안으로서의 DynamoDB
- 읽기의 경우 RDS로부터 데이터 캐시를 위해 ElastiCache 사용 방안
- 재해에 대비하기 위한 다중 AZ
- 사용자 데이터를 저장하기 위한 RDS의 사용
- 읽기 확장을 위한 읽기 전용 복제본의 사용
- 또는 ElastiCache
- 서로 참조하는 보안 그룹을 위한 철저한 보안 기능
세번째 아키텍처(Stateful Web App : MyWordPress.com)
전체 조건
- 완전히 확장 가능한 WordPress 웹사이트를 만들려고 한다.
- 해당 웹사이트에 접근하여 업로드한 그림이 바르게 나타나길 바란다.
- 사용자 데이터와 블로그 내용 등 모든게 MySQL 데이터베이스에 저장되어야 한다.
- 글로벌하게 확장하고 싶다.
RDS Layer
- 위의 이미지는 기존에 운영 중인 아키텍쳐의 구조이다.
- 첫번째로 할 일은 RDS가 있는 계층을 생성하는 것이다.
- 다중 AZ이고, 모든 EC2 인스턴스에 걸쳐 적용되고 있다.
Scaling with Aurora : Multi AZ & Read Replicas
- RDS 계층을 오로라 MySQL로 교체한다.
- 이를 통해 다중 AZ, 읽기 전용 복제본, 원한다면 글로벌 데이터베이스까지 적용할 수 있다.
- 또한 연산을 줄일 수 있다.
Storing images with EBS
- 이미지를 저장하기 위해 EC2인스턴스 하나와 Amazon EBS볼륨이 연결되어 있는 단일 AZ의 단순한 소룰션 아키텍쳐를 도입할 수 있다.
- 하지만 이러한 구조의 문제점은 아래와 같이 확장을 하여 EC2인스턴스와 EBS볼륨을 하나 더 연결 시켰을 경우 저장한 EBS 볼륨과 읽어올 볼륨 저장소가 일치 하지 않을 경우 이미지에 접근할 수 없다는 문제가 발생한다.
Storing images with EFS
- EFS를 활용해 네트워크 파일 시스템 드라이브를 사용하여 이전의 문제를 해결 할 수 있다.
- 스토리지가 모든 인스턴스에 공유된다
- EFS는 탄력적인 네트워크 인터페이스를 위해 각각 AZ에 ENI를 생성할 수 있다.
- 이 ENI는 EFS 드라이브에 접근하는 모든 EC2에 사용할 수 있다.
최종 복습
- 적은 연산량과 다중 AZ 및 읽기 전용 복제본을 갖춘 오로라 DB에 대해 검토
- 단일 인스턴스 애플리케이션에서 작동하는 EBS에 데이터를 저장하는 것에 대해 다룸
- 그러나 인스턴스가 많아지면 잘 작동하지 않음
- EFS를 사용하여 다중 AZ에 걸친 분산 애플리케이션을 만들 수 있다.
Instantiating Applications Quickly
- full stack(EC2, EBS, RDS)을 실행하면
- 애플리케이션 설치
- insert initial(or recovery) data
- Configure everything
- Launch the application
- 위와 같은 일련의 과정은 오랜 시간이 걸린다.
- 이러한 속도를 높이기 위해서 사용할 수 있는 클라우드의 장점이 있다
- EC2 Instances
- Golden AMI를 사용하여 이후의 EC2 인스턴스들을 Golden AMI로부터 직접 실행한다.(애플리케이션, OS 종속성 등을 재설치할 필요가 없기 때문이다.)
- Golden AMI : 애플리케이션과 OS 종속성 등 모든 것을 사전에 설치하고, 그것으로 부터 AMI를 생성하는 것.
- BootStrap using User Data(동적인 환경변수를 사용하기 위함, 애플리케이션과 OS 종속성을 설치할 수 있지만 각각의 인스턴스 마다 중복된 작업을 해줘야 하기 때문에 느리다.)
- BootStrapping : 인스턴스가 처음 시작될 때 구성하는 행위
- Hybrid : Golden AMI와 User Data를 같이 사용하는 것
- Golden AMI를 사용하여 이후의 EC2 인스턴스들을 Golden AMI로부터 직접 실행한다.(애플리케이션, OS 종속성 등을 재설치할 필요가 없기 때문이다.)
- RDS Database
- 스냅샷으로부터 복구를 통해 스키마와 데이터 준비하기
- EBS Volumes
- 스냅샷으로부터 복구를 통해 포맷된 디스크와 데이터를 준비할 수 있다.
- EC2 Instances
Elastic Beanstalk
- 개발자 입장에서 애플리케이션을 AWS에 배포할 수 있게 한다.
- 하나의 인터페이스에서 EC2, ASG, ELB, RDS 등 모든 컴포넌트를 사용한다.
- 관리자를 대신하여 모든것을 배포하는 관리형 서비스이다.
- 용량 프로비저닝, 로드 밸런서 설정, 스케일링, 애플리케이션 상태 모니터링, 인스턴스 설정 등
- 개발자는 코드 자체에만 집중할 수 있다.
- 물론 모든 컴포넌트 설정에 대해 완벽한 통제를 할 수 있다.
Elastic Beanstalk - Components
- Application : Elastic Beanstalk 구성요소의 집합체(environments, versions, configurations)로 구성됨
- Application Version : 애플리케이션의 버전은 사용자의 애플리케이션 버전과 같게 된다.
- Environment : 특정 애플리케이션 버전을 실행하는 리소스들의 컬렉션이다.
- 어떤 환경에서 한번에 하나의 애플리케이션 버전만 가질 수 있다. 하지만 애플리케이션 버전을 버전1에서 버전2로 업데이트 할 수 있다.
- Tiers : 웹 서버 환경 티어와 워커 환경 티어가 있다.
- dev, test, prod 같은 다양한 환경을 만들 수 있다.
Web Server Tier vs Worker Tier
- Web Server Tier
- 로드 밸런서가 있고, 웹 서버가 될 수 있는 EC2 인스턴스가 있는 전통적인 아키텍쳐이다.
- Worker Tier
- EC2 인스턴스에 직접적으로 액세스하는 클라이언트가 없다.
- 메시지 대기열인 SQS Queue를 사용한다.
- EC2 인스턴스들이 메시지를 SQS Queue에서 가져와서 처리한다.
- 워커 환경은 SQS 메시지의 개수에 따라 스케일링 된다.
- 웹 환경이 메시지를 워커 환경의 SQS Queue에 푸시하게 함으로써 웹 환경과 워커 환경을 하나로 모을 수 있다.