본문 바로가기
WEB

Jenkins를 통한 CI & CD 구축하기.

by jinukix 2021. 12. 24.

저희 프로젝트를 배포하기 위해 리눅스 서버에서 Git pull을 하여 코드를 받아온 뒤 빌드하여 jar파일을 실행시켜야 했습니다. 이는 굉장히 반복적이고 귀찮은 과정이기에 배포와 테스트 자동화의 필요성을 느끼게 되었습니다. 

먼저 CI와 CD에 대해 알아봅시다.

CI (Continous Integration)

CI는 개발자들을 위한 자동화 프로세스인 지속적인 통합을 의미합니다. 우리는 보통 원격 저장소에 공용 레포지토리를 생성하여 작업하게 됩니다. 이때 개인이 작업한 내용이 신뢰성을 가질 수 있도록 단위 테스트, 빌드 등 부가적인 작업이 이루어져야 합니다. CI를 성공적으로 구현하는 경우 애플리케이션에 대한 새로운 코드 변경 사항이 정기적으로 빌드 및 테스트되어 공유 레포지토리에 통합되게 됩니다.

CD (Continous Delivery / Deployment)

CD는 지속적인 제공 및 지속적인 배포를 의미합니다. 지속적인 제공이란 개발자들이 애플리케이션에 적용한 변경 사항이 테스트를 거쳐 레포지토리에 자동으로 업데이트되는 것을 뜻합니다. 지속적인 배포란 개발자의 변경 사항을 레포지토리에서 프로덕션 환경까지 자동으로 릴리스하는 것을 의미합니다.

정리하자면 CI를 통해 지속적으로 빌드와 테스트를 진행하고 이를 통과한 코드에 대하여 운영서버에 그 내용을 배포해 반영하는 것입니다.  저희는 Jenkins를 이용해 CI&CD를 구축하기로 했습니다. 저희는 Github에서 main 브랜치로 푸시하게 되면 자동으로 서버로 반영되는 것을 목표로 진행했습니다. 

Jenkins CI & CD 구축 - CI 

먼저 Github -> Setting -> Deveoper settings -> Personal access token -> Generate new token으로 이동해 토큰을 등록합니다. 적당한 이름을 지어주고 repo, admin:repo_hook 체크를 해줍시다.

생성된 토큰 값을 복사해 Jenkins 관리 -> Manager Credentials -> Add Credentials로 이동해 Credentials를 생성합니다. Kind는 Secret text로 Secret에는 아까 복사했던 토큰 값을 ID에는 적당한 이름을 넣어주도록 하겠습니다.

Jenkins 서버에서 시스템 설정 -> GitHub탭으로 이동합니다. 방금 전 등록한 Credentials를 이용해 GitHub Server를 추가합니다. Test Connection을 통해 정상적으로 연결이 됐는지 확인합니다.

Payload URL에 젠킨스 서버 URL + /github-webhook/ 을 입력합니다. Content type은 application/json으로 설정합니다.

다시 Jenkins 서버로 돌아오겠습니다. 저는 Jenkins 파이프라인을 사용했습니다. 파이프라인을 통해 스크립트 파일(JenkinsFile)을 작성해 CI&CD를 위한 연속적인 이벤트를 실행시킬 수 있습니다.

General 탭에서 GitHub project url을 입력합니다.

Build Triggers에는 GitHub hook trigger for GITScm polling을 체크합니다.

Pipeline에서 Definition에서 Pipeline script from SCM을 설정합니다. Repository URL도 입력해줍니다. 

Credentials에서는 kind를 Username with password으로 Github의 계정 정보를 입력합니다.

main 브랜치에 존재하는 Jenkinsfile을 실행시켜주도록 하겠습니다.

이제 JenkinsFile을 작성해보겠습니다. 다음은 제가 작성한 스크립트 파일입니다. 

pipeline {
    agent any

    stages {
        stage('Git Checkout') {
            steps {
              checkout scm
              echo 'Git Checkout Success!'
            }
        }

        stage('Test') {
            steps {
                sh './gradlew test'
                echo 'test success'
            }
        }

        stage('Build') {
            steps {
                sh './gradlew clean build'
                echo 'build success'
            }
        }
    }
}

test와 build 즉, CI 작업을 수행하는 단순한 로직입니다. 이제 JenkinsFile을 포함해서 main 브랜치로 푸시를 하겠습니다. 그러면 다음과 같이 스크립트가 자동으로 실행되는 것을 확인할 수 있습니다.

로그

Jenkins CI & CD 구축 - CD

지금까지 CI 작업을 진행했습니다. 이제 공용 레포지토리로 푸시되는 코드들의 테스트, 빌드의 자동화가 이루어졌습니다. 다음은 CD 작업입니다. 신뢰성을 가지게 된 공용 레포지토리의 코드들이 운영서버로 배포되는 것을 자동화해보겠습니다.

Jenkins의 publish over ssh 플러그인을 사용해 빌드된 jar 파일을 운영서버로 넘김과 동시에 운영서버에서 배포 스크립트를 실행시키도록 하겠습니다.

먼저 배포 서버에 .ssh/authorized_keys에 Jenkins 서버의 id_rsa.pub의 공개키를 넣어둬야 합니다. 참고로. ssh파일의 권한은 700, authorized_keys의 권한은 600이 아니라면 ssh 인증이 동작하지 않습니다. 다음으로는 Jenkins 시스템 설정 -> Publish over SSH에서 SSH Servers를 추가합니다. key에는 id_rsa 비공개키를 입력합니다.

배포 서버의 정보를 입력합니다.

성공적으로 연결됬음을 확인합니다.

이제 JenkinsFile에서 다음 코드를 추가하겠습니다.

빌드된 jar파일을 넘기고, 배포 서버에서 deploy.sh 스크립트를 실행합니다. 다음은 배포 서버로 넘어가 deploy.sh 스크립트를 작성하겠습니다.

먼저 현재 실행중인실행 중인 애플리케이션이 있는지 확인합니다. 실행 중인 애플리케이션이 존재한다면 종료합니다. 그리고 새로 받아온 애플리케이션을 nohup 명령어를 통해 백그라운드로 실행하게 됩니다.

이로써 CI & CD 를 구현하게 되었습니다. 테스트, 빌드, 배포까지 작업을 자동화하는 데 성공했습니다. 이제 우리는 코드 검증, 배포까지의 작업을 일일이 하지 않아도 됩니다. 

댓글