본문 바로가기

Jenkins

[Jenkins] Docker Jenkins로 Spring Boot 빌드 및 배포 - 2 (파이프라인 작성 및 빌드 테스트)

반응형

 

시스템 환경

  • jenkins 인스턴스 (ec2 ubuntu 20.04)
  • server 인스턴스 (ec2 ubuntu 20.04)
  • 개발 데스크탑 (mac 12.0.1)

 

구현할 파이프라인 구조

  1. 개발 데스크탑에서 코드 작성 후 github push
  2. github에서 webhook -> jenkins instance
  3.  jenkins 파이프라인실행
    1. git clone
    2. gradle build
    3. docker build
    4. docker image push
    5. jenkins 인스턴스에서 server 인스턴스로 ssh 접속
    6. server 인스턴스 docker image pull
    7. server 인스턴스 docker image run
    8. server 인스턴스 기존에 같은 서비스 존재 시 기존 서비스 종료
  4. jenkins에서 메일 또는 슬랙으로 결과 전송

 

 

Docker Jenkins로 Spring Boot 빌드 및 배포 - 1 (Jenkins 권한 및 플러그인 설정)

 

 

[Jenkins] Docker Jenkins로 Spring Boot 빌드 및 배포 - 1 (Jenkins 권한 및 플러그인 설정)

시스템 환경 jenkins 인스턴스 (ec2 ubuntu 20.04) server 인스턴스 (ec2 ubuntu 20.04) 개발 데스크탑 (mac 12.0.1) 구현할 파이프라인 구조 개발 데스크탑에서 코드 작성 후 github push github에서 webhook ->..

kanoos-stu.tistory.com

 

 

파이프라인 코드 작성

작성할 파이프라인은

jenkins인스턴스에서 git clone -> gradle build -> docker build -> docker push

순으로 작업이 진행된다.

Declarative pipeline 문법

pipeline {
    agent any

    triggers {
        pollSCM('*/3 * * * *')
    }

    environment {
        imagename = "docker build로 만들 이미지 이름"
        registryCredential = 'docker hub credential ID'
        dockerImage = ''
    }

    stages {
        // git에서 repository clone
        stage('Prepare') {
          steps {
            echo 'Clonning Repository'
            git url: 'git repository 주소',
              branch: 'master',
              credentialsId: '생성한 github access token credentail id'
            }
            post {
             success { 
               echo 'Successfully Cloned Repository'
             }
           	 failure {
               error 'This pipeline stops here...'
             }
          }
        }

        // gradle build
        stage('Bulid Gradle') {
          agent any
          steps {
            echo 'Bulid Gradle'
            dir ('.'){
                sh """
                ./gradlew clean build --exclude-task test
                """
            }
          }
          post {
            failure {
              error 'This pipeline stops here...'
            }
          }
        }
        
        // docker build
        stage('Bulid Docker') {
          agent any
          steps {
            echo 'Bulid Docker'
            script {
                dockerImage = docker.build imagename
            }
          }
          post {
            failure {
              error 'This pipeline stops here...'
            }
          }
        }

        // docker push
        stage('Push Docker') {
          agent any
          steps {
            echo 'Push Docker'
            script {
                docker.withRegistry( '', registryCredential) {
                    dockerImage.push("docker tag name")  // ex) "1.0"
                }
            }
          }
          post {
            failure {
              error 'This pipeline stops here...'
            }
          }
        }
    }
}

*Dockerfile은 spring project 내부에 같이 있어 clone시 Dockerfile도 생성됨.

 

Jenkins build

작성한 파이프라인을 빌드 및 테스트해보기 위해 콘솔에서 파이프라인을 생성해야한다.

먼저 Dashboard -> 새로운 Item을 선택하면 다음 화면이 나온다. 

item의 이름을 자신이 알아볼 수 있게 입력하고 Pipeline 선택 후 OK 버튼을 눌러준다.

 

해당 화면에서 'Build Now' 를 클릭하면 jenkins build가 실행되고 잠시 후 다음과 같이 Stage View에 진행 상황이 나올것이다.

실패하면 좌측 하단 Build History를 통해 자세한 로그를 확인할 수 있다.

 

파이프라인이 실패없이 진행되었다면 docker hub에서 해당 image가 update된 것을 확인할 수 있다.

 

반응형

 

 

Server인스턴스에 SSH 접속

이제 남은 파이프라인 작업은 jenkins인스턴스에서 server인스턴스로 ssh 접속하여 docker image pull 및 run 작업을 시켜주면 된다.

