Jenkins 파이프라인 빌드 실패 해결
Jenkins 파이프라인에서 발생하는 빌드 실패 문제를 진단하고 해결하는 방법을 알아봅니다.
Jenkins 파이프라인 빌드 실패 해결
Jenkins 파이프라인은 복잡한 CI/CD 워크플로우를 구현할 수 있지만, 다양한 원인으로 빌드가 실패할 수 있습니다.
Environment
$ java -version
openjdk version "17.0.9" 2023-10-17
$ jenkins --version
Jenkins 2.426.2Problem: Pipeline Execution Failure
// Jenkinsfile
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'python -m build'
}
}
stage('Test') {
steps {
sh 'pytest tests/'
}
}
}
}에러 출력:
[Pipeline] sh
+ python -m build
ERROR: No module named build
[Pipeline] }
ERROR: script returned exit code 1또는:
[Pipeline] End of Sandbox
java.io.IOException: script returned exit code 1
at org.jenkinsci.plugins.workflow.cps.CpsStepContext$3.checkOutcome(CpsStepContext.java:463)Analysis: Jenkinsfile 분석
# Jenkins 로그 확인
$ docker exec jenkins cat /var/log/jenkins/jenkins.log | tail -100
# Pipeline Syntax 확인
$ java -jar jenkins-cli.jar declarative-linter < Jenkinsfile
# Groovy 문법 검증
$ groovy -c JenkinsfileSolution: Pipeline 에러 해결
방법 1: Agent 및 환경 설정
// Jenkinsfile
pipeline {
agent {
docker {
image 'python:3.11-slim'
args '-v $HOME/.cache:/root/.cache'
}
}
environment {
PYTHONDONTWRITEBYTECODE = '1'
PYTHONUNBUFFERED = '1'
}
stages {
stage('Setup') {
steps {
sh 'pip install --upgrade pip'
sh 'pip install -r requirements.txt'
}
}
stage('Build') {
steps {
sh 'python -m build'
}
}
stage('Test') {
steps {
sh 'pytest tests/ --junitxml=reports/junit.xml'
}
}
}
post {
always {
junit 'reports/junit.xml'
}
}
}방법 2: Credentials 관리
pipeline {
agent any
environment {
AWS_CREDENTIALS = credentials('aws-deployer')
SONAR_TOKEN = credentials('sonar-token')
}
stages {
stage('Build') {
steps {
withCredentials([
string(credentialsId: 'docker-hub-pass', variable: 'DOCKER_PASS')
]) {
sh 'echo $DOCKER_PASS | docker login -u username --password-stdin'
}
}
}
stage('Deploy') {
steps {
withAWS(credentials: 'aws-deployer', region: 'eu-west-1') {
sh 'aws s3 sync dist/ s3://my-bucket/'
}
}
}
}
}방법 3: Parallel Execution
pipeline {
agent any
stages {
stage('Build') {
parallel {
stage('Unit Tests') {
steps {
sh 'pytest tests/unit/ --junitxml=unit.xml'
}
}
stage('Integration Tests') {
steps {
sh 'pytest tests/integration/ --junitxml=integration.xml'
}
}
stage('Lint') {
steps {
sh 'flake8 src/'
}
}
}
}
}
post {
always {
junit '**/*.xml'
archiveArtifacts artifacts: 'dist/**', allowEmptyArchive
}
}
}방법 4: Error Handling
pipeline {
agent any
stages {
stage('Deploy') {
steps {
script {
try {
sh './deploy.sh'
} catch (Exception e) {
currentBuild.result = 'FAILURE'
slackSend(
channel: '#alerts',
message: "Deployment failed: ${e.message}"
)
throw e
}
}
}
}
}
post {
failure {
sh 'echo "Deployment failed, rolling back..."'
sh './rollback.sh'
}
}
}방법 5: Shared Libraries
// vars/pythonPipeline.groovy
def call(Map config = [:]) {
pipeline {
agent {
docker {
image config.dockerImage ?: 'python:3.11-slim'
}
}
stages {
stage('Build') {
steps {
sh "pip install -r ${config.requirementsFile ?: 'requirements.txt'}"
sh config.buildCommand ?: 'python -m build'
}
}
stage('Test') {
steps {
sh config.testCommand ?: 'pytest tests/'
}
}
}
}
}
// Jenkinsfile
@Library('my-shared-library') _
pythonPipeline(
dockerImage: 'python:3.11',
buildCommand: 'make build',
testCommand: 'make test'
)Troubleshooting Commands
# 1. Pipeline 로그 확인
$ curl -s http://jenkins:8080/job/myjob/lastBuild/consoleText
# 2. Pipeline Syntax 검증
$ java -jar jenkins-cli.jar declarative-linter < Jenkinsfile
# 3. Node 상태 확인
$ curl -s http://jenkins:8080/computer/api/json
# 4. 환경 변수 확인
$ java -jar jenkins-cli.jar groovysh
> println System.getenv()
# 5. Jenkins 재시작
$ sudo systemctl restart jenkinsLessons Learned
Docker Agent 활용: 파이프라인별로 필요한 도구를 Docker image로 관리하면 환경 일관성을 유지할 수 있습니다.
Credentials 관리: Secrets는 Jenkins Credentials에 저장하고, 파이프라인에서만 사용하세요.
에러 핸들링: try-catch와 post 블록을 사용하여 빌드 실패 시 알림 및 롤백을 구현하세요.
Shared Library: 여러 프로젝트에서 반복되는 파이프라인 로직은 Shared Library로 만드세요.
로그 관리: 상세 로그를 남기고, JUnit 같은 리포트로 테스트 결과를 추적하세요.
This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.