::: IT인터넷 :::

Jenkins에 Docker 이미지 빌드 파이프라인 구성

곰탱이푸우 2022. 2. 7. 08:20
Jenkins에 Docker 이미지 빌드 환경을 구성하기 위해 Docker 빌드 에이전트 생성과 Jenkins 연결을 진행했다.
 
해당 과정은 다음 포스팅을 참고한다.
 
그리고 빌드 과정을 테스트하기 위한 Docker 예제  이미지도 만들었다.
 
해당 과정은 다음 포스팅을 참고한다.
이제 Jenkins에서 빌드 플랜을 생성하고 파이프라인을 구성하면, Jenkins에서 Docker 이미지의 빌드와 배포가 가능하다.

 

 

전체 과정

Jenkins에서 진행해야 하는 작업은 다음과 같다.
  1. Jenkins 플러그인 설치
  2. 배포에 사용할 Nexus 계정 생성
  3. 빌드에 사용할 GitLab 계정 생성
  4. GitLab Access Token 발급
  5. Jenkins에 GitLab Access Token 등록
  6. Nexus3 설정
  7. 빌드 생성
  8. 빌드 수행
  9. 빌드와 배포 결과 확인
 
1~5번은 이전에 진행한 파이썬과 Visual Studio 빌드 환경 구성을 진행하면서 이미 다뤘던 내용이다.
따라서 이번 포스팅에서는 다루지 않는다.
 
다음 포스팅을 참고한다.
Nexus3의 경우 배포하는 Docker 이미지를 저장하기 위해 로컬 저장소를 설정해야 한다.
 
로컬 저장소 생성과 이미지 Push 방법은 다음 포스팅을 참고한다.
Docker 이미지를 로컬 저장소에 배포하기 위해서는, 빌드 에이전트가 Docker 로컬 저장소에 로그인 되어 있어야 한다.
빌드 에이전트에서 docker login 명령으로 로컬 저장소에 로그인 되어 있는지 확인한다.
 
아래 포스팅을 다시 참고한다.
위의 모든 과정 준비가 완료되면 아래 3단계를 진행한다.
  1. 빌드 생성
  2. 빌드 수행
  3. 빌드와 배포 결과 확인
 
 

빌드 생성

테스트를 위한 Docker 예제  이미지 빌드 플랜을 생성한다.
 
Jenkins의 좌측 상단의 새로운 Item을 클릭한다.
 
item name에는 프로젝트명인 srtest-docker를 입력한다.
Freestyle project를 선택한 다음 OK를 클릭한다.
 

General 설정

이 빌드는 매개 변수가 있습니다.
General 설정에서는 "이 빌드는 매개 변수가 있습니다"에 체크한다.
매개 변수 추가 선택 후 "Git Parameter"를 선택한다.
 
Git Parameter의 Name에 BRANCH를 입력하고, Parameter Type 에서 Branch를 선택한다.
 
이렇게 설정하면 시작할 때 빌드할 main 브랜치와 작업 브랜치를 선택할 수 있다.
 
Restrict where this project can be run
General 설정의 아래 부분에 Restrict where this project can be run을 선택한다.
Label Expression에는 Docker 빌드 에이전트의 레이블인 DockerBuild01을 입력한다.
 
Docker 빌드 환경이 준비 된 이미지로 실행을 제한하기 위한 것이다.
 
Docker 빌드 가상환경을 Jenkins에 연결하는 방법은 다음 포스팅을 참고한다.
 

소스 코드 관리

소스 코드 관리는 빌드할 코드를 가져오기 위한 설정이다.
 
Git을 선택하고 Repository URL에 GitLab의 해당 프로젝트 git 파일 경로를 입력한다.
Credentials에는 Jenkins에 연동한 GitLab 계정을 선택한다.

 

Jenkins에 GitLab의 계정을 연동하는 방법은 아래 포스팅을 참고한다.
Branches Specifier에는 ${BRANCH}를 입력한다.
General에서 설정한 Git Parameter로 선택한 브랜치의 경로가 전달된다.
 

