본문 바로가기

[Project] 프로젝트 삽질기34 (feat AWS EB, Docker)

어가며

사이드 프로젝트에서 푸시 알림을 활용한 서비스를 개발하고 있습니다. 프로젝트에서 저는 비즈니스 로직에만 집중했습니다. 그러다 보니 현재 서비스가 어떻게 배포되고 있는지 정확하게 알 수 없었습니다. 이번 기회에 프로젝트가 어떤 과정을 통해 배포되고 있는지 알아야겠다고 생각했습니다. 이 글을 통해 AWS EB, Docker, Github Action을 활용하여 배포한 과정을 정리하려 합니다. 

 
 
 

 
 
 
 
 

 

 

 

 

 

AWS Elastic Beanstalk

AWS Elastic Beanstalk을 활용하면 용량 프로비저닝, 로드 밸런싱, 애플리케이션 상태 모니터링 등을 자동으로 처리합니다. EB를 활용하지 않으면 EC2를 별도로 설정해서, 로드 밸런서 등을 수동으로 모두 세팅해야 하지만, EB를 활용하면 완전 관리형이기 때문에 쉽고 빠르게 설정할 수 있다는 장점이 있습니다. 또한 다양한 배포 방식을 제공한다는 점이 큰 장점입니다. 만약 수동 제어가 필요하다면, 수동 제어 또한 가능하며 EB를 활용하는데 추가 요금이 들어가지 않는 것도 큰 장점입니다. 

 

 

EB를 활용하면 EC2에 플랫폼을 별도로 설치하지 않아도 원하는 플랫폼을 버전과 함께 지정하면 알아서 설치해줍니다. 원래 EC2를 기본적으로 설정하고 Node.js를 활용하려면 Node.js를 별도로 설치해줘야 하지만 EB를 활용하면 그러지 않아도 됩니다. 또한 작업하고 있는 코드를 압축해서 EB에 업로드하면 바로 EC2에 배포가 가능합니다. 그리고 배포 중 문제가 생길 시 즉각 롤백이 가능합니다. 

 

 

 

AWS EB에서 Docker 활용하기

AWS EB에서는 Docker 컨테이너에서 웹 애플리케이션의 배포를 지원합니다. Docker를 통해 현재 버전의 애플리케이션과 AWS EB에서 운용할 수 있는 애플리케이션을 동일하게 운영할 수 있습니다. AWS EB에서 Docker를 활용하는 방법은 코드가 저장된 디렉터리에 Docker 파일이 있으면, 그 파일을 기준으로 EC2에 Docker 컨테이너가 생성되며 서버가 배포됩니다.

 

 

 

 

 

 

AWS EB와 Github Action 활용하기

저는 AWS EB와 Github Action을 활용하여 자동 배포할 수 있게끔 설정했습니다. AWS EB만 활용할 경우 매번 수정된 코드를 수동으로 업로드해줘야 합니다. 이 번거로움을 해결하기 위해 Github Action을 활용했습니다. 위 사진처럼 main에 코드가 합쳐지면, Github Action을 통해 AWS S3로 코드가 저장되며, S3에 저장된 코드를 통해 AWS EB에서 배포되도록 설정했습니다. 

 

 

name: Deploy Docker
on:
  push:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout source code
        uses: actions/checkout@v2

      - name: Create env
        run: |
          touch .env
          echo NODE_ENV=production >> .env
          echo PORT=${{ secrets.PORT }} >> .env

          cat .env

      - name: Generate deployment package
        run: zip -r deploy.zip . -x '*.git*' -x node_modules/\*

      - name: Deploy to EB
        uses: einaregilsson/beanstalk-deploy@v14
        with:
          aws_access_key: ${{ secrets.AWS_PROD_ACCESS_KEY }}
          aws_secret_key: ${{ secrets.AWS_PROD_SECRET_KEY }}
          application_name: ${{ secrets.AWS_PROD_APPLICATION_NAME }}
          environment_name: ${{ secrets.AWS_PROD_ENV_NAME }}
          region: ${{ secrets.AWS_REGION }}
          version_label: triple-deploy-${{ github.sha }}
          deployment_package: deploy.zip

      - name: Success
        run: echo deployed successfully.

 

 

Github Action 코드를 보면, master branch에 push 됐을 때 아래의 jobs가 실행됩니다. Github Action 환경은 ubuntu-latest를 활용했고 actions/checkout@v2는 Workflow에서 접근할 수 있는 리포지토리의 파일을 받아오는 데 사용되는 공식 Github 작업입니다.

 

 

 

 

 

그 후 아래에서 Create env를 통해 배포에 필요한 환경 변수를 생성합니다. 환경 변수는 Github 리포지토리의 Settings의 Secrets에서 설정했습니다. 

 

 

