인생을 코딩하다.

[Infra] 젠킨스란? 젠킨스를 이용해 CI 자동화하기 본문

Infra

[Infra] 젠킨스란? 젠킨스를 이용해 CI 자동화하기

Hyung1 2021. 7. 11. 23:12
728x90
반응형

https://junghyungil.tistory.com/167

 

[Infra] CI란?, 어떤 CI 도구를 사용할까?

CI는 왜 발생했을까요? CI는 애자일 프로젝트를 수행하는 데 많은 도움이 됩니다. 애자일 프로젝트에 관해 이야기하기에는 이 글이 너무 길어지기 때문에 여기를 보고 오시면 좋을 것 같습니다.

junghyungil.tistory.com

젠킨스에 관해 알아보기전, CI에 관해서 알아야하고, 많은 CI 도구중 젠킨스를 고른 이유에 관해 아셔야하기 때문에

위 글을 먼저 읽어보고 오시면 좋을 것 같습니다.

젠킨스란?

CI 도구중 하나입니다. 소프트웨어 개발 시 지속적으로 통합 서비스를 제공하는 툴이고 주로 빌드 - 테스트를 자동화하기 위해 사용합니다.  

 

젠킨스의 장점

 

  • 무료입니다.
  • 많은 플러그인을 지원하며, 커스터마이징이 다양합니다.
  • 많은 사용자들을 보유하고 있고, 관련 문서가 많습니다.
  • 호스팅을 직접해야하기 때문에 관련된 모든 부분을 관리할 수 있습니다.

젠킨스의 단점

  • 규모가 작은 프로젝트의 경우, 설정하는데 리소스 낭비가 발생할 수 있습니다.
  • 호스팅을 직접해야하기 때문에 서버 운영 및 관리 비용이 발생합니다.

정도의 장단점이 있습니다.

 

젠킨스 서버를 띄우기 위해 네이버 클라우드 플랫폼 선택

NCP를 선택한 가장 큰 이유는 회원가입 후 결제수단 등록시 무료로 제공하는 10만 크레딧 때문입니다. 또한 사용데 있어  이해하기 쉽게 문서화가 잘 되어 있기 때문에 처음 서버를 구축하는 경우 메뉴얼만 잘 따라하면 큰 문제없이 서버를 구축할 수 있습니다. AWS에 비해 저렴하기 때문에 학생, 취준생 분들에게 적합하다고 생각합니다.

 

네이버 클라우드 플랫폼에서 회원가입 후 무료로 10만 크레딧을 받아줍니다.

크레딧을 받으셨으면

 

젠킨스 사용 가이드를 따라하시면 젠킨스 서버를 생성하기까지 별 어려움없이 따라오실 수 있습니다.

 

전 월34,000원의 [Compact] 1vCPU, 2GB Mem, 50GB Disk [g1]로 설정하였습니다. 월 8만원 이상의 statndard급 서버보다는 느리지만, 큰 규모의 프로젝트가 아닌 이상 충분하다고 생각하여 더욱 저렴한걸로 오래 이용해보기 위함입니다.

 

서버를 생성하셨으면 다음 절차를 참고해주시면 됩니다.

1. 젠킨스 초기 설정시 젠킨스 버전을 업데이트 해주어야 합니다.

주의! 아래와 같은 화면이 나올시 바로 install을 바로 누르시지 마시길 바랍니다!! 

전 바로 install을 해버려서 삽질을 좀 했네요. install을 바로 눌러버렸기 때문에 아래 설치 화면 전의 단계를 캡처해두지 못했는데 이 부분 참고하시길 바라겠습니다. 그럼 제가 왜 바로 install을 누르지 말라고 강조하는 걸까요?

 

 

NCP 이미지를 통해 Jenkins서버를 구축했을때 단점이 최신 버전의 젠킨스가 아닌 구 버전의 젠킨스가 설치되어 버립니다. 따라서 아래와 같이 일부 플러그인이 정상적으로 설치되지 않습니다.

 

젠킨스 버전을 업데이트하지 않고 제 경우와 같이 위의 사진처럼 설치해버리면 일부 플러그인이 설치되지 않기 때문에 추 후 일일이 플러그인을 하나하나 다 설치해야하는 비용이 발생합니다. 

 

따라서 젠킨스의 신 버전을 설치해주어야 하는데요,

 

putty로 접속한 터미널로 가서 Jenkins의 버전을 직접 업데이트를 해줍니다.

ps -ef | grep jenkins

커맨드를 입력해서  Jenkins.war의 위치 파악 후

service jenkins stop

커맨드를 입력해서 젠킨스 서버를 중지시킵니다.

 

다음으로 Jenkins.war가 저장된 위치인 /usr/lib/jenkins/jenkins.war 로 이동후 아래 커맨드를 입력해 jenkins.war 파일을 삭제합니다.

rm -f jenkins.war

삭제가 완료되었으면 /usr/lib/jenkins 디렉토리에서 아래 커맨드를 입력해 최신 버전 Jenkins를 설치합니다.

