젠킨스로 CI/CD 구현하기

심야·2023년 8월 20일
0

데브옵스

목록 보기
12/13
post-thumbnail

이전에 젠킨스를 활용해 CI/CD를 구현했다.

구현한지 너무 오래되서 자세하게 기억은 안나지만.. 나중에 다시 구현할 경우를 위해 어떻게 구현했었는지 간단하게나마 작성한다 😂


Credentials

크리덴셜을 미리 등록해놔야 CI/CD를 구현할 수 있다.
크리덴셜은 Dashboard => Jenkins 관리 => Manage Credentials => System => Global credentials 경로에서 등록할 수 있다. Manage Credentials에 접속하면 아래처럼 System 버튼이 보인다. 해당 버튼을 클릭하자.

시스템에 접근하면 글로벌 크리덴셜이 있다. 글로벌 크리덴셜에 접속하자.

Add Credentials

Add Credentials 버튼을 클릭하면 크리덴셜을 생성할 수 있다.
각자 환경에 맞는 크리덴셜을 생성하자.

나같은 경우, 깃허브 크리덴셜은 Username with password, 배포 서버는 SSH Username with private key, Jenkins CI/CD는 Username with password, 슬랙 알림은 Secret text을 이용해 생성했다.

Publish over SSH Plugin

SSH 연결 서버를 등록해야 한다. 본 글에서는 배포 서버인 웹 서버와 SSH 연결을 진행한다.

ssh 포트와 연결에 필요한 키를 등록한다.

Slack Plugin

알림이 울리는 슬랙 채널을 등록한다.
빌드, 배포 시 젠킨스에 접속하지 않아도 성공/실패 등의 알림을 받으려면 슬랙이 필요하다.

GitHub Pull Request Builder

Pull Request Builder 설정을 해야한다. 크리덴셜에는 깃허브의 Personal access tokens을 등록하고 Admin list는 깃허브 계정을 등록해야 한다.

CI

General

프로젝트 대상 URL을 등록한다.

소스 코드 관리

Git

레포지토리 URL을 등록한다.

Branches to build

빌드할 브랜치를 선택한다.

Additional Behaviours

Update tracking submodules to tip of branch 를 선택한다.

빌드 유발

Pull Request 발생 시 빌드가 돌아갈 수 있도록 GitHub Pull Request BuilderUse github hooks for build triggering을 체크한다.

Build Steps

gradle을 사용하기 때문에 gradlew 실행 권한을 부여하고 기존 빌드를 제거하는 명령어를 작성한다.

빌드 후 조치

빌드 후 슬랙에서 알림이 발생할 수 있도록 설정한다.

CD

소스 코드 관리

레포지토리를 설정하고 Branches to build 에서 빌드에 사용할 브랜치를 설정한다. 해당 레포지토리에서는 개발 브랜치와 메인 브랜치를 분리하였다.

Additional Behaviours

Update tracking submodules to tip of branch 를 체크한다.

빌드 유발

  • Token

  • Allow several triggers per build

  • Optional filter

Build Steps

빌드 시 실행할 명령어를 입력한다.

빌드 후 조치

SSH를 이용해 배포 대상 서버에 연결한다. 연결 후, jar 파일을 배포 서버에 업로드 후 run.sh 쉘 스크립트 파일을 실행한다.

빌드 후 발생하는 슬랙 알림을 설정한다.

배포 서버

Build Triggers

Pipeline

Pipeline script