먼저 sshagent plugin을 설치해준다.

이전과 마찬가지고 Dashboard -> Jenkins 관리 -> 플러그인 관리에서 ssh agent를 검색하고 체크 및 Download now and install after restart 버튼 클릭 후 재시작

 

그리고 server인스턴스에 ssh접속할 수 있도록 Credentail을 등록해준다.

 

Kind 드롭박스에서 SSH Username with private key를 선택해주고

ID는 server인스턴스의 유저명 (ec2 ubuntu의 경우 ubuntu)

Username은 파이프라인 코드에서 식별할 키값

Private Key에서 Enter directly를 체크하고 add 버튼을 누른 뒤 server인스턴스의 pem 파일내용을 그대로 넣어준다.

-----BEGIN RSA PRIVATE KEY----- 

~~~~~

-----END RSA PRIVATE KEY-----

모두 포함해서 입력해야한다.

 

그리고 다음과 같이 파이프라인을 빌드 하면

 pipeline {
    agent any
    stages { 
        stage('SSH SERVER EC2') {
          steps {
            echo 'SSH'
            
            sshagent(['credentail 식별 값']) {
                sh 'ssh -o StrictHostKeyChecking=no [user name]@[ip address] "whoami"'
                sh "ssh -o StrictHostKeyChecking=no [user name]@[ip address] 'docker pull [이미지 이름]:[태그 이름]'"
                sh "ssh -o StrictHostKeyChecking=no [user name]@[ip address] 'docker run [이미지 이름]:[태그 이름]'"
            }
          }
       }
    }
}

-o StrictHostKeyChecking=no - ssh접속 시 host의 key를 확인하지 않음

 

docker ps 명령어로 서비스가 실행된 것을 확인할 수 있다.

그 외에 script파일 실행같은 부가적으로 필요한 코드는 필요에 맞게 작성하면 된다.

해당 코드의 stage 부분만 처음 파이프라인 코드의 stages 가장 밑에 추가해주면 

  1. jenkins인스턴스 git clone
  2. jenkins인스턴스 gradle build
  3. jenkins인스턴스 docker build
  4. jenkins인스턴스 docker push
  5. jenkins인스턴스 -> server인스턴스 ssh접속
  6. server인스턴스 docker pull
  7. server인스턴스 docker run

다음과 같은 순서로 동작하는 파이프라인이 완성된다.

 

 

반응형

 

 

Slack 메세지 전송

먼저 플러그인을 설치한다.

Dashboard -> Jenkins관리 -> 플러그인 관리 -> slack 검색 및 slack notification 선택 후 설치

플러그인이 설치 되었으면 jenkins에서 slack channel 접근할 권한을 부여해야한다.

먼저 slack에서 토큰 및 하위 도메인을 발급받는다.

 

slack 앱에서 하단의 앱 추가 -> jenkins 검색 -> jenkins 선택 후 연동을 하면 연동 가이드 웹페이지에 하위 도메인과 토큰이 출력되어있다.

다음은 jenkins에서 slack 토큰정보 입력

Dashboard -> Jenkins관리 -> 시스템 설정 -> Slack 탭에서 

 

 

Workspace - 하위 도메인 / Default channel - 메세지 받을 채널 명

Credential은 생성되어있지않으므로 Add -> Jenkins 선택

 

Kind 목록에서 Secret text를 선태갛고

Secret - 발급받은 slack 토큰 / ID 는 파이프라인 코드에서 식별할 값

을 입력 후 Add를 선택하고 기존화면에서 생성한 Credential을 선택해 준다.

그리고 문제가없다면 Test Connection을 클릭하면 Success 로그와 함께 해당 slack채널로 

 

해당 메세지가 전송 될 것이다.

 

마지막으로 파이프라인 코드에서 slack 메세지를 전송

pipeline {
    // 스테이지 별로 다른 거
    agent any

    stages {
        stage("foo") {
            steps {
                echo 'slack test'
            }
            post {
                success {
                    slackSend channel: '#channel-name', color: 'good', message: "success"
                }
                failure {
                    slackSend channel: '#channel-name', color: 'danger', message: "failure"
                }
            }
        }
    }
}

해당 코드를 빌드하면 success 메세지가 slack의 해당 채널로 전송될 것이다.

 

관리에 유용하게 필요한 부분에 적절하게 slack 메세지를 사용하면 된다.

반응형