- name: Generate deployment package
        run: zip -r deploy.zip . -x '*.git*' -x node_modules/\*

 

그 후 현재 환경을 압축하는 설정을 추가했습니다.

 

 

- name: Deploy to EB
        uses: einaregilsson/beanstalk-deploy@v14
        with:
          aws_access_key: ${{ secrets.AWS_PROD_ACCESS_KEY }}
          aws_secret_key: ${{ secrets.AWS_PROD_SECRET_KEY }}
          application_name: ${{ secrets.AWS_PROD_APPLICATION_NAME }}
          environment_name: ${{ secrets.AWS_PROD_ENV_NAME }}
          region: ${{ secrets.AWS_REGION }}
          version_label: triple-deploy-${{ github.sha }}
          deployment_package: deploy.zip

 

 

마지막으로 AWS S3에 압축한 파일을 저장 후 AWS EB에 업로드하는 환경을 추가했습니다.

 

 

 

aws_access_key와 aws_secret_key는 AWS IAM 계정에서 설정 후 추가해야 합니다. 저는 AWS EB의 모든 권한을 주고, 사용자 만들기를 추가한 후 각각의 키를 얻을 수 있었습니다. 

 

 

 

 

 

 

또한 application_name은 위 사진에서 보이는 Triple을 넣어주면 되며, environment_name은 환경 이름인 Triple-env를 설정했습니다. 이렇게 설정하고, Github의 master 브랜치에 push를 하면 자동으로 배포되는 시스템을 구축했습니다.

 

 

만약 PM2를 활용하고 있다면, scripts 부분에 start와 poststart를 반드시 명시해야 합니다.

 

"start": "node ./node_modules/pm2/bin/pm2 start ./dist/app.js --name server",
"poststart": "node ./node_modules/pm2/bin/pm2 logs",

 

 

또한 AWS EB를 통해 생성한 EC2에 직접 접근하려 한다면 EC2 Key pair가 필요합니다. 이를 어떻게 만들 수 있는지 알아보겠습니다. AWS EC2에 접속하고 사이드 바의 키 페어를 클릭합니다. 그 후 우측 상단의 키 페어 생성을 누릅니다. 

 

 

 

 

그 후 키 페어 이름을 적어서 생성하면 마무리됩니다. 

 

 

 

 

 

 

 

AWS EB 배포 방식

AWS EB에는 여러 가지 배포 방식이 존재합니다. 저는 단일 인스턴스를 활용했기에 All at once로 활용했지만, 이 방식은 인스턴스가 배포되는 과정에서는 인스턴스에 접근할 수 없다는 문제점이 있습니다. 만약 사용자가 많아진다면 어떤 배포 방식을 활용해야 했을까요? 이 기회에 배포 방식에 대해 자세히 알아보려 합니다. 해당 내용은 AWS Elastic Beanstalk 활용하여 수 분만에 코드 배포하기 - 최원근 솔루션즈 아키텍트(AWS) 영상에서 참고했습니다. 

 

 

 

 

 

 

 

 

 

All at once

All at once 배포 방식은 말 그대로 한 번에 모든 인스턴스를 배포하는, 가장 빠른 배포 방식입니다. 배포가 진행되는 동안 잠시 인스턴스에 접근할 수 없는 문제가 있지만, 빠르게 배포해야 하는 경우 이 배포 방식을 활용하면 적합합니다. 

 

 

 

 

 

 

 

Rolling

Rolling 배포 방식은 운용하고 있는 인스턴스 중, 사용자가 지정한 설정만큼 먼저 배포를 진행하는 방식입니다. 운용하는 인스턴스 중 일부만을 먼저 업데이트하기 때문에, All at once 방식의 인스턴스의 가동 중지 문제를 방지할 수 있습니다.  

 

 

 

 

 

 

 

Rolling with additional batch

말 그대로 추가 배치를 통해 롤링 업데이트를 하는 방식입니다. 위의 Rolling 업데이트는 4개의 인스턴스 중, 운용하고 있는 일부 인스턴스를 업데이트했습니다. 하지만 추가 배치를 통한 롤링 업데이트 방식은 처음 인스턴스를 업데이트하려고 하면, 인스턴스를 추가로 먼저 생성합니다. 그 후 생성한 인스턴스가 제대로 업데이트된 후 로드밸런서에 붙입니다. 그 후 나머지 운용하고 있는 인스턴스를 롤링 업데이트 방식으로 업데이트합니다.

 

 

 

 

 

 

 

Immutable