pipeline {
  agent any
    stages {
            stage('Git Progress') {
                 steps {
                        git branch: 'develop',
                            url: 'https://github.com/f-lab-edu/half-time.git'
                        }

                 post {
                        success {
                                    sh 'echo "Successfully Cloned Repository"'
                                 }
                        failure {
                                    sh 'echo "Fail Cloned Repository"'
                                 }
                      }
            }

            stage('Build'){
                steps {
                // gradlew 있어야 함. git clone해서 프로젝트 가져옴
                sh 'chmod +x gradlew'
                sh './gradlew clean build'

                sh 'ls -al ./build/libs/*SNAPSHOT.jar'
                }

                post {
                    success {
                        echo 'gradle build success'
                    }

                    failure {
                        echo 'gradle build failed'
                    }
                }
            }

            stage('Test') {
                steps {
                    echo '테스트 관련된 몇 가지 단계를 수행한다.'
                }
            }

            stage('jar file to server'){
                steps{
                    sshagent(credentials:['Dev_server']){
                    sh 'id && ls -al ./build/libs/*SNAPSHOT.jar'
                    sh 'scp -P 2222 -i /var/lib/jenkins/.ssh/id_rsa ./build/libs/half-time-0.0.1-SNAPSHOT.jar ${MAIN_SERVER}:/home/web-app/half-time-0.0.1-SNAPSHOT.jar'
                    }
                }
            }


            stage('run server'){
                steps{
                    sshagent(credentials:['Dev_server']){
                        sh """
                        ssh -p 2222 -o StrictHostKeyChecking=no ${MAIN_SERVER} 'uname -a && cd /home/web-app/ && ls -al && /bin/bash nohup ./run.sh &'
                        """
                    }
                }
            }
    }
    environment {
                    MAIN_SERVER = "root@106.10.38.91"
            }
  }

run.sh

배포 서버에서 jar 파일을 실행할 수 있도록 쉘 스크립트를 작성하였다.
해당 스크립트는 CD에서 빌드 후 실행한다.

#!/bin/bash
echo "spring boot pid check"
CURRENT_PID=`ps -ef | grep -v "grep" | grep "jar" | awk '{print $2}'`
if [ "$CURRENT_PID" != "" ]
then
        echo "프로세스 PID : $CURRENT_PID"
        echo "sudo kill -15 $CURRENT_PID"
        kill -15 $CURRENT_PID

        sleep 5 
        echo "half-time app deploy"
        chmod 777 /home/web-app/half-time-0.0.1-SNAPSHOT.jar
        nohup java -jar /home/web-app/half-time-0.0.1-SNAPSHOT.jar &
else
        sleep 5
        echo "half-time app deploy"
        chmod 777 /home/web-app/half-time-0.0.1-SNAPSHOT.jar
        nohup java -jar /home/web-app/half-time-0.0.1-SNAPSHOT.jar &
fi

Jenkins 비밀번호 잊어버린 경우

비밀번호를 잊어버렸다면, /var/lib/jenkins/ 경로의 config.xml 파일에서 useSecurity의 true 값을 false로 수정 후 젠킨스를 다시 시작한다.

참고

본 글에서 참고한 자료는 아래와 같다.
webhook처럼 이 글에서 다루지 않는 내용은 아래 글들을 참고하면 된다.

https://www.redhat.com/ko/topics/devops/what-cicd-pipeline
https://jud00.tistory.com/entry/CICD%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C
https://inpa.tistory.com/entry/%F0%9F%91%A9%E2%80%8D%F0%9F%92%BB-CI-CD-%ED%8C%8C%EC%9D%B4%ED%94%84-%EB%9D%BC%EC%9D%B8-%EC%9D%B4%EB%9E%80
https://tecoble.techcourse.co.kr/post/2021-10-10-jenkins/
https://tecoble.techcourse.co.kr/post/2021-08-14-ci-cd/
https://www.redhat.com/ko/topics/devops/what-is-ci-cd
https://velog.io/@jellyb3ar/CICD-Jenkins-%EC%A0%95%EB%A6%AC
https://krksap.tistory.com/1377
https://crispyblog.kr/development/common/10
https://itholic.github.io/qa/
https://www.youtube.com/watch?v=0Emq5FypiMM&list=WL&index=8
https://a1010100z.tistory.com/172
https://freedeveloper.tistory.com/464
https://yuddomack.tistory.com/entry/%EB%B0%B0%ED%8F%AC-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EA%B5%AC%EC%84%B1%ED%95%98%EA%B8%B04-slack%EC%97%90%EC%84%9C-github-jenkins-%EC%95%8C%EB%A6%BC%EB%B0%9B%EA%B8%B0
https://forl.tistory.com/139
https://taetaetae.github.io/2020/09/07/github-pullrequest-build/
https://stackoverflow.com/questions/64050510/trigger-jenkins-build-when-pull-request-is-merged-in-github
https://ocblog.tistory.com/77
https://osg.kr/archives/429
https://ict-nroo.tistory.com/35

profile
하루하루 성실하게, 인생 전체는 되는대로.

0개의 댓글