SKKUDING 멤버 모두가 현재 진행되고 있는 프로젝트 시스템의 구성 및 배포에 대해 충분히 공유되었으면 좋겠다는 바람을 담아 제작하였습니다. 모르는 것이 있거나, 제안해주실 것이 있다면 부담없이 같이 이야기하며 공부해보아요~! -김태훈
분리된 가상 사설 네트워크 환경입니다. Private IP를 사용해야 하므로, 10.X.X.X, 172.16~31.X.X, 192.168.X.X 영역을 사용합니다. 외부 네트워크로부터 보안을 유지합니다.
설정한 VPC 안에서는, VPC네트워크로 설정한 IP대역 안에서, 배포를 하고자 하는 여러 어플리케이션의 IP대역을 따로 설정해주어야 합니다. 이 과정을 Subnetting 이라고 합니다. 예를들어, 10.0.0.0/24 로 VPC 네트워크 IP대역을 설정했다면, 10.0.0.0/26, 10.0.0.64/26, 10.0.0.128/26, 10.0.0.192/26 의 4개의 IP대역으로 Subnetting 할 수 있을 것입니다.
하지만 VPC안에 배포해야 하는 요소들은 외부에서 자유롭게 사용할 수 있는 것들(웹 서버) , 외부에서 접근하지 못하게 해야하는 민감한 것들 (DB)가 있습니다. 그래서 이러한 것들을 고려하여 분리하는 것이 Subnet 영역입니다.
Subnet 영역은 Public, Private 두가지로 나뉩니다. 외부에 접근을 허용하는 것을 Public Subnet으로, 허용하지 못하게 하는 것은 Private Subnet으로 나누어야 합니다. 한가지 유의해야할 점은 하나의 Subnet영역은 하나의 Availability Zone에 위치해야 한다는 점입니다.
그렇다면 VPC의 사설 네트워크를 사용하고 있는데, Public Subnet으로 배포를 한다고 한들, 어떻게 외부에서 허용이 가능할까요?
이는 바로 Internet Gateway의 역할이 있기 때문입니다.
인터넷 게이트웨이는 VPC와 외부 인터넷과의 통신을 담당합니다.
저희가 Public Subnet에 포함시킨 어플리케이션들은 모두 IGW와 연결되어야함은 당연합니다. 외부와 통신할 수 있는 통로가 있어야 하기 때문입니다.
그래서, 라우팅 테이블을 만들때, IGW도 반드시 포함을 시켜야 합니다. IGW는 외부에서 VPC에 접속할 수 있는 Public IP와 내부 Public Subnet의 Private IP (외부에서 접속을 허용해야 하는 어플리케이션의 Private IP를 말함) 를 Translate하기 때문입니다. 라우팅 테이블에 IGW가 없으면, 어떤 Private IP가 VPC IP와 연관이 되어있는지 모르겠죠?
NAT도 추후에 살펴보겠습니다.
저희 서비스의 주가 되는 배포 환경이라고 할 수 있습니다. ECS는 도커 이미지를 활용하여 만들어진 컨테이너화된 어플리케이션을 보다 쉽게 배포하고, 관리하는 오케스트레이션 AWS 서비스입니다. 오케트스트레이션이라는 낯선 용어를 이해하기보다, 그냥 복잡한 배포 환경을 관리하기 쉽게 해주는 서비스라고 가볍게 생각하시면 됩니다.
저희가 배포해야할 것은 세가지라고 할 수 있습니다.
Nginx (웹서버)
Nest.js (백엔드)
Iris (채점서버)
각각의 개발사항을 담은 도커 이미지를 빌드하여, 컨테이너를 격리시켜야 합니다.
위 그림은, ECS의 기본구조에 대한 그림인데요. 기본적으로 ECS는 Cluster를 정의하는 것 부터 시작합니다. 이는 도커 컨테이너를 실행할 수 있는 논리적인 공간입니다. 도커 컨테이너를 띄우기 위해서는 도커가 설치된 인스턴스가 반드시 필요합니다. 백엔드 개발환경(Nest.js) 를 만들기 위해 EC2 인스턴스에 Nest관련 패키지를 다운로드해야 개발할 수 있는 것처럼, 도커 컨테이너를 띄우기 위해서는 도커가 설치된 인스턴스가 필요합니다. 이러한 인스턴스를 클러스터라고 부릅니다.
저희는 이 인스턴스로 Fargate(VM)를 사용합니다. EC2를 사용할 수도 있겠지만, EC2는 CPU,RAM,메모리에서 한계가 정해져 있으므로 트래픽이 몰리면, EC2가 EC2를 부르면서 여러 신경써야할 점이 많습니다. 그러므로 저희는 Fargate를 사용하여, 이러한 관리의 부담을 덜기로 했습니다. (지갑은 아파요)
다음으로는 Task를 정의해야 합니다. Task란 컨테이너를 실행하는 최소 단위를 말합니다.애플리케이션을 구성하는 파라미터와 하나 이상의 컨테이너를 설명하는 JSON 형식의 텍스트 파일입니다 (AWS왈).
태스크에서 사용할 도커 이미지나, 태스크에서 사용하는 CPU의 양과 같은 인프라적인 측면에 관한 정보, 컨테이너 죽으면 다시 재시작 할지 말지와 같은 정보들을 직접 정의할 수 있습니다.
마지막으로는 Service입니다. Task를 실행하기 위해 Service를 이용합니다. ALB같은 AWS 서비스를 사용하여, 원하는 태스크의 수를 유지하는 일들을 설정할 수 있습니다.
Frontend 의 빌드 파일을 저장할 용도로 S3를 사용합니다.
DB를 위한 AWS 서비스로 RDS를 사용합니다. 그림에 표시된 3번,5번,6번을 보시면 같은 Private Subnet에 묶여있는 것을 볼 수 있습니다. VPC에 대한 설명을 다시 읽어보시면 아시겠지만, 하나의 Subnet에는 반드시 하나의 AZ만 존재해야 합니다. 특히 DB같은 경우에는 고가용성이 중요합니다. 만약 DB가 하나의 AZ에만 할당이 되어있었고, AZ를 담당하는 서버가 죽으면 많이 곤란해질 것입니다.
따라서 저희는 ECS,RDS,Cache 관련 서비스를 여러 AZ에 포함시키기 위해 AZ의 개수만큼 Private Subnet을 설정하여 해당 서비스들을 하나의 Subnet에 포함하여 배포할 예정입니다.
Redis 사용예정
Judge 서버 연동을 위하여 MQ를 사용합니다. 트래픽도 트래픽이지만, 교내 서버를 이용하기에는 MQ가 좋다고 합니다.
저희 교내 물리 서버에요.
멋있어요!