빌드 환경

빌드 환경에서는 Delete workspace before build starts 옵션에 체크한다.
빌드 진행하기 전에 Workspace 공간을 초기화 하는 기능이다.
 
나머지 옵션들은 사용하지 않는다.

 

 

Build (빌드)

version 정보 환경 변수 등록
먼저 Add build step을 클릭하고 Inject environment variables를 선택한다.

 

Properties File Path에 ./version을 입력한다.
배포에 필요한 저장소 경로와 이미지명, 버전 정보를 환경 변수로 등록한다.

 

아래 포스팅에서 추가한 version 파일을 의미한다.
빌드 명령 작성
다시 Add build step을 클릭하고 Execute shell을 선택한다.
 
추가 되는 블록의 Command 부분에 아래 코드를 입력한다.
#!/bin/bash

# 배포 경로, 이미지명, 버전 정보, 브랜치명 출력
echo "REPO_PATH = " + $REPO_PATH
echo "IMAGE_NAME = " + $IMAGE_NAME
echo "IMAGE_VERSION = " + $IMAGE_VERSION
echo "BRANCH = " + $BRANCH

# 빌드 명령 수행
## main 브랜치인 경우 sr-release 경로 추가
if [ $BRANCH == "origin/main" ]; then
echo "It's MAIN Branch!! - RELEASE!!"
docker build -t $REPO_PATH/sr-release/$IMAGE_NAME:$IMAGE_VERSION .
## 작업 브랜치인 경우 sr-snapshot 경로 추가
else
echo "It's WORK Branch!! - SNAPSHOT!!"
    docker build -t $REPO_PATH/sr-snapshot/$IMAGE_NAME:$IMAGE_VERSION .
fi

# is_success 파일 생성
# 빌드에 성공하면 IS_SUCCESS=True 저장
if [ $? -eq 0 ]; then
  echo "IS_SUCCESS=True" > is_success
# 빌드에 실패하면 IS_SUCCESS=False 저장
else
  echo "IS_SUCCESS=False" > is_success
fi
 
다음과 같이 입력한다. 아래 부분이 잘렸는데, is_success 관련 내용도 포함되어 있다.
 
 
빌드 성공 여부 환경 변수 등록
앞서 생성한 is_success 파일에 기록한 IS_SUCCESS 값을 환경 변수로 등록한다.
 
Add build step을 선택하고 Inject environment variables를 클릭한다.
 
Properties File Path에 is_success를 입력한다.
앞서 생성한 파일명이다.

 

빌드 성공과 실패에 따라 다른 작업을 수행하기 위한 방법이다.
 
각 블록마다 환경 변수가 전달되지 않아 이러한 방법을 사용했는데, 블록을 나누지 않고 단일 Bash Shell 스크립트로 작성해도 된다.
 
빌드 실패인 경우 처리
빌드 실패인 경우에 대해 먼저 추가한다.
 
Add build step을 선택하고 Conditional step (single)을 클릭한다.

 

Run?에서 Strings match를 선택하고, String 1에 ${IS_SUCCESS}, String 2에 False를 입력한다.
 
Builder에서 Execute shell을 선택하고, Command에 아래 코드를 입력한다.
echo $IMAGE_NAME:$IMAGE_VERSION + "Build Failed!!!"
 
빌드 실패 메시지를 출력하는 기능만 수행한다.
아래와 같이 입력하면 된다.
 
 
빌드 성공인 경우 처리
빌드를 성공한 경우 생성 된 이미지를 로컬 저장소에 배포해야 한다.

 

Add build step을 선택하고 Conditional step (single)을 클릭한다.
 
Run?에서 Strings match를 선택하고, String 1에 ${IS_SUCCESS}, String 2에 True를 입력한다.
 
Builder에서 Execute shell을 선택하고, Command에 아래 코드를 입력한다.
# 빌드 성공 메시지 출력
echo $IMAGE_NAME:$IMAGE_VERSION + "Build Success!!!"

