사이드 프로젝트를 위한 Jenkins 구축하기3 - 파이프라인 훑어보기
사이드 프로젝트를 위한 Jenkins 구축하기3 - 파이프라인 훑어보기
들어가며
이번 포스트는 책 내용을 참고하지 않고, AI & 구글 검색을 통해 수행하였습니다. 제 홈서버인 ubuntu를 기반으로 하고 있습니다
계기
- 사이드 프로젝트에서 ci/cd를 젠킨스로 선정함
- 세팅을 많이 해보지 않는 상태로 레퍼런스가 많고, 성능이 어느정도 검증된 것을 선택하는 것이 좋다고 판단함
젠킨스 파이프라인 훑어보기
젠킨스 파이프라인
- 젠킨스에 강력한 자동화 도구 세트를 추가하는 플러그인 모음
- 파이프라인은 코드로 정의된 일련의 자동화 프로세스
- 복잡한 빌드, 테스트, 배포 과정을 일관되게 자동화 해줌
파이프라인 플로우 차트 예시
파이프라인 주요 구성 요소
Jenkinsfile
- 파이프라인의 정의를 담고 있는 텍스트 파일
- 소스 코드 관리 시스템에 저장
- Jenkinsfile은 프로젝트의 빌드, 테스트, 배포 단계를 정의하며, 이를 통해 파이프라인을 코드로 관리
Stage
- 파이프라인의 주요 단계를 정의하는 블록
- 각 스테이지는 빌드, 테스트, 배포와 같은 특정 작업을 수행
- 스테이지는 파이프라인의 진행 상황을 시각적으로 보여주는 역할도 수행
Step
- 스테이지 내에서 실행되는 개별 작업 단위
- Jenkins에게 무엇을 수행할지 지시
- 선언적 파이프라인과 스크립트 파이프라인 모두에서 기본 구성 요소로 사용
파이프라인의 두 가지 문법
선언적 파이프라인(Declarative Pipeline)과 스크립트 파이프라인(Scripted Pipeline)
|특성|선언적 파이프라인|스크립트 파이프라인| |–|–|–| |문법| 더 엄격하고 구조화된 문법| Groovy 기반의 유연한 문법| 시작 구문| pipeline { } 블록으로 시작| node { } 블록으로 시작| 학습 곡선| 상대적으로 낮음, 초보자에게 적합| 상대적으로 높음, Groovy 지식 필요| 유연성| 제한적, 사전 정의된 구조 내에서만 작동| 매우 높음, 복잡한 로직 구현 가능| 프로그래밍 모델| 선언적(declarative) 프로그래밍 모델| 명령형(imperative) 프로그래밍 모델| 오류 처리| 내장된 오류 처리 메커니즘 (post 섹션)| 직접 try-catch 블록 구현 필요| 조건문| when 지시어 사용| 일반 Groovy 조건문 사용 (if-else)| 병렬 실행| parallel 지시어로 간단히 구현| 더 복잡한 구현 필요| 재사용성| 공유 라이브러리를 통해 제한적| 함수 정의와 호출로 높은 재사용성| 가독성| 높음, 표준화된 구조| 복잡한 파이프라인에서는 낮을 수 있음| 유지보수| 일반적으로 더 쉬움| 복잡한 코드는 유지보수가 어려울 수 있음| 단계 정의| stages와 steps 블록 필수| 더 자유로운 구조|
선언적 파이프라인(Declarative Pipeline) 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
pipeline {
agent any
environment {
MAVEN_HOME = tool 'Maven'
VERSION = '1.0.0'
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Build') {
steps {
sh "${MAVEN_HOME}/bin/mvn clean package"
echo "Building version ${VERSION}"
}
}
stage('Test') {
steps {
sh "${MAVEN_HOME}/bin/mvn test"
}
post {
always {
junit '**/target/surefire-reports/*.xml'
}
}
}
stage('Deploy') {
when {
branch 'main'
}
steps {
echo "Deploying to production..."
// 배포 스크립트
}
}
}
post {
success {
echo "Pipeline completed successfully!"
emailext (
subject: "Build Successful: ${currentBuild.fullDisplayName}",
body: "The build was successful.",
to: "team@example.com"
)
}
failure {
echo "Pipeline failed!"
emailext (
subject: "Build Failed: ${currentBuild.fullDisplayName}",
body: "The build failed. Please check the logs.",
to: "team@example.com"
)
}
}
}
스크립트 파이프라인(Scripted Pipeline) 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
node {
def mvnHome = tool 'Maven'
def version = '1.0.0'
try {
stage('Checkout') {
checkout scm
}
stage('Build') {
sh "${mvnHome}/bin/mvn clean package"
echo "Building version ${version}"
}
stage('Test') {
sh "${mvnHome}/bin/mvn test"
junit '**/target/surefire-reports/*.xml'
}
// 조건부 배포
stage('Deploy') {
if (env.BRANCH_NAME == 'main') {
echo "Deploying to production..."
// 배포 스크립트
} else {
echo "Skipping deployment for branch ${env.BRANCH_NAME}"
}
}
// 성공 알림
currentBuild.result = 'SUCCESS'
emailext (
subject: "Build Successful: ${currentBuild.fullDisplayName}",
body: "The build was successful.",
to: "team@example.com"
)
} catch (Exception e) {
// 실패 처리
currentBuild.result = 'FAILURE'
emailext (
subject: "Build Failed: ${currentBuild.fullDisplayName}",
body: "The build failed: ${e.message}",
to: "team@example.com"
)
throw e
} finally {
// 항상 실행되는 정리 작업
echo "Pipeline execution completed"
}
}
파이프라인의 장점
- 코드로서의 파이프라인
- 빌드 프로세스를 코드로 정의하여 버전 관리 시스템에서 관리
- 내구성
- Jenkins 서버가 예기치 않게 다시 시작되더라도 파이프라인 작업 지속 가능
- 일시 중지 가능
- 파이프라인은 사용자 입력을 기다리기 위해 일시 중지 가능
- 다양한 기능
- 조건부 실행, 병렬 실행, 루프, 변수 등 다양한 프로그래밍 기능을 지원
- 확장성
- 공유 라이브러리를 통해 공통 파이프라인 코드를 재사용 가능
배운 점
- 젠킨스의 기본 파이프라인 구조를 이해할 수 있었음
This post is licensed under CC BY 4.0 by the author.