카테고리 없음

Jenkins와 Docker를 활용한 CI/CD -2편

꽃달린감나무 2023. 11. 17. 17:08
728x90

이번 포스팅은 인턴 기간 동안 맡은 프로젝트의 ci/cd를 구축하고 이를 팀원들에게 공유하기 전, 지식과 기술을 다듬기 위한 포스팅입니다.
앞 포스팅에서 docker를 활용해 jenkins를 구축하는 포스팅이 있으니 관심이 있으신 분은 참고해주세요!! 😃

Jenkins와 Docker를 이용한 CI/CD - 1편
 

Jenkins와 Docker를 이용한 CI/CD - 1편

인턴 기간 중 맡은 프로젝트에서 CI/CD를 구축하고 이를 팀원들에게 공유하기 전, 스스로 개념과 과정을 익히고자 블로그에 관련 글을 포스팅 하고자 합니다😃 CI/CD 구축을 위한 환경 제가 구축

hidevelop.tistory.com

 

1. Jenkins 필요 라이브러리 설치

Plugin Manager에 접속하여 필요한 플러그인들을 설치한다.

Jenkins 관리  >  Plugins > Available plugins 순으로 들어가면 원하는 플러그인은 설치할 수 있다. 

 

 

 

1.SSH Agent Plugin : 배포할 서버 안에서 명령어를 실행할 때 사용

2.Docker Pipeline : 파이프라인 안에서 Docker Pipeline의 문법을 사용해 이미지를 build하고 push 한다.

3.Bitbucket : bitbucket push시 webhook을 받을 수 있도록 설정할 수 있다.

 

2. 권한 설정(bitbucket, Docker, SSH 접근 권한)

모든 설치가 완료되었으면, 권한을 등록해줘야 합니다. 우리가 등록할 권한은 아래 2개입니다.

Jenkins 관리 > Manage Credentials > (global) > Add Credentials 에서 권한을 추가할 수 있습니다.

 

2 -1. Docker hub에 접근할 수 있는 권한

 - Kind : Username with Password

 - Username : Docker hub ID

 - Password : Docker hun PassWord

 - ID : 추후 Pipeline Script 작성 시 credentialsId로 사용됨 



 

2- 2. SSH로 배포할 서버에 접근할 수 있는 권한

1. Kind : SSH Username with private key

2. ID : Deploy-Server-SSH-Credential

3. Username : ec2 운영체제 사용자(ex : ec2-user, root)

 

2-3. 비트버켓 계정 권한 

 - Kind : Username with Password

 - Username : bitbucket username(저같은 경우는 LJY)입니다.

 - Password : bitbucket PassWord

 - ID : 추후 Pipeline Script 작성 시 credentialsId로 사용됨 

3. 비트 버킷 WebHook 등록

webhook을 간단히 설명드리자면, webhook에 등록되어있는 구독자에게 자기 자신에게 이벤트가 발생할 시 알림을 주는 거라고 생각하시면 될 것같습니다. 

 

순서 : Repository Settings > Webhooks > Add Webhook 

 

webhook을 등록하기 위해서는 도메인이 필요한데요. 저는 서브 도메인이 있어, 해당 도메인으로 진행헀습니다. 도메인 없다면 ngork를 사용해서 해보시는 것도 추천드립니다!!

 

형식 : http://도메인/bitbucket-hook/

 

4. 파이프라인 생성

Jenkins Item

jenkins의 "아이템"은 jenkins에서 작업을 정의하고 관리하는 단위입니다. 젠킨스는 여러 아이템들이 개발자가 설정하는 것에 맞춰 동작하면서, CI/CD 서버를 구축합니다. item은 Pipeline과 Freestyle인 2가지 종류로 나뉩니다.

 

Freestyle

- Freestyle은 GUI를 사용하여 간단하 설정으로 프로젝트를 만들 수 있습니다. 

- Jenkins 대시보드에서 직접 설정할 수 있는 간단한 구성을 제공합니다.

- 단일 빌드 작업에 많이 사용됩니다.

 

Pipline

- Pipline은 연속적인 작업 흐름을 구현하는데 사용됩니다,

- CI/CD 처럼 코드 빌드, 테스트, 배포 등 여러 단계를 하나의 스크립트 파일로 정의하기 때문에, 작업에 대한 흐름을 한 눈에 파악하기 쉽습니다.

- 코드 저장소에 저장된 Jenkinsfile을 통해 정의되며, 코드 형태로 버전 관리를 할 수 있습니다.

 

예시

pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                // 빌드 스크립트 실행
            }
        }
        stage('Test') {
            steps {
                // 테스트 스크립트 실행
            }
        }
        stage('Deploy') {
            steps {
                // 배포 스크립트 실행
            }
        }
    }
}

 

 

어떤 것을 선택해야할까요?

파이프라인 : 복잡하고 지속적인 통합 및 배포 요구 사항이 있고 코드로 작업에 대한 흐름을 파악해야하는 프로젝트에 적합합니다. 코드로 관리할 시에는 단지 코드만을 수정하면 되니 버전관리와 높은 유연성을 확보할 수 있습니다.

 