wget http://mirrors.jenkins-ci.org/war/latest/jenkins.war

설치가 완료되면 service jenkins start 커맨드 입력 후 접속하면 업데이트가 완료됩니다.

 

2. 젠킨스 초기 설정시 JDK 버전을 업데이트 해주어야 합니다.

NCP를 통해 Jenkins를 구축하면 기본적으로 JDK 1.8이 설치됩니다. 본인 프로젝트가 JDK 1.8을 사용하고 계시다면 이 단계는 굳이 참고하실 필요 없습니다. 전 JDK 11을 사용하고 있기 때문에 업데이트를 해주었습니다.

 

rpm -qa | grep java

커맨드를 입력하여 현재 버전 목록을 확인해봅니다.

yum remove java-1.8.0-openjdk-headless-1.8.0.262.b10-0.el7_8.x86_64

을 입력하여 1.8버전을 삭재해줍니다.

 

삭제가 완료되었으면,

yum install java-11-openjdk-devel.x86_64

를 입력 후 java 11 버전으로 설치해줍니다.

 

설치가 완료되었다면,

java -version

을 입력하여 정상적으로 설치가 되었는지 확인해봅니다.

jdk11버전 설치가 완료되었다면, 이어서 환경변수를 설정해주어야 합니다.

readlink -f /usr/bin/javac

커맨드를 입력하여 javac의 위치를 파악해줍니다. 

vi /etc/profile

커맨드를 입력 후, 맨 아래로 내리면 기존 JDK1.8로 설정되어있는 환경변수가 있을 것 입니다. 

전 이미 바꿔서 위처럼 되어있지만, 아마 바꾸지 않으셨다면

export JAVA_HOME ~~ 1.8

 로 되어있으실 겁니다

 

커서를 해당하는 칸에 옮긴후 `a`를 누르면 수정하실 수 있습니다.

export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-11.0.11.0.9-1.el7_9.x86_64

를 입력하여 환경변수를 수정해줍니다.

 

재접속 후 echo $JAVA_HOME를 입력하면 위와 같이 환경변수가 정상적으로 변경된 것을 볼 수 있을 것 입니다.

 

3. 젠킨스 초기 설정시 gradle 버전을 설정 해주어야 합니다.

CentosOS에 본인이 사용하고있는 gradle과 동일한 버전을 설치해줘야 합니다. 아래 커맨드를 입력해 gradle을 설치한다.

 

본인의 프로젝트의 아래의 디렉토리에 들어간 후, 아래 사진과 같이 gradle 버전을 복사해줍니다.

 

wget https://services.gradle.org/distributions/gradle-6.8-bin.zip -P /tmp

명령어를 이용해 gradle을 설치해줍니다. 

 

다운로드가 완료되면

cd /opt/gradle

커맨드를 입력해 /opt/gradle 디렉토리로 이동 후

sudo unzip -d /opt/gradle /tmp/gradle-*.zip

커맨드를 입력하여 방금 다운로드한 zip파일의 압축을 풀어줍니다.

 

압축을 푼 후 ls /opt/gradle/gradle-6.3 커맨드를 입력해 정상적으로 설치되었는지 확인해봅니다.

 

bin init.d lib LICENSE NOTICE README가 출려된다면 정상적으로 설치된 것 입니다.

 

마지막으로

export PATH=$PATH:/opt/gradle/gradle-6.3/bin

를 입력하여 gradle 환경변수를 설정하여 주시면 됩니다.

 

이제 깃허브에 접속해서  Access token을 생성해야 합니다.

Credentials 설정을 위해 자신의 깃허브에 접속해 Github > Settings > Developer settings > Personal access tokens에서 아래와 같이 체크한 후 토큰을 생성합니다.

 

주의! 한 번 발급받은 토큰은 다시 확인할 수 없으니 꼭 안전한 폴더에 복사해서 보관해두셔야합니다!

 

토큰 생성을 끝냈으면 Jenkins 관리 -> 시스템 설정에서 GitHub 탭으로 이동한 후 Credentials을 생성해줍니다.

 

Secret text 선택 후 Secret에 좀 전에 발급받은 GitHub Access token을 입력한다. ID와 Description은 해당 프로젝트와 관련해 적절하게 지어줍니다.

 webhook 생성

gitflow 브랜치 관리 전략을 사용하고 있기 때문에 모든 브랜치에 대해서 push와 PR이 일어날 때 마다 test와 build를 적용했습니다. 이를 위해 먼저 github webhook을 생성해야합니다.

 

 

빨간색으로 밑줄 친 부분에는 자신의 Jenkins 주소를 입력하고, 나머지는 기본 디폴트 값으로 설정 되어있는 것을 유지한채 webhook를 생성해줍니다.

 

Multibranch Pipeline Item 생성

모든 브랜치에 대해서 push와 PR이 일어날 때 마다 test와 build를 적용하기로 했으니 멀티브랜치 파이프라인으로 Item을 생성해줍니다.

 

젠킨스 서버에 접속해, 

멀티브랜치 파이프라인을 생성해줍니다.

 

