• Elastic Beanstalk + Jenkins + Docker 로 배포하기 :: 마이구미
    AWS 2020. 9. 3. 23:00
    반응형
    이 글은 Jenkins 를 활용한 CI/CD 구축을 다룬다.
    여기서 다루는 모든 앱은 Docker 기반으로 구성되고 실질적인 배포는 AWS 의 EB(Elastic Beanstalk) 를 사용하는 것을 가정한다.

     

    도커에 대한 지식이 필요하다.

    익숙하지 않다면, 관련 글을 추천한다.

    https://subicura.com/2017/01/19/docker-guide-for-beginners-1.html

     

    기본적으로 알아야할 도커의 용어는 다음과 같다.

     

     

    Dockerfile 파일은 빌드를 거치면, 도커 이미지를 생성할 수 있다.

    Dockerfile 과 도커 이미지는 살아움직이는 것이 아닌 단순히 파일이라고 보면 된다.

    이를 기반으로 숨을 불어넣어 서버와 같은 존재를 구축되는 것이 도커 컨테이너이다.

    도커 이미지는 ubutnu, nginx, nodejs, openjdk, jenkins 등과 같은 이름으로 만들어져 있는 모습을 볼 수 있다.

    우리는 필요한 이미지를 가져와서 환경에 구애받지 않고, 쉽게 구축할 수 있다.

     

    각 단계별 진행에 다루기에 앞서, 최종 결과물을 먼저 언급한다.

    목적 -
    서비스 또는 기능 단위로 많은 서버가 존재할 것이다.
    이 서버들은 젠킨스를 통해 각각 빌드, 테스트등과 같은 행위를 거친 후, 배포를 실행하게 된다.

     

    이 글에서의 결과물을 위해 사용하는 기술 스택은 다음과 같다.

     

    • Jenkins
    • Github
    • AWS ECR
    • AWS Elastic Beanstalk
    • Docker

     

    간단히 설명하자면,

     

    • Jenkins - CI/CD 툴
    • Github - 코드 파일 저장소
    • AWS ECR - Docker Hub 와 같은 목적으로 AWS 에서 제공하는 도커 이미지 저장소
    • AWS Elastic Beanstalk - AWS 서비스 인프라 관리
    • Docker - 응용 프로그램

     

    AWS 관련된 것들은 aws-cli 를 기반으로 처리한다.

    우선 이를 활용한 최종 결과물부터 확인해보자.

     

     

    위 그림처럼 젠킨스를 기반으로 다양한 서비스와 통신하는 모습을 볼 수 있다.

    각 화살표에서 무엇을 하는지 확인해보자.

     

     

     

    우선, 간단하게 설명하면 다음과 같다. (아래에서 다시 다룰 예정)

    기본적으로 젠킨스는 Github 에 있는 코드 파일들을 가져온다.

    Github 에 저장되어있는 코드는 기본적으로 애플리케이션 코드들이 존재할 것이다.

    그리고 배포를 위한 파일들이 존재하게 된다.

     

    • Dockerfile (필수)
    • Dockerrun.aws.json (필수)
    • ebextensions/* 
    • ...

     

    Dockerfile 은 도커 이미지를 업데이트하기 위해 사용되며, 업데이트된 이미지를 ECR 에 push 하게 된다.

     

    Dockerrun.aws.json 파일은 빈스톡으로 멀티 컨테이너 도커 환경의 애플리케이션을 배포하기 위해 사용된다.

    파일 구성에는 도커 컨테이너를 실행에 필요한 도커 이미지가 지정되어, 빈스톡은 이를 기반으로 빌드한다.

    여기서 Dockerrun.aws.json. ebextensions 과 같이 빈스톡에 필요한 파일들을 압축하여 S3 에 저장하게 된다.

     

    그리고 S3 저장된 zip 파일을 빈스톡에서 가져오는 모습이다.

    그리고 압축된 파일 중 Dockerrun.aws.json 을 통해 정의된 도커 이미지를 ECR 에서 가져온다.

    이를 순서로 표현하고자 한다면, 다음과 같다.

     

     

    하단에서 다루는 실습을 보면서도 이 흐름을 계속 보길 바란다.

    젠킨스가 실제로 파이프라인을 통해 빌드하는 과정은 다음으로 나타낼 수 있다.(달라질 수 있음)

     

     

    젠킨스에서 위 과정들이 올바른지 검증하고 실행하게 된다.

    위에서 언급한 흐름과 각 서비스에서 원하는 게 무엇인지 정확히 이해해야 실습 단계를 이해할 수 있다.

     


    실제로 구축하는 과정을 보자.

    우선 젠킨스 서버를 구축해보자.

    2개의 컨테이너로 구성된다. (도커의 이해를 더 높이기 위해 멀티 컨테이너로 구성했다)

    이 글의 예제에서의 젠킨스는 로컬 환경(Mac)에, App은 AWS EC2 에 존재한다.

     

     

    각 Ngnix 는 포트80 -> 포트8080 으로 프록시 역할을 한다고 생각하자.

     

    자세한 내용은 Github 코드로 대신할 것이고, README.md 를 참고바란다.

    Mac 환경에 대한 이슈와 여러가지 이유로 인한 삽질이 굉장히 많았다.

    혹시나 이해안가는 것이나 이슈가 생긴다면, README.md 에서 발견할 수 있다.

     

    Jenkins - https://github.com/hotehrud/jenkins_docker_example

    Application - https://github.com/hotehrud/jenkins_eb_docker_example

     

    1. 젠킨스 구축

     

    Github 코드에는 도커 위한 파일로 Dockerfile, Dockerfile.nginx, docker-compose.yml 가 존재한다.

    docker-compose.yml 는 멀티 컨테이너를 편하게 제어하기 위한 docker 에서 제공하는 기능이다.

    이를 통해 각각 docker run 을 할 필요없이, 한번에 도커 컨테이너들을 실행할 수 있다.

     

    Dockerfile.nginx 는 nginx 를 위한 이미지로 내부 설정을 커스텀하기 위해 nginx 디렉토리를 ADD 하는 모습을 볼 수 있다.

    Dockerfile 에는 npm, aws-cli 등 젠킨스에서 빌드 시 필요로 하는 것들을 셋팅한 모습을 볼 수 있다.

    docker-compose.yml 에서는 몇가지 volume 을 통해 마운트하는 모습을 볼 수 있다.

    aws-cli 를 활용하기 때문에, aws credentials 이 존재해야한다.

    *aws ecr 을 사용할 때는 임시 권한을 얻어 사용하기 때문에, role 수정이 필요할 수 있다. (README.md)

     

    Dockerfile 을 빌드한 후, 빌드된 이미지로 컨테이너를 생성한다.

     

    $ cd .docker
    $ docker build -t mygumi/jenkins .
    $ docker build -t mygumi/jenkins_nginx . -f Dockerfile.nginx
    $ docker images // 생성된 이미지 확인
    $ cd ../
    $ docker-compose up

     

     

    컨테이너가 실행되는 과정에서 로그에 초기화 비밀번호가 찍힌다.

    이는 id 가 "admin" 에 해당하는 비밀번호를 의미한다.

    그대로 모든 플러그인을 설치하는 버튼을 클릭하면 젠킨스는 구축된다.

    0.0.0.0 으로 접속하면 8080 으로 오픈되어있는 젠킨스를 볼 수 있다. (*0.0.0.0 으로 하는 이유는 README.md 를 참고하길 바란다)

     

    2. 젠킨스 배포를 위한 App 서버 구성

     

    현재 App 서버를 EB 를 통해 구축되어 있다라고 가정한다.

    그렇다면 App 환경을 AWS 관점에서 바라보면 다음과 같다

     

     

    EC2 환경에서 구성되는 각 컨테이너는 ECR 에 존재하는 이미지를 통해 생성된다.

    그리고 EB 를 통해 배포가 이루어진다.

     

    빈스톡은 EC2 가 구성하고 있는 환경이 어떤 도커 이미지를 사용하고 있는지, 이미지는 어디에 존재하는지 등을 알아야한다.

    처음에 언급했듯이, 젠킨스는 Github 에 저장되어있는 파일들을 통해 이를 실행할 수 있다.

     

    Github 에서 Application 관련 파일들은 다음과 같이 구성되어있다.

     

    ├ .docker
         ┬ 
         ├ nginx
         ├ Dockerfile
         ├ Dockerfile.nginx
         ├ generate-dockerrun.sh
         ├ generate-version.sh
     ├ Jenkinsfile    
     ├ app.js

     

    젠킨스 서버와는 달리 AWS 와의 통신을 위한 파일들이 존재하게 된다.

     

    • generate-dockerrun.sh // Dockerrun.aws.json 파일 목적
    • generate-version.sh // S3 에 올릴 zip 파일 목적
    • Jenkinsfile // 젠킨스 빌드 스크립트 파일

     

     

    Jenkinsfile 파일을 확인해보면, stages  build, upload, deploy 로 구성되어있다.

    처음에 언급한 젠킨스 빌드 과정을 단계적으로 표현한 것이다.

    쉘 스크립트 명령어로 코드를 통해 충분히 이해할 수 있기에, 간략히 설명하면 다음과 같다.

     

    stage build

    • bash - 쉘 스크립트 실행
    • zip - EB 를 위해 S3 에 올릴 zip 파일을 생성.
    • npm -  install, test, build 등 이러한 명령어를 테스트 목적.
    • aws ecr -  ECR 저장소 확인.
    • docker - build, tag, push 를 통해 도커 이미지 ECR 에 저장.

    이 단계가 버그 없이 잘 동작했다면, App 의 코드가 이상이 없고,

    EB 에 알려줄 빌드를 위한 zip 파일이 만들어진 상태이고, 

    서버 환경에 따른 이미지들이 ECR 에 잘 저장된 상태이다.

     

    aws-cli 을 통해 모든게 이루어지기 때문에, 이를 잘 이해하고 있어야한다.

     

    stage upload

    • aws s3 - 이전 단계에서 만들어진 zip 을 실제 S3 에 저장.

     

    stage deploy

    • aws elasticbeanstalk - 빈스톡을 생성하고 배포 요청.

     

    젠킨스를 빌드하면, 처음에 언급했던 흐름을 그대로 진행하면서 EB 는 재배포를 시작하게 된다.

    젠킨스 빌드가 시작되면 각 단계에서 실패 시 로그를 볼 수 있기에, 로그를 보면서 해결해나가면 된다.

    반응형

    댓글

Designed by Tistory.