Github Actions & Nginx를 이용한 CI/CD 무중단 배포 자동화 구축 - EC2 & S3 설정

DevSeoRex·2023년 5월 13일
22

😂 이번 프로젝트까지 수동 배포로 가긴 그렇잖아..

두 번의 프로젝트를 진행하는 동안, 항상 수동으로 배포를 하곤 했습니다.
AWS에 EC2 인스턴스를 만들고, 인스턴스에 접근해서 프로젝트를 빌드한 war 파일을 옮겨서 실행시키는 방법으로 배포를 했습니다.

그 당시에는 SSR 방식으로 로컬에서 프론트까지 전부 개발하고 있었기때문에 이런 방식이 불편하지 않았습니다. 하지만 이번에 프로젝트는 프론트 개발자분들과 협업해야 되기 때문에 새로운 배포 방식을 고민하게 되었습니다.

🤔 어떻게 배포해야 할까?

Github에서 특정 이벤트(push, pull-request)가 발생했을때, 빌드와 배포를 해주는 대표적인 툴로는 두가지를 생각해볼 수 있습니다. JenkinsGithub Actions가 push된 코드를 빌드하고 S3에 업로드 후 배포까지 진행하는 방법이 있습니다.

Jenkins와 Github Actions 그러면 어떤 것을 사용할지 고민했습니다.
프로젝트를 진행하면서 서버 비용을 고려하지 않을 수 없었습니다. 가용할 수 있는 EC2 인스턴스는 저희 팀원 인원수와 같기 때문에 총 4개의 인스턴스를 사용할 수 있었습니다.

그러면 몇개의 인스턴스가 필요할 지 생각을 해보았습니다.
프론트 개발자분들이 사용할 EC2 Next.js 서버가 한개 있어야 하고,
MySQL 두개를 올려서 사용할 EC2 한개가 필요했습니다. 거기에 Spring Boot 프로젝트를 배포하고 Redis를 올려둘 인스턴스 한개 총 3개의 인스턴스가 필요했습니다.

팀원들과 토론을 통하여 얻은 결론은, 추가적인 서버를 증설하지 않고 사용할 수 있는 Github Actions를 통한 CI/CD 구축을 해보자는 결론이 나왔습니다.

😇 시스템 아키텍쳐를 어떤 구조로 구성할까?

Github Actions를 이용한 CI/CD 구축에도 사용할 수 있는 기술은 여러개가 있고 그 과정과 방법이 달라서 어떻게 배포를 진행할건지 논의를 해본결과, 아래와 같은 시스템 아키텍쳐를 가져가게 되었습니다.

Github에서 main branch로 push(merge)가 일어나게 되면, Github Actions를 이용해 배포를 진행하게 됩니다. 빌드 성공과 실패 여부에 관계없이 Slack을 통한 알림을 받을 수 있도록 설정하였습니다.

Github Actions를 통해 성공적으로 배포된 프로젝트는 AWS S3에 업로드 되게 되고, Github Actions는 CodeDeploy에 배포를 요청하고, CodeDeploy는 S3로 부터 빌드 파일을 요청하고 응답받게 됩니다.

CodeDeploy는 EC2에 설치된 AWS CodeDeployAgent를 통해 배포를 진행하게 되고, 이 과정에서 실제 배포가 수행되게 됩니다.

전체적인 배포는 이렇게 진행이 되고, 배포 전략은 blue/green 전략으로 채택하게 되었습니다.
배포를 시작할때 현재 실행중인 애플리케이션을 종료하게 되면, 유저는 해당 애플리케이션이 종료 됨으로 인하여 불편을 겪을 수 있습니다.

현재 최신 버전을 배포하면서, 배포가 완료되면 현재 실행중이던 애플리케이션을 종료시켜서 사용자에게 중단이 일어나지 않는 것처럼 불편을 주지 않을 수 있었습니다.

Nginx를 이용하여 현재 실행중인 애플리케이션에 접근할 수 있도록 로드 밸런싱을 사용하였습니다.

추가적으로 Spring Boot와 Redis를 docker-compose를 이용해서 실행시키도록 도입하였고, MySQL Replication을 이용한 Master-Slave 분기 구조를 도입 하였습니다.

배포와 관련되지 않은 다른 부분은 추가적인 포스팅을 통해 작성하도록 하겠습니다.

🐶 EC2 인스턴스 만들기

가장 먼저, Spring Boot 애플리케이션과, Redis 그리고 CodeDeployAgent와 같은 배포를 위한 도구들을 설치할 메인 인스턴스를 하나 만들어주겠습니다.

  • Amazon 리눅스를 선택합니다.
  • 인스턴스 유형을 프리티어인 t2.micro로 설정해줍니다.
  • 인스턴스 접속에 필요한 키 페어를 설정해줍니다. RSA 암호화 방식의 .pem 파일을 사용합니다.
  • 네트워크 구성 및 세부 구성을 설정해줍니다(저는 기존에 사용하던 보안그룹을 사용했습니다)
  • 추가 설정에 사용해야 하는 인스턴스의 태그를 만들어 줍니다.

