시스템 아키텍쳐
해당 프로젝트에서 사용한 시스템 아키텍쳐는 다음과 같다.
1. 개발자가 코드를 수정하고, 배포를 원하는 브랜치로 Github에 Push한다.
2. Github Actions에서 정해진 워크플로우에 따라 두 가지 작업을 수행한다.
(1) CodeDeploy에 배포 요청을 보낸다.
(2) Gradle 빌드를 수행한 후 생성된 jar 파일을 S3 버킷에 저장한다.
3. 배포 요청을 받게 되면, CodeDeploy Agent (배포 작업을 수행하는 프로그램) 가 EC2 서버 내에서 개발자가 직접 작성한 appspec.yml를 스캔 후 빌드 스크립트를 실행하게 된다.
4. 빌드 스크립트 내에서 두 개의 포트를 번갈아가며 스위칭하여, 블루/그린 배포를 수행한다. 이 결과 8081 포트가 작동 중일 때는 8082에 새 버전의 프로젝트가 올라가고, 짧은 시간에 nginx가 가리키는 포트가 8082 포트로 변경되어 사용자 입장에서 끊김없이 작업을 수행할 수 있게 된다.
블루/그린 배포란 ?
Blue/Green 무중단 배포란, 새로운 버전을 새로운 인스턴스에 배포하고, 배포 일정이 되면 이전 버전의 트래픽을 새로운 버전으로 일제히 전환하는 무중단 배포 전략입니다. 이전 버전을 Blue, 새로운 버전을 Green이라고 칭합니다.
이번 포스팅에서는, 배포하는 것에 필요한 자원들을 모두 생성하고 설정해보겠다. 포스팅 내에서는 처음 배포해보거나 서버를 처음 다뤄보는 사람도 따라할 수 있을 정도로 자세하게 설명할 예정이나, 혹시 빠뜨린 부분이 있다면 적극적으로 지적해주시길 바란다.
1. EC2 생성
나는 프리티어 버전인 Ubuntu 22.04 LTS, amd64, t2.micro 인스턴스로 생성하였다.
키 페어 생성 후 로컬 PC에 저장한다. 키 페어는 Ubuntu 서버에 접속 시 꼭 필요하므로 잘 보관하도록 한다.
네트워크 설정에 대해서는 나중에 자세히 설명하겠다. 우선 '보안 그룹 생성'에 체크하고 넘어가자.
나머지는 모두 기본값으로 설정하고 '인스턴스 시작'을 누르면 2-3분 내에 인스턴스가 실행 중으로 뜬다.
2. 보안 그룹 설정
보안 그룹이란, 인스턴스에 대한 인바운드 규칙과 아웃바운드 규칙을 정의하고 외부 접근을 허용하거나 제한하는 가상 방화벽이다. 즉 외부에서 인스턴스에 접근하려면, 접근하려는 포트가 인바운드 규칙에 정의되어있어야 하고 인스턴스에서 외부 서버로 접근하려면 그 포트 역시 아웃바운드 규칙에 정의되어있어야 한다.
위에서 생성한 EC2 서버와 보안 그룹을 연결하면 서버의 인바운드, 아웃바운드 규칙을 정의할 수 있다.
먼저 보안 그룹 메뉴로 들어간다.
위에서 생성한 보안 그룹의 이름을 선택하고, '인바운드 규칙 편집' 버튼을 누른다.
그리고 아래와 같이 인바운드 규칙을 설정한다.
22 포트는 Ubuntu 서버에 SSH 프로토콜로 접속하기 위해 열어놓은 것이고, 443 포트는 HTTPS URL의 접근을, 80 포트는 HTTP URL의 접근을 허용하기 위해 열어놓았다.
또한, Spring Boot 애플리케이션을 무중단 배포하기 위해 사용할 두 포트인 8081, 8082 포트도 추가적으로 열어놓았다.
3. 탄력적 IP 생성 후 연결
현재 인스턴스에 접속하기 위해서는 서버의 IP주소가 필요하다. 그러나 이 때의 IP는 고정 IP로, 인스턴스가 재실행될 때마다 IP 주소는 계속 달라지게 되는데, 추후 도메인을 구매하고 서버와 연결하기 위해서는 탄력적 IP(Elastic IP, EIP)가 필요하다.
탄력적 IP란 ?
하나의 인스턴스에 부여되는 고정 퍼블릭 IPv4 주소이다. 현재 IPv6에는 탄력적 IP주소를 지원하고 있지 않으며, 탄력적 IP주소를 인스턴스나 네트워크 인터페이스에 연결하지 않고 사용하면 요금이 부과될 수 있으므로 주의해야 한다.
탄력적 IP 메뉴에 들어간 후, '탄력적 IP 주소 할당' 버튼을 클릭한다.
네트워크 경계 그룹을 'ap-northeast-2'로 설정해준 후, 별다른 설정을 하지 않고 바로 탄력적 IP주소를 생성한다.
이후 생성된 탄력적 IP를 선택하고, 작업 > 탄력적 IP주소 연결 탭을 누른다.
그러면 이렇게 탄력적 IP주소를 연결할 EC2 서버 중에서 IP 주소로 접속할 인스턴스를 선택할 수 있다.
여기까지 인스턴스에 대한 설정이 끝났다.
다음으로는 CodeDeploy와 S3를 생성하고 EC2 서버와 연동해서 사용할 수 있도록 설정해보겠다.
4. CodeDeploy 애플리케이션 생성
CodeDeploy 메뉴를 누르게 되면 아래와 같이 애플리케이션을 생성하는 버튼이 뜬다.
아래와 같이 설정하고 애플리케이션을 바로 생성해준다.
생성한 애플리케이션은 왼쪽 사이드바에서 배포 > 애플리케이션 탭에서 확인 가능하다.
이후 배포 그룹을 설정해야하는데, 이는 IAM 사용자의 역할이 필요한 단계이므로 이후에서 다시 소개하겠다.
5. Amazon S3 버킷 생성하기
Amazon S3 (Simple Storage Service) 란 ?
영어 이름에서 설명한 것처럼 AWS의 하나의 저장소 서비스라고 할 수 있다. 주요 개념으로는 Object (객체)와 Bucket (버킷)이 있다. 객체는 파일과 해당 파일에 대한 메타 데이터로 구성되며, 버킷은 객체를 담기 위한 하나의 컨테이너와 같은 것으로 최대 100개까지의 버킷을 가질 수 있다 .
S3 메뉴에 들어가서 '버킷 만들기'를 선택한다.
버킷 이름을 입력하고, 모든 설정을 Default로 두고 바로 생성해준다.
S3 버킷에 대해서는 사용자의 역할 (Role)을 만들어서 접근 권한을 관리할 예정이다. 따라서 퍼블릭 액세스를 모두 차단해준다.
S3 버킷까지 생성해주었다면, 배포 단계에서 권한을 부여하기 위한 IAM 사용자를 만들고 각각의 프로그램에 권한을 부여해주자.
6. IAM 사용자 생성
IAM이란 ?
IAM (Identity and Access Management) 는 AWS 서비스를 사용할 가상 사용자를 생성하고, 이러한 사용자를 그룹으로 구성하여 공통된 권한을 쉽게 관리하기 위해 만들어진 서비스이다. 위에서 생성한 Code Deploy와 S3에 권한을 가지고 액세스 하기 위해서는 임시 보안 자격 증명을 부여하는 역할(role)을 만들 수 있다.
IAM 탭에 들어가 액세스 관리 > 사용자 메뉴로 들어간다.
'사용자 생성' 버튼을 누른 뒤, 사용자 이름을 입력하고 '다음' 버튼을 누른다.
이 단계에서 '직접 정책 연결'을 선택하고 AmazonS3FullAccess와 AWSCodeDeployFullAccess으로 권한 정책을 세팅한다. 다음 단계를 누르면 아래 화면처럼 내가 입력한 정보가 뜨고, 확인 후 생성을 누른다.
이렇게 생성하고 나면 이 사용자로 AWS 서비스에 로그인 하기 위해서 액세스 키와 비밀 액세스 키를 발급받아야 한다.
생성된 사용자의 상세 페이지에 들어가서, 아래로 내려 '액세스 키' 탭을 찾는다.
위 사진에서 '액세스 키 만들기'버튼을 누르면 이런 페이지가 뜨고, 액세스 키와 비밀 키를 생성하기 위해 Command Line Interface 사용 사례를 선택한다.
설명 태그 설정을 건너뛰면 아래와 같이 액세스 키가 뜨게 되는데, 액세스 키 IP와 비밀 액세스 키가 뜨는데, 이는 최초 1회 발급이므로 꼭 따로 기록해두거나 CSV 를 다운로드하여 보관하기 바란다.
7. IAM 사용자 역할 생성
CodeDeploy와 S3 리소스에 접근하기 위한 IAM 사용자 역할을 생성하자.
역할(role)이란?
위에서 생성한 IAM 권한 사용자가 S3, CodeDeploy 서비스에 접근할 수 있도록 권한 정책을 부여하는 것이다. IAM 사용자는 AWS 서비스에 대한 액세스를 위해 생성하는 자격이기 때문에 AWS에 로그인하고 서비스를 영구적으로 이용할 수 있는 반면에, IAM 역할은 특정 사람을 가정한 것이 아닌 필요에 따라 임시로 특정 권한을 얻을 수 있는 임시 보안 정책이다.
EC2 IAM 역할 생성하기
EC2 서버에서 S3 버킷과 CodeDeploy에 접근하기 위해서는 인스턴스에 IAM 역할을 부여할 필요가 있다.
아래와 같은 과정으로 역할을 생성하고 인스턴스에 등록해보자.
액세스 관리 > 역할 탭에 들어가 '역할 만들기'를 클릭한다.
사용 사례에서 EC2를 선택하고 다음으로 넘어간다.
다음 단계에서 AmazonS3FullAccess와, AwsCodeDeployFullAccess를 검색 후 체크하고 다음 단계로 넘어오면, 역할 이름과 추가한 권한을 확인할 수 있다.
역할을 생성하였다면, EC2 대시보드로 접속해 아래와 같이 인스턴스의 역할을 설정한다.
인스턴스 우클릭 > 보안 > IAM 역할 수정 탭에 들어가서 아래와 같이 생성한 역할로 업데이트한다.
이 과정을 통해 EC2 인스턴스에서 S3, CodeDeploy의 리소스에 접근이 가능해졌다!
CodeDeploy IAM 역할 생성하기
CodeDeploy에 AWSCodeDeployRole을 부여해서 EC2 인스턴스에 대한 Read, Write 권한과 S3버킷에서 객체를 읽는 권한 등을 허용해보자.
사용 사례에서 CodeDeploy를 찾아 선택하고, 세 가지 유형 중에서 "CodeDeploy"를 선택 후 다음으로 넘어간다.
위와 같이 세팅하면 기본적으로 주어지는 권한 정책을 그대로 유지하며 '다음'을 누른다.
다음 화면에서도 별다른 설정 없이 역할 이름을 기입하고 CodeDeploy 접근용 IAM 역할을 최종 생성한다.
이렇게 생성한 CodeDeploy IAM 역할을 이용해 CodeDeploy 애플리케이션에서 배포 그룹을 설정해보자.
배포 그룹이란 ?
배포를 수행할 인스턴스 집합을 의미한다. 특정 인스턴스를 지목해 배포를 수행할 때 배포 그룹을 생성해서 태그 그룹을 설정하는 방식으로 소프트웨어를 배포하게 되는 것이다. IAM 사용자는 AWS 서비스에 대한 액세스를 위해 생성하는 자격이기 때문에 AWS에 로그인하고 서비스를 영구적으로 이용할 수 있는 반면에, IAM 역할은 특정 사람을 가정한 것이 아닌 필요에 따라 임시로 특정 권한을 얻을 수 있는 임시 보안 정책이다.
이전에 생성한 CodeDeploy 애플리케이션 상세 페이지로 접속하자. 아래 화면에서 '배포 그룹 생성' 버튼을 누른다.
배포 그룹의 이름을 설정하고, 서비스 역할로 방금 생성한 CodeDeploy 역할을 선택한다.
하나의 인스턴스로 배포할 예정이기 때문에 '현재 위치'를 선택한다.
EC2 인스턴스에 배포하기 위해서 환경 구성 탭에서 'Amazon EC2 인스턴스'를 선택하고, 위에서 생성한 EC2 서버를 등록한다.
AWS CodeDeploy Agent은 EC2 서버에서 따로 설치하여 진행하기 때문에 설치하지 않고, 배포 시 한 번에 배포를 끝낼 수 있도록 CodeDeployDefault.AllAtOnce로 배포 구성을 선택한다. 마찬가지로 하나의 인스턴스로 동작하기 때문에 로드 밸런싱은 두지 않는다.
배포 그룹을 생성하면 CodeDeploy와 관련된 모든 설정이 끝난다.
여기까지 배포 과정에서 필요한 모든 AWS 서비스를 생성하고 권한을 적절하게 부여하였다.
다음 포스팅에서는 Github Actions를 동작시킬 워크플로우를 생성하고, CodeDeploy와 S3를 자동으로 동작시켜 EC2 서버에서 배포를 수행할 수 있도록 코드를 작성하는 실습을 해보겠다.
포스팅에 잘못 기입된 부분이 있다면 댓글로 알려주시면 감사하겠습니다 ! 😊
'Server > Architecture' 카테고리의 다른 글
Github Actions + Code Deploy + S3 + NginX 로 Spring Boot 블루/그린 무중단 배포 구현하기 (3) (0) | 2023.08.28 |
---|---|
Github Actions + Code Deploy + S3 + NginX로 Spring Boot 블루/그린 무중단 배포 구현하기 (2) (0) | 2023.08.27 |
[MSA] 터빈 서버 (Turbine Server)로 Hystrix Client 메시지 수집하기 (0) | 2023.03.28 |
[MSA] Spring Cloud Config Server 구축 및 profiles 설정 (2) | 2023.03.27 |
[MSA] 유레카(Eureka)서버, 줄(Zuul) 서버 설정 및 구동하기 (0) | 2023.03.24 |