# Docker 로컬 저장소에 배포
if [ $BRANCH == "origin/main" ]; then
    echo "It's MAIN Branch!! - REALEASE!!"
    docker push $REPO_PATH/sr-release/$IMAGE_NAME:$IMAGE_VERSION
else
    echo "It's WORK Branch!! - SNAPSHOT!!"
    docker push $REPO_PATH/sr-snapshot/$IMAGE_NAME:$IMAGE_VERSION
fi
 
빌드 성공 메시지를 출력하고, 생성 된 Docker 이미지를 Docker 로컬 저장소에 배포한다.
main 브랜치인 경우 release 경로에, 작업 브랜치인 경우 sr-snapshot 경로에 배포한다.
 
아래와 같이 입력하면 된다.
 
release와 snapshot 경로를 구분한 이유는, Docker 이미지 크기가 크기 때문이다.
사설 저장소의 공간이 부족해지면, 개발중 버전인 snapshot 경로의 파일들만 제거하면 된다.
 
 

생성 된 빌드 산출물 제거

빌드가 완료되면 빌드 산출물을 제거한다.
Docker 이미지를 빌드하면 베이스 이미지, 명령 수행으로 생긴 레이어 이미지, 캐시 데이터, 최종 생성 이미지 등 다양한 산출물이 생성 된다.
 
이러한 산출물은 빌드가 완료되면 깨끗하게 제거하는 것이 빌드 에이전트를 쉽게 관리하는 방법이다.
다행히 Docker에서는 초기화를 위한 prune 명령을 제공한다.
 
먼저 Add build step을 선택하고 Execute shell을 클릭한다.
 
아래 코드를 작성한다.
#!/bin/bash
docker stop $(sudo docker ps -aq)
docker rm $(sudo docker ps -aq)
docker system prune --all --volumes --force
 
아래와 같이 입력하면 된다.
 
실행 중인 모든 컨테이너를 종료하고, 모든 컨테이너를 삭제한다.
그리고 prune 명령을 통해 모든 이미지, 캐시 데이터, 볼륨 등을 삭제한다. --force 옵션은 사용자의 Y/N 선택 없이 바로 실행한다.
 
아래 블로그를 참고하였다.

빌드 후 조치

이제 빌드 파이프라인의 마지막 단계이다.
빌드 후 조치 추가를 선택하고 Delete workspace when build is done을 클릭한다.
 
별도로 설정할 것은 없다.
 
 

빌드 수행과 배포

모든 설정이 완료되었으므로 실제 빌드와 배포를 진행해본다.
 
생성한 빌드 플랜을 클릭하고 좌측의 Build with Parameters를 클릭한다.
 
빌드 할 브랜치를 선택한다. 테스트 코드가 있는 init-commit 브랜치를 선택하고 빌드하기를 클릭한다.
 
좌측 하단에 보이는 것과 같이 빌드가 진행되는 것을 확인할 수 있다.
해당 부분을 클릭한다.
 
좌측의 Console Output을 클릭한다.
 
빌드 진행 관련 로그를 확인할 수 있다.
빌드에 실패한 경우 이 곳에서 로그를 확인하면 확인이 가능하다.
 

 

결과 확인

최종적으로 Docker 로컬 저장소에 업로드가 잘 되었는지 확인한다.
 
Nexus에서 Docker 저장소를 클릭한다.
우측에 빌드 플랜에서 지정한 sr-snapshot 경로에 정상적으로 업로드 된 것을 확인할 수 있다.

 

해당 이미지를 클릭하면 해당 Docker 이미지의 정보를 확인할 수 있다.
 
우측 하단의 목록을 클릭하면 상세 정보가 출력된다.
초기에 설정한 jenkinsbuild 계정으로 업로드 된 것을 확인할 수 있다.

 

보안적인 부분에서 공용 계정을 사용하는 것은 좋지 않은 선택이다.
가급적 담당자 별로 전용 계정을 생성해서 사용할 것을 권장한다.
 
빌드 에이전트에서 확인해보면  깨끗하게 정리 된 것을 확인할 수 있다.
 
이로서 Docker 이미지 빌드 자동화가 완성되었다!!