Immutable은 변경 불가능이라는 뜻을 담고 있습니다. 이 업데이트 방식은 기존 인스턴스를 업데이트하는 것이 아닌, 새로운 오토 스케일링 그룹을 만들어서, 그 안에서 인스턴스를 생성하고 업데이트합니다. 이때 기존에 운용하고 있는 인스턴스에는 변경이 이루어지지 않으므로 변경 불가능이라는 뜻을 담고 있습니다. 새로운 오토 스케일링 그룹에서 생성한 인스턴스가 성공적으로 업데이트되면 변경 이전에 운용하고 있던 인스턴스를 내보내는 방식으로 동작합니다. 이 배포 방식은 만약 배포가 실패할 경우 빠르게 롤백할 수 있다는 이점이 있습니다. 

 

 

 

 

 

 

 

Blue/Green

블루 그린 방식을 활용하기 위해서는 먼저 Clone Environment라는 메뉴를 클릭해야 합니다.

 

 

 

 

즉 기존 운영하고 있는 AWS EB 환경을 복제합니다. 그 과정에서 시간이 걸립니다. 

 

 

 

 

 

그럼 환경이 복제됩니다. 그 후 해야 할 것은 새로운 환경의 이름만 주면 됩니다. 기존 환경은 그대로 놔두고, 새로 만든 환경만 업데이트를 수행합니다.

 

 

 

 

그럼 새로운 환경에 배포 환경을 만들었기에, 기존 배포 환경에는 영향을 주지 않습니다. 그렇기에 All at once로 업데이트할 수 있습니다. 그 후 잘 동작하는지 내부적으로 확인하고 제대로 동작한다면 다음 과정을 수행합니다.

 

 

 

 

 

만약 잘 동작하면 원래 있었던 배포 환경의 DNS와 새로 생성한 배포 환경의 DNS를 바꿔야 합니다. 메뉴를 눌러서 Swap Environment URLs를 클릭합니다. 

 

 

 

 

 

 

그 후 URLs를 변경하면 

 

 

 

 

URL이 서로 변경됩니다.

 

 

 

 

서로의 URL이 변경되면 최근 접속한 클라이언트는 새로운 환경으로 접속됩니다.

 

 

 

 

 

이렇게 블루 그린 배포 방식을 활용하면 장단점이 명확합니다. 장점은 롤백을 엄청나게 빠르게 할 수 있다는 점입니다. 또한 다운타임이 존재하지 않습니다. 그리고 기존 환경을 건들지 않았기에 기존 인스턴스에는 영향이 전혀 없습니다. 대신 단점이 있다면 새로운 환경을 복제하는 데 시간이 오래 걸립니다.

 

 

 

 

 

 

 


 

 

 

 

 

 

 

마치며

앞으로도 팀의 발전을 돕는 개발자가 되기 위해 노력하려 합니다. 팀에 필요한 부분이 무엇일지 고민하면서, 팀에 도움이 된다면, 열심히 공부해서 실무에 적용할 수 있는 개발자가 되기 위해 노력하고 싶습니다. 팀의 성장에 기여할 수 있는 개발자가 되겠습니다. 

 

 

 

 

 


 

 

 

 

 

 

참고 및 출처

 

[AWS] Elastic Beanstalk

AWS Elastic Beanstalk란? AWS(Amazon Web Services)는 100개 이상의 서비스로 구성되어 있으며 각 서비스는 기능 영역을 나타냅니다. 다양한 서비스는 AWS 인프라 관리 방법의 유연성을 제공하는 반면 어떤 서

earth-95.tistory.com

 

[AWS, Github Action] Elastic Beanstalk에 SpringBoot 이미지 Docker로 배포하기(4) - Github Action과 Dockerfile을 작성

들어가기 전에 이번 포스팅은 ECR, Elastic Beanstalk 세팅이 완료되어 있다는 가정하에 진행합니다. 따라서, 해당 부분이 아직 완성되지 않았다면 하기 포스팅들을 먼저 보신 후 이번 포스팅을 읽어

earth-95.tistory.com

 

9분 59초 만에 Github Action + AWS Elastic Beanstalk로 TS 프로젝트 CI/CD 파이프라인 구축하기

서론 AWS는 가끔 버전에 따른 이슈가 발생하기 때문에 참고만 해주세요! 필자는 대부분의 프로젝트에서 Github Action을 CI/CD 툴로 이용하고 있다. 그 이유는 "매우 간편"하게 사용할 수 있기 때문이

bluayer.com

 

Elastic Beanstalk 환경에 애플리케이션 배포 - AWS Elastic Beanstalk

이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.

docs.aws.amazon.com

 

GitHub Actions + Docker + AWS ECR + AWS EB를 활용한 무중단 배포

무중단 배포 구축해보기

velog.io