프리 스타일 : GUI를 통한 간편한 설정이 필요한 경우 사용됩니다. 단순한 빌드 및 테스트 작업에 적합합니다.

 

 

3-1. 파이프라인

대시보드에 새로운 Item을 클릭해줍니다. (블루 오션 열기는 무시하셔도 됩니다.)

 

들어가셔서 item의 이름을 입력하시고, Pipline을 클릭해주신 다음 OK 버튼을 누르시면 됩니다.

 

pipeline을 만들면, BuildTrigger 에서 Build when a change is pushed to BitBucket 에 체크를 하고 CI/CD를 원하는 레포지토리에 URL을 넣어줍니다.

 

3-2. Pipeline 작성(JenkinsFile)

pipeline을 작성하는데 2가지 방법이 있습니다. 

 

프로젝트 내에 JenkinsFile을 작성하여 사용하는 방법 (Pipeline script from SCM)

이 방법은 프로젝트 상단에(src 폴더와 같은 계층)내에 JenkinsFile을 올려놓으면, 이를 젠킨스가 인식하여 배포를하는 방식입니다.

 

젠킨스에서 script 바로 작성 (Pipeline Script)

젠킨스에서 바로 쉘 스크립트를 적어주면 됩니다. (저희는 이방법으로 사용할 것입니다.)

 

JenkinsFile

pipeline {
    agent any
    
    stages {
        stage("Set Variable") {
            steps {
                script {
                    IMAGE_NAME = "도커 이미지 이름"
                    IMAGE_STORAGE = "index.docker.io/v1/" //도커 허브 주소
                    IMAGE_REPOSITORY = "Dokcer 이미지 저장소"
                    IMAGE_STORAGE_CREDENTIAL = "젠킨스에서 설정한 도커 권한 ID"
                    SSH_CONNECTION = "배포서버 퍼블릭 IP"
                    SSH_CONNECTION_CREDENTIAL = "젠킨스에서 설정한 SSH 권한 ID"
                }
            }
        }
        stage("Repository Clone"){
            steps{
                git branch : "배포를 원하는 브랜치", credentialsId : "비트 버켓 권한 ID", url : "자동배포를 원하는 레포지토리 url"
            }
        }
        
        
        stage("Clean Build") {
            steps {
                sh "chmod +x gradlew" // 그래들 명령어 권한 허용
                sh "./gradlew clean bootjar" // 그래들로 clean과 bootjar를 실행
            }
        }
        
        stage("Build Container Image") {
            steps {
                script {
                    image = docker.build("${IMAGE_REPOSITORY}/${IMAGE_NAME}") //이미지 빌드
                }
            }
        }

        stage("Push Container Image") {
            steps {
                script {
                    docker.withRegistry("https://${IMAGE_STORAGE}", IMAGE_STORAGE_CREDENTIAL) {
                        image.push("${env.BUILD_NUMBER}")
                        image.push("latest")
                    }
                }
            }
        }

        stage("Server Run") {
            steps {
                sshagent(['Deploy-Server-SSH']) {
                    sh "ssh  ec2-user@${SSH_CONNECTION} 'docker rm -f ${IMAGE_NAME}'"
                    sh "ssh  ec2-user@${SSH_CONNECTION} 'docker rmi -f ${IMAGE_REPOSITORY}/${IMAGE_NAME}:latest'"
                    sh "ssh  ec2-user@${SSH_CONNECTION} 'docker pull ${IMAGE_REPOSITORY}/${IMAGE_NAME}:latest'"
                    sh "ssh  ec2-user@${SSH_CONNECTION} 'docker images'"
                    sh "ssh  ec2-user@${SSH_CONNECTION} 'docker run -d --name ${IMAGE_NAME} --net my-bridge -p 8000:9000 ${IMAGE_REPOSITORY}/${IMAGE_NAME}:latest'"
                    sh "ssh  ec2-user@${SSH_CONNECTION} 'docker ps'"
                }
            }
        }
    }

}

:

 

 

 

스크립트에 대해 설명을 드리자면,

1. Set Variable : 필요한 변수들을 설정해주는 단계

2. Repository Clone : 비트버킷 저장소에서 코드를 클론하는 단계

3. Cleans Build : gradle을 사용해서 .jar를 파일을 만드는 단계 (gradle의 권한도 설정)

4. Build Container Image : 만든 .jar를 파일을 이미지로 만들어주는 단계

5. Push Container Image : 만든 이미지를 docker hub에 push 해주는 단계

6. Server Run : 배포 서버에서 기존에 존재하던 도커 배포 이미지를 삭제하고 pull 받아서 실행시켜주는 단계

 

이제 작성을 완료하였으면, 시험해 볼차례입니다.

대쉬보드로 나가셔서 만든 파이프라인을 누르고, 지금 빌드를 실행시키면 됩니다.

 

저같은 경우는 JenkinsFile에 오류가 있어서 잡으면서 진행했기 때문에, 시도횟수와 실패 흔적들이 있습니다. ㅠㅠ

 

자 이렇게 자동 배포단계를 만들었습니다. 긴 글 읽어주셔서 감사합니다. 모르는 것이 있으면 댓글 달아주시면 아는 한에서 최대한 답변드리겠습니다 :) 

728x90