지금 한 작업들을 통해서 EC2 인스턴스가 만들어졌습니다.
EC2에 접속하기 위해서 아래와 같은 명령어를 입력하면 서버에 접속할 수 있습니다.

$ sudo ssh -i <key 이름> ec2-user@아이피 주소(퍼블릭 IP)

퍼블릭 아이피 주소는 EC2 대시보드에서 확인이 가능합니다.

접속은 가능하지만 매번 이렇게 사용하는 것은 너무 불편해서 어떻게 간소화 할 방법이 없을까 고민했는데 역시 방법은 있었습니다.

🧚 EC2 조금 더 편안하게 접속해보기

EC2 인스턴스를 만들때 내려받은 pem 확장자의 키 파일을 이용해서 좀 더 쉽게 접속이 가능하도록 설정 해보겠습니다.

  • 접속 간소화 설정을 위한 디렉토리로 이동합니다.
$ chmod 735 cd ~/.ssh/
  • config 파일을 만들고 문서 편집기로 열어줍니다.
$ vi ./config


vi로 문서 편집기를 열면 수정이 안되기 때문에 아래와 같이 수정 모드로 설정을 해야합니다.
i를 입력하면 insert 모드로 변경되어 수정이 가능해집니다.

  • config 파일의 내용을 수정합니다.
Host {사용할 서비스 이름 - 외우기 쉬운 단어로 자유롭게 설정}
HostName { AWS 퍼블릭 IP 또는 탄력적 IP }
User ec2-user
IdentityFile ~/.ssh/server_key.pem

IdentityFile의 경로에 현재 server_key.pem 파일이 없기 때문에 복사해줍니다.

  • 키 파일을 ~/.ssh/ 경로로 이동시켜 줍니다.
// 키 파일의 경로까지 이동
cd {키 파일의 경로 -> ex) /desktop/server_key}

// 키 파일을 ~/.ssh/ 경로로 복사
cp server_key.pem ~/.ssh/
  • ssh {호스트 이름} 으로 서버에 접속이 가능합니다.

👀 프로젝트 업로드용 S3 버킷 생성

Github Actions에서 빌드된 프로젝트 업로드용 S3 버킷을 생성하겠습니다.

  • S3 서비스에 들어가서 버킷 만들기를 클릭하고 버킷의 이름을 설정합니다.
  • 체크된 디폴트 값인 모든 퍼블릭 액세스 차단을 그대로 두고 다음으로 넘어갑니다.

👏 AWS IAM 권한 사용자 설정

  • 사용자를 추가해줍니다.
  • 권한 정책을 설정해줍니다(AWSCodeDeployFullAccess 와 AmazonS3FullAccess를 선택)
  • 사용자 > 보안자격증명 메뉴에서 액세스 키 만들기를 진행합니다.
  • 생성된 액세스키와 비밀 액세스키를 잘 보관합니다(이 페이지를 벗어나면 다시 계정을 만들어야 합니다)

⚽ 약간의 TMI 트러블슈팅!

AWS에서 제공하는 pem 형식의 key 파일의 내용을 복사해야 할때 linux 환경에서는 cat 명령어를 사용할 수 있습니다.

또는 VS code로 열어보면 내용을 확인할 수 있는데,

-----BEGIN RSA PRIVATE KEY-----
d10rDJAgi7MW/EuuqA1HduAX9h1riVXMPvQA1OxxvD+ec5
02kB
K4sZkLcCgYEAma5YvBZ9ZrjqMEpVMjw7RDz49
-----END RSA PRIVATE KEY-----

이 코드를 전부 복사해서 넣어줘야 동작합니다.
첫번째 줄과 마지막 줄의 코드를 의미 없는 코드인 줄 알고 빼고 넣었더니 계속 에러를 겪는 문제가 생겨서 잠시 TMI..를 풀어 보았습니다.

🐈 다음으로..

지금까지 채택하게 된 시스템 아키텍쳐와, 그 기술을 채택한 이유를 설명하고 AWS EC2와 S3그리고 IAM 사용자 설정을 완료했습니다. 배포 자동화를 하려면 설정이 거의 반인데 이미 반을 지나가고 있습니다!

다음 포스팅에서는 나머지 설정을 하는 방법에 대해 포스팅 하겠습니다.

읽어주신 분들께 감사드립니다!

다음 시리즈 게시글
Github Actions & Nginx를 이용한 CI/CD 무중단 배포 자동화 구축 - 나머지 설정과 Github Actions 셋팅
다음 시리즈 게시글로 이동 ->

🙇

3개의 댓글

comment-user-thumbnail
2023년 5월 16일

혹시 맨 처음 사진에 모식도는 어떤 프로그램으로 만드신건가요?

1개의 답글
comment-user-thumbnail
2023년 5월 20일

크...개판데렉서

답글 달기