Jenkins를 통한 CI/CD 구축(1)

박세건·2024년 9월 3일
0

기술 실습

목록 보기
3/18
post-thumbnail

이번 포스팅은 Docker를 통한 Jenkins가 설치되어있다고 생각하고 진행합니다.


CI/CD 전략

  1. PR 생성
  2. 정상적인 빌드 확인
  • 이 과정에서 정상인지 아닌지를 Mattermost를 통해 알림
  1. 정상적인 결과가 확인되면 dev 브랜치에 병합
  2. Jenkins 서버에 Webhook을 통해 전달

    Webhook, 특정 애플리케이션에게 이벤트 발생을 실시간을 알려주기 위한 방법
    ex) 젠킨스의 Webhook URL을 열고 Gitlab에서 Webhook URL로 요청을 받아 이벤트 발생 사실을 확인

  3. Webhook을 통해 신호를 받은 Jenkins는 저장된 파이프라인 스크립트를 실행하여 jar 파일 생성
  • 스프링 부트 패을리케이션을 빌드해서 jar 파일 생성
  1. 생성된 jar이 EC2에게 전달
  2. EC2에서 jar 파일을 실행하여 배포 완료

Job 방식

Job(잡)은 특정 작업을 수행하는 단위로, 일반적으로 소프트웨어의 빌드, 테스트, 배포 등을 자동화하기 위해 설정됩니다.

프리스타일 vs 파이프라인

Job을 생성하는 방식은 크게 2가지로 나눠진다.

  • 프리스타일
    • GUI 기반
    • 간단하지만, 복잡한 과정에 적절하지 않음
  • 파이프라인
    • 코드 기반
    • Jenkinsfile로 파일 관리 가능하고 버전 관리도 가능

GUI보다는 코드 기반으로 작성하는 것이 편리하다는 의견을 확인하여 파이프라인으로 진행

Scripted vs Declarative

파이프라인은 크게 2가지 방식으로 나눠진다.

  • Scripted
    • Groovy 언어
    • 유연성, 확장성 좋음
    • 난이도 높음
  • Declarative
    • 사용이 간단(Groovy 몰라도됌)
    • 최근 많이 사용한다고 함

      Declarative 스타일로 많이 이동된다고 하여 Declarative 방식 선택


Plugin 설치 및 설정

Jenkins에서 관련 플러그인을 설치

  • Dashboard -> Jenkins 관리 -> Plugins -> available Plugins -> Gitlab 검색
  • 관련 Plugin 설치
    • gitlab, mattermost, ssh agent 등

Credentials 추가

Credentials(자격증명) 추가하여 Jenkins가 GitLab에 접근해서 pull or push or merge 할 수 있도록 정보를 등록

  • GitLab 에서 Personal Access Tokens 생성
    • 생성된 토큰은 잊지않도록 관리한다.
  • Jenkins에 Credentials 등록1
    • Dashboard - Jenkins 관리 - Credentials - (global) 마우스 올리기 - “Add credentials” 클릭
    • kind : Username with password 선택
    • Scope : Global 선택
    • Username : git bash 에서 로그인하는 GitLab 계정
    • Password : git bash 에서 로그인하는 GitLab 비밀번호
    • ID : 해당 Credentials를 식별하기 위한 ID (사용자 임의의 문자열로 기입)
    • Description: 설명
  • Jenkins에 Credentials 등록2
    • kind : GitLab API token 선택
    • Scope : Global 선택
    • API token: 앞서 발급한 gitlab access token
    • ID : 해당 Credentials를 식별하기 위한 ID (사용자 임의의 문자열로 기입)
    • Description: 설명

GitLab 연결

  • 이전에 작성해놓은 token 값과 Gitlab host URL을 입력
  • Test Connection으로 Success 확인

Job 생성 및 세팅

  • 파이프라인 선택

