ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [AWS] Spring Boot, Jenkins, CodeDeploy로 CI/CD 하기
    Cloud/AWS 2021. 4. 6. 10:07
    728x90
    반응형

    들어가기 전에

    이번 글에서 CI/CD를 할 때는 위의 아키텍쳐로 진행하려고 합니다. (다만, Auto Scaling은 사용하지 않고 운영용 EC2 1대, Jenkins 빌드용 EC2 1대를 사용할 예정입니다.)


    그래서 사용한 도구에 대해서 정리하면 아래와 같습니다.

    • Spring Boot(gradle)
    • EC2 Linux2 2대(운영용 프리티어 1대, 젠킨스 빌드용 RAM 16G 1대)
    • Jenkins(CI)
    • CodeDeploy(CD)
    • S3 Bucket
    • Docker
    • Github Hook

     

    이러한 기술들을 사용해서 CI/CD를 진행하는 글을 이어나가겠습니다. 추가로 이번 글에서 EC2 생성, S3 버켓 생성, CodeDeploy 생성, IAM 사용자 권한 부여 등등 같은 것들에 대해서는 다루지 않겠습니다.

     

     

     

    EC2 인스턴스 생성하기

    jenkins를 사용할 때 EC2 프리티어로 사용하니까 빌드를 할 때마다 EC2가 맛이가는 문제가 발생했습니다. 그래서 여기 에서 저와 비슷한 상황의 분을 찾았는데 역시.. EC2 프리티어로는 버티기가 힘들었던 거 같습니다. 그래서 젠킨스 빌드용 EC2는 성능 좋은 것으로 생성해보겠습니다. (운영용 EC2는 프리티어 Linux2로 이미 만들어놓았습니다.)

     

    123

     

    위와 같이 RAM 16G로 하나 생성하겠습니다.

     

     

     

    EC2 Linux2에 Docker 설치하기

    sudo yum update -y
    sudo amazon-linux-extras install -y docker
    sudo service docker start

    그리고 EC2에 접속한 후에 위의 명령어로 EC2에 Docker를 설치하겠습니다.

     

     

     

    docker로 jenkins 설치하기

    sudo docker run -d --name jenkins -p 32789:8080 jenkins/jenkins:jdk11

    스크린샷 2021-04-05 오전 12 09 37

    위와 같이 컨테이너가 잘 실행되고 있다면 http://EC2-IP:32789로 접속하겠습니다.

     

     

    스크린샷 2021-04-05 오전 12 08 58스크린샷 2021-04-05 오전 12 13 44

    sudo docker exec -it jenkins bash  // jenkins bash 쉘 접속
    cat /var/jenkins_home/secrets/initialAdminpassword

    위와 같이 jenkins bash에 접속해서 비밀번호를 알아낸 후 접속하겠습니다.

     

     

     

    스크린샷 2021-04-05 오전 12 16 43스크린샷 2021-04-05 오전 12 20 15

     

    그리고 원하는 계정으로 가입을 하겠습니다.

     

     

    스크린샷 2021-04-05 오전 12 21 26스크린샷 2021-04-05 오전 12 21 32

     

     

    스크린샷 2021-04-05 오전 12 24 55

     

    그리고 현재 Jenkins로 CI(빌드 및 테스트)를 하고 이 결과를 S3에 저장합니다. 그리고 저장된 빌드 파일을 AWS CodeDeploy가 EC2에 CD(자동 배포)를 해주는 것이기 때문에 Jenkins에 CodeDeploy 플러그인을 설치하겠습니다.

     

     

     

    스크린샷 2021-04-05 오전 12 30 05스크린샷 2021-04-05 오전 12 31 03

     

    그리고 위와 같이 프로젝트를 하나 생성하겠습니다.

     

     

     

    스크린샷 2021-04-05 오전 12 32 48스크린샷 2021-04-05 오후 5 35 27

     

    Github에 push가 되었을 때 Github이 Jenkins에 Hook을 날려 자동 빌드할 수 있도록 Github hook Trigger를 선택하겠습니다.(아래에서 Github Hook 설정을 하게 됩니다.)

     

    ./gradlew clean build

    그리고 Build 부분을 보면 위와 같이 적었습니다. Spring Boot gradle은 위의 명령어를 통해서 jar 파일을 만들기 때문입니다.

     

     

    스크린샷 2021-04-05 오전 12 41 36

     

    또한 이번에는 빌드 후 조치로 Jenkins 빌드가 끝난 이후에 CodeDeploy가 배포하는 단계의 설정입니다.

     

     

    스크린샷 2021-04-05 오후 5 33 38스크린샷 2021-04-05 오전 12 48 20

    • AWS S3 Bucket, CodeDeploy 애플리케이션, 배포 그룹을 만들었을텐데 그것의 이름을 위에 맞게 적으면 됩니다.
    • Include Files를 보면 CodeDeploy가 EC2로 옮길 파일들을 적는 것입니다.(**/*.jar, **/appspec.yml, **/scripts/* 라고 적었습니다. Dockerfile은 이 글에서 다루지 않기 때문에 적지 않아도 괜찮습니다.)
    • 마지막으로 IAM 사용자에게 발급받은 액세스 키, 비밀 엑세스 키가 있을 것입니다. 그것을 입력하겠습니다.

     

    그러면 이제 Jenkins에 대한 기본적인 설정은 끝났습니다.

     

     

     

    Github WebHook 추가

    Github에 push가 되었을 때 Jenkins로 Hook을 날려 빌드가 실행되도록 하는 역할을 합니다.

     

    스크린샷 2021-04-05 오전 12 50 38스크린샷 2021-04-05 오전 12 51 02

    • PayLoad URL에 http://{EC2 IP}:32789/github-webhook/을 입력하겠습니다.(마지막에 / 안쓰면 302에러 뜨니 꼭 써야 합니다!)
    • application/json 선택

     

     

    스크린샷 2021-04-05 오전 12 53 12

    그리고 위와 같이 초록색 체크 버튼이 떠야 제대로 등록이 된 것입니다.

     

     

     

    EC2 Linux2 CodeAgent 설치하기

    CodeDeploy가 EC2에 배포를 하기 위해서는 CodeAgent 설치가 필요합니다. 그래서 아래의 명령어를 통해서 설치를 하겠습니다.

    sudo yum install -y aws-cli
    cd /home/ec2-user/ 
    sudo aws configure 
    wget https://aws-codedeploy-ap-northeast-2.s3.amazonaws.com/latest/install
    chmod +x ./install
    sudo ./install auto (/usr/bin/env: ruby: No such file or directory 이런 에러 난다면 아래 설치)
    sudo yum install ruby
    sudo service codedeploy-agent status

    test

    여기서도 Jenkins에서 입력했던 것과 마찬가지로 IAM 사용자의 액세스 키, 비밀 엑세스 키를 입력해주면 됩니다.

     

     

     

    스크립트 파일과 yml 파일 작성하기

    CodeDeploy가 배포를 어디에 어떤 과정으로 할 지를 담은 파일은 appspec.yml이고, deploy.sh는 EC2 내부에서 동작하도록 만든 스크립트 파일입니다.

    스크린샷 2021-04-06 오전 9 47 37

     

    파일의 구조는 위와 같습니다. 하나씩 작성을 해보겠습니다.

     

     

     

    appspec.yml

    version: 0.0
    os: linux
    files:
      - source:  /
        destination: /home/ec2-user/jenkins  # EC2 내부 배포 할 위치
        overwrite: yes
    
    permissions:
      - object: /
        pattern: "**"
        owner: ec2-user
        group: ec2-user
    
    hooks:
      ApplicationStart:
        - location: scripts/deploy.sh    # ApplicationStart 단계에서 해당 파일을 실행해라
          timeout: 60
          runas: ec2-user

     

     

    deploy.sh

    #!/bin/bash
    BUILD_JAR=$(ls /home/ec2-user/jenkins/build/libs/*.jar)     # jar가 위치하는 곳
    JAR_NAME=$(basename $BUILD_JAR)
    echo "> build 파일명: $JAR_NAME" >> /home/ec2-user/deploy.log
    
    echo "> build 파일 복사" >> /home/ec2-user/deploy.log
    DEPLOY_PATH=/home/ec2-user/
    cp $BUILD_JAR $DEPLOY_PATH
    
    echo "> 현재 실행중인 애플리케이션 pid 확인" >> /home/ec2-user/deploy.log
    CURRENT_PID=$(pgrep -f $JAR_NAME)
    
    if [ -z $CURRENT_PID ]
    then
      echo "> 현재 구동중인 애플리케이션이 없으므로 종료하지 않습니다." >> /home/ec2-user/deploy.log
    else
      echo "> kill -15 $CURRENT_PID"
      kill -15 $CURRENT_PID
      sleep 5
    fi
    
    DEPLOY_JAR=$DEPLOY_PATH$JAR_NAME
    echo "> DEPLOY_JAR 배포"    >> /home/ec2-user/deploy.log
    nohup java -jar $DEPLOY_JAR >> /home/ec2-user/deploy.log 2>/home/ec2-user/deploy_err.log &

    위의 스크립트 파일을 통해서 최종 자동 배포의 과정이 일어나는 것입니다. 그리고 Github의 아래와 같이 간단한 Controller를 만든 후에 push를 해보겠습니다.

     

     

    스크린샷 2021-04-06 오전 9 56 48

     

    스크린샷 2021-04-05 오후 5 31 36

     

    그러면 위와 같이 Jenkins CI가 성공한 것도 확인할 수 있습니다. 또한 CodeDeploy도 성공 되었나 확인해보겠습니다.

     

     

    스크린샷 2021-04-06 오전 9 58 33

    그리고 CodeDeploy도 보면 성공한 것을 볼 수 있습니다. 성공했다면 EC2에도 파일들이 잘 배포가 되었을 것입니다.

     

     

    스크린샷 2021-04-06 오전 9 54 15

    실제로 EC2 내부를 보면 위와 같이 파일들이 잘 전달된 것을 볼 수 있습니다.

     

     

    스크린샷 2021-04-06 오전 10 00 04

    그리고 보면 실제로 8080 포트의 java가 실행되고 있는 것을 볼 수 있습니다.

     

     

    스크린샷 2021-04-06 오전 10 01 08

     

    다음 포스팅에서는 배포 파일을 좀 더 깔끔하게 EC2에 올리고 Docker로 이미지를 만들어 컨테이너로 실행시키는 것에 대해서 다뤄보겠습니다. 

    반응형

    댓글

Designed by Tistory.