생성하면 아래와 같은 화면이 나옵니다.

add source에서 gitHub를 선택해준 후, 다음 화면에서 add 박스를 금방 만든 멀티브렌치 파이프라인 이름을 선택해줍니다.

 

Multibranch Pipeline는 Secret text로 Credentials 생성이 불가능하기 때문에 아래와 같이 Kind를 Username with password를 선택한 후 , Username에는 본인의 github 닉네임을 입력하고 Password에는 위에서 발급한 Access token으로 새로운 Credentials를 생성해줍니다.

 

Repository HTTPS URL은 자신의 프로젝트 주소를 넣어준 후 아래 Validate버튼을 눌러 정상적으로 연결이 되는지 확인해봅니다. 정상적으로 연결되었다면 하단에 성공했다는 메시지가 출력될 것입니다.

 

마지막으로

리포지토리 자동 스캔 구간을 설정해줍니다.

인텔리제이와 연동

GitHub를 통해 Push 또는 PR 이벤트가 발생하면 Jenkinsfile에 작성된 Shell script를 기준으로 Jenkins에서 다음 이벤트가 실행됩니다. Jenkinsfile은 프로젝트의 root 디렉토리 아래 추가해야 합니다.

아래는 제가 작성한 Jenkinsfile의 Shell script 문법 입니다.

pipeline {
    agent any

    environment {
        PATH = "/opt/gradle/gradle-6.8/bin:$PATH"
        SLACK_CHANNEL = '#jenkins'
        TEAM_DOMAIN = 'black-postoffice'
        TOKEN_CREDENTIAL_ID = 'junghyungil-Slack'

    }

    stages {

        stage('Start') {
            steps {
                slackSend (channel: SLACK_CHANNEL, color: '#FFFF00', message: "STARTED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})", teamDomain: TEAM_DOMAIN, tokenCredentialId: TOKEN_CREDENTIAL_ID )
            }
        }

        stage('Git Checkout') {
            steps {
                checkout scm
                echo 'Git Checkout Success!'
            }
        }
		
        // Build라는 이름의 스테이지 블록 생성 후 
        stage('Build') {
            steps {
                // 빌드된 파일 지웠다가 다시 새로 빌드 실행
                // 자신이 작성한 테스트 외에 작성하지 않은 테스트에 관해 빌드할 때 테스트를 스킵 
                sh 'gradle clean build --exclude-task test'
                echo 'Build Success!'
            }
        }

        stage('Test') {
            steps {
                sh 'gradle test'
                echo 'Test Success!'
            }
        }

    }

  post {
    success {
         slackSend (channel: SLACK_CHANNEL, color: '#00FF00', message: "SUCCESSFUL: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})", teamDomain: TEAM_DOMAIN, tokenCredentialId: TOKEN_CREDENTIAL_ID )
         }

    failure {
         slackSend (channel: SLACK_CHANNEL, color: '#F01717', message: "FAILURE: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})", teamDomain: TEAM_DOMAIN, tokenCredentialId: TOKEN_CREDENTIAL_ID )
         }
    }

}

위는 가벼운 쉘 스크립트 문법이라 보면 이해하실 수 있으실 겁니다. 혹시나 이해가 안 가신다면 Shell script 문법에 알아보시길 권장드립니다. 

 

위에서 작성한걸 보시면 슬랙과 연동한 것을 보실 수 있습니다. 저는 슬랙과 연동하여 깃허브 webhook 이외에도 알람을 받을 수 있도록 설정해놨습니다. 24시간 깃허브에서만 확인할 수는 없습니다. 이를 대바하여 slack과 연동 후 시간, 장소 상관없이 모바일에서 Slack을 통해서도 알람을 확인할 수 있도록 연동해놓았습니다.

 

젠킨스와 slack을 연동하는 것에 관한 글은 이 곳에 작성해두었습니다.

 

이제 깃허브에 PUSH하여 봅니다.

빌드와 테스트가 실패하면 X, 성공하면 체크표시가 된 것을 확인할 수 있습니다.

 

젠킨스 서버에서 접속하여 Status 메뉴에 접속화여 확인해보면

 

를 확인 할 수 있습니다.

 

실패한 빨간 박스에 커서를 갖다두면 LOG를 확인 할 수 있는 버튼이 나옵니다. 버튼을 클릭하면

실패한 이유에 관한 원인도 분석할 수 있습니다.

 

지금까지의 과정이 모두 완료됬다면, 젠킨스 서버에서 여러 메뉴들을 눌러보며 이것저것 직접 눈으로 확인해보시면 좋을 것 같습니다. 

 

전체적인 프로젝트 진행 상황 및 코드는 

https://github.com/f-lab-edu/black-postoffice 

 

f-lab-edu/black-postoffice

익명으로 편하게 고민, 일상을 공유하는 소셜 네트워크 서비스입니다. Contribute to f-lab-edu/black-postoffice development by creating an account on GitHub.

github.com

에서 확인하실 수 있습니다.

 

긴 글 읽어주셔서 감사합니다.

728x90
반응형
Comments