Jenkins 파이프라인 생성

  • 새로운 Item 클릭

  • 이름 작성 후 Pipeline 선택 후 OK

  • script 작성(Declarative 방식)

    • Declarative Plugin 설치
    • 기본 틀
    pipeline {
      agent any
    
      stages {
          stage('Build') {
              steps {
                  //
              }
          }
          stage('Test') {
              steps {
                  //
              }
          }
          stage('Deploy') {
              steps {
                  //
              }
          }
      } 
    • pipeline: Jenkins 파이프라인을 정의하는 블록입니다. 이 블록은 파이프라인의 모든 구성 요소를 포함합니다.
    • agent any: 이 파이프라인이 실행될 수 있는 에이전트를 지정합니다. any는 어떤 에이전트에서도 실행 가능함을 의미합니다.

익숙해진다면 코드를 작성하는 것이 좋지만 익숙하지 않다면 Snippet Generator를 사용해서 작성한다.

파이프라인 코드

pipeline {
    agent any



    stages {
        stage('Clone') {
            steps {
               git branch: 'dev', credentialsId: 'qkrtprjs', url: 'https://lab.ssafy.com/qkrtprjs456/test.git'
            }
            post {
                failure {
                  echo 'Repository clone failure !'
                }
                success {
                  echo 'Repository clone success !'
                }
            }
        }
    }
}
  • Git Clone 하겠다는 코드를 작성함

Build Triggers 설정

Dashboard -> dev -> Configuration

  • Build when a change is pushed to GitLab 체크
  • 원하는 트리거 설정
  • 하단에 고급버튼 클릭
  • Secret token에 Generate 클릭 후 토큰 기억하기

GitLab Webhook 생성

  • GitLab에서 Setting > Webhook > Add new webhook
    • URL : Jenkins build Triggers에 있는 주소
    • Secret Token : Jenkins에서 이전에 발급받은 주소
    • Trigger : 이전에 선택했던 옵션
      • push even, merge request events click
      • wildcard pattern : dev
  • 생성되었다면 GitLab에서 push events 버튼으로 테스트 가능

Trouble Shooting

  • "Invalid token" 발생

    ...Secret Token 빼먹었다

  • 하지만 GitLab에서는 정상적으로 테스트가 완료되었고 Jenkins로 넘어왔지만 Jenkins에서 에러가 발생

 ERROR: Error cloning remote repo 'origin'
hudson.plugins.git.GitException: Command "git fetch --tags --force --progress -- https://lab.ssafy.com/qkrtprjs456/test.git +refs/heads/*:refs/remotes/origin/*" returned status code 128:
stdout: 
stderr: remote: HTTP Basic: Access denied. The provided password or token is incorrect or your account has 2FA enabled and you must use a personal access token instead of a password. See https://lab.ssafy.com/help/topics/git/troubleshooting_git#error-on-git-fetch-http-basic-access-denied

위 와 같은 에러가 발생 내용을 보면 2FA 인증이나 토큰과 관련된 에러같은데 해결해보자

시도 과정

  1. Access Token 새로 발급
  • 여전히 같은 에러
  1. Credentials 로 만들었던 토큰은 유저 Access Token을 사용했지만 저장했어야 하는 내용은 프로젝트의 Access Token 이를 수정하고 다시 push
  • 여전히 같은 에러
  1. Login 관련 Credentials 비밀번호 수정
  • Login 관련 Credentials 설정에서 로그인 아이디와 비밀번호를 실제 로그인 하는 과정에서 사용하는 아이디와 비밀번호로 설정 해서 생성 했음
  • 근데 이전에 프로젝트 PUSH 하는 2FA 관련 설정에서는 비밀번호를 User Access Token을 사용해서 해결했었던게 기억남
  • Credentials의 비밀번호를 User Access Token으로 수정하니 정상적으로 Jenkins에서 인식

Webhook을 통해 프로젝트의 push를 인식하고 clone하도록 정상적으로 확인
이어서 빌드와 배포 과정도 실행하도록 구현해보자

profile
멋있는 사람 - 일단 하자

0개의 댓글