젠킨스 빌드 실패 문제 해결: 종합 가이드

이 종합 가이드는 젠킨스 빌드 실패를 신속하게 진단하고 해결하기 위한 전문가 전략을 제공합니다. 콘솔 로그를 체계적으로 분석하여 근본 원인을 찾고, SCM 인증, 환경 설정 오류(PATH 및 도구 버전), 종속성 캐싱, 빌드 에이전트의 리소스 제약 등 일반적인 함정을 해결하는 방법을 배울 수 있습니다. 개발자가 강력하고 신뢰할 수 있는 CI/CD 파이프라인을 유지할 수 있도록 실용적인 단계와 명령줄 예제가 포함되어 있습니다.

젠킨스 빌드 실패 문제 해결: 종합 가이드

빌드 실패는 CI/CD에서 정상적인 현상입니다. 비용이 많이 드는 부분은 빨간 상태 자체가 아니라 모두가 추측하며 시간을 낭비하는 것입니다. 젠킨스는 코드 오류, 누락된 자격 증명, 에이전트 문제, 종속성 중단 또는 플러그인 문제를 가리킬 수 있습니다. 작업은 이를 신속하게 분리하는 것입니다.

첫 번째 실제 오류, 에이전트 이름, 커밋 SHA, 마지막 성공적인 빌드 이후 변경된 사항부터 시작하세요. 이 네 가지 사실은 일반적으로 많은 노이즈를 방지합니다.


첫 번째 단계: 콘솔 출력 분석

젠킨스 빌드 실패 문제 해결에서 가장 중요한 도구는 콘솔 출력입니다. 이 로그에는 실행된 모든 명령, 모든 출력 스트림, 그리고 결정적으로 오류 메시지를 포함한 전체 실행 기록이 포함되어 있습니다.

근본 원인 찾기

최종 실패 상태보다는 첫 번째 실제 오류 메시지를 찾기 위해 위로 스크롤하는 것이 중요합니다. 오류는 종종 연쇄적으로 발생합니다. 단일 환경 설정 오류로 인해 수십 개의 후속 오류 및 스택 추적이 발생할 수 있습니다. ERROR, FATAL, EXCEPTION 또는 특정 빌드 도구 오류(예: Maven BUILD FAILURE, npm ELIFECYCLE)와 같은 키워드를 찾으세요.

팁: 콘솔 출력이 지나치게 큰 경우 브라우저의 검색 기능을 사용하거나 로그를 정규 표현식 검색을 지원하는 텍스트 편집기에 복사하여 오류 표시로 빠르게 이동하세요.

빌드 실패의 일반적인 범주 및 해결 방법

빌드 실패는 일반적으로 다섯 가지 주요 범주로 나뉩니다. 이러한 범주를 체계적으로 조사하면 철저한 진단이 가능합니다.

1. 소스 제어 관리(SCM) 문제

초기 체크아웃 단계에서 발생하는 실패는 일반적으로 연결, 인증 또는 경로 구성과 관련이 있습니다.

원인 진단/해결 방법
인증 실패 젠킨스(또는 에이전트)에 리포지토리를 복제하는 데 필요한 자격 증명(SSH 키, 개인 액세스 토큰, 사용자 이름/비밀번호)이 없습니다. 해결 방법: 파이프라인에 사용된 자격 증명 ID가 젠킨스에 저장된 유효하고 만료되지 않은 자격 증명과 일치하는지, 그리고 젠킨스 에이전트가 이를 사용할 수 있는 액세스 권한이 있는지 확인하세요.
잘못된 브랜치/태그 지정된 브랜치 또는 태그가 존재하지 않거나 구성이 오래된 참조를 가리킵니다.
얕은 복제 문제 리포지토리가 얕은 복제(depth: 1)로 구성된 경우, 빌드 프로세스가 나중에 다운로드되지 않은 기록 커밋이나 태그에 액세스하려고 하면 실패할 수 있습니다.

2. 환경 및 경로 구성 오류

가장 빈번한 실패 원인 중 하나는 로컬 개발자 환경과 원격 젠킨스 에이전트 환경 간의 차이입니다. 에이전트에 도구나 경로 정의가 누락될 수 있습니다.

누락된 도구 및 경로 진단

  1. 환경 변수 덤프: 파이프라인에 간단한 단계를 추가하여 에이전트가 사용하는 환경 변수를 출력합니다. 이는 PATH가 올바르게 설정되었고 시스템 변수가 정의되었는지 확인합니다.

    stage('환경 확인') {
        steps {
            sh 'printenv'
            // 또는 특정 도구 확인
            sh 'java -version'
            sh 'mvn -v'
        }
    }
    
  2. 도구 설치 확인: 빌드를 실행하는 젠킨스 에이전트에 필요한 도구(Java Development Kit, Node.js, Python, Maven 등)가 설치되어 있는지 확인하세요. 젠킨스가 도구 설치를 관리하는 경우 Manage Jenkins > Global Tool Configuration에서 도구 구성을 확인하세요.

  3. 셸 차이: 복잡한 셸 스크립팅이 포함된 실패의 경우, 다른 에이전트에서 사용되는 셸(예: /bin/bash vs. /bin/sh) 간의 호환성을 확인하세요.

3. 종속성 및 빌드 도구 실패

이러한 실패는 빌드 도구(예: npm, pip, Maven, Gradle)가 실행되지만 종속성을 해결하거나 코드를 컴파일할 수 없을 때 발생합니다.

네트워크 및 리포지토리 액세스

  • 방화벽 차단: 젠킨스 에이전트가 회사 방화벽 또는 보안 그룹 제한으로 인해 외부 종속성 리포지토리(예: Maven Central, Docker Hub, PyPI)에 연결할 수 없을 수 있습니다. 해결 방법: 에이전트 머신에서 curl 또는 wget을 사용하여 리포지토리 URL에 수동으로 연결을 테스트하세요.
  • 프록시 구성: 외부 액세스에 프록시가 필요한 경우, 프록시 설정(HTTP_PROXY, HTTPS_PROXY)이 젠킨스 에이전트 환경 변수에 올바르게 정의되어 있는지 확인하세요.

손상된 캐시 및 로컬 아티팩트

빌드 도구가 유지 관리하는 로컬 캐시(예: Maven의 ~/.m2/repository 또는 Node의 ~/.npm)가 손상되어 확인 실패가 발생할 수 있습니다.

  • 실행 가능한 해결 방법: 에이전트의 캐시 디렉토리를 일시적으로 지우거나 이름을 바꾸고 빌드를 다시 실행하세요. Maven의 경우 종속성 업데이트를 강제로 적용하기 위해 -U 플래그를 사용하여 실행할 수 있습니다.

4. 작업 공간 및 리소스 제약

젠킨스 빌드에는 적절한 리소스, 특히 디스크 공간과 파일 시스템 권한이 필요합니다.

디스크 공간 및 권한

  • 장치에 남은 공간 없음: 젠킨스 에이전트의 작업 공간 드라이브가 가득 차면 빌드 프로세스(특히 대규모 아티팩트를 생성하거나 Docker 빌드를 실행하는 경우)가 실패합니다. 해결 방법: 보존 정책 또는 자동화된 작업 공간 정리 스크립트를 구현하세요. 에이전트 디스크 사용량을 사전에 모니터링하세요.
  • 권한 거부: 젠킨스 실행기 사용자에게 특정 디렉토리, 임시 파일 또는 출력 경로에 대한 읽기/쓰기 권한이 없을 수 있습니다. 해결 방법: jenkins 사용자(또는 에이전트 프로세스를 실행하는 사용자)에게 작업 공간(/var/lib/jenkins/workspace/) 및 빌드가 액세스하는 모든 외부 디렉토리에 대한 필요한 권한이 있는지 확인하세요.

오래된 작업 공간

때로는 이전 실패한 빌드의 잔여 파일(예: 오래된 컴파일된 아티팩트, 잠금 파일)이 새 빌드를 방해할 수 있습니다. 작업 공간을 수동으로 삭제한 후 빌드가 성공하기 시작하면 오래된 데이터가 원인일 가능성이 높습니다.

  • 모범 사례: 파이프라인의 시작 또는 끝에 cleanWs() 단계를 사용하거나, 체크아웃 전에 작업 공간을 지우도록 작업을 구성하세요.

    pipeline {
        agent any
        stages {
            stage('정리') {
                steps {
                    cleanWs()
                }
            }
            // ... 나머지 파이프라인
        }
    }
    

5. 플러그인 및 젠킨스 시스템 문제

환경 문제보다 덜 일반적이지만 시스템 수준 문제는 빌드를 전체적으로 중단시킬 수 있습니다.

  • 플러그인 충돌/비권장: 최근에 업데이트되었거나 새로 설치된 플러그인이 기존 파이프라인 단계 또는 핵심 젠킨스 기능과 충돌할 수 있습니다. 해결 방법: 젠킨스 시스템 로그(Manage Jenkins > System Log)에서 플러그인 관련 예외를 확인하세요. 문제가 있는 플러그인 버전을 롤백해 보세요.
  • 파이프라인 구문 오류(Groovy): 선언적 또는 스크립트형 파이프라인을 사용하는 경우 구문 오류, 일치하지 않는 괄호 또는 승인되지 않은 메서드(Groovy 샌드박스가 활성화된 경우)로 인해 실행이 즉시 실패합니다. 해결 방법: 내장된 Pipeline Syntax 생성기와 실패한 작업의 Replay 기능을 사용하여 작은 수정 사항을 빠르게 테스트하세요.

고급 디버깅 기술

지속적이거나 복잡한 실패의 경우 더 깊은 조사가 필요합니다.

분리 및 재현

젠킨스 외부에서, 빌드 에이전트 머신에서 동일한 사용자 및 환경 변수를 사용하여 정확한 실패 시퀀스를 재현해 보세요. 프로세스가 수동으로 실패하면 문제는 코드 또는 에이전트 설정에 있으며 젠킨스 자체에 있는 것이 아닙니다.

디버그 플래그 사용

많은 빌드 도구는 실행 논리에 대한 추가 통찰력을 제공하는 자세한 정보 표시 또는 디버그 모드를 제공합니다.

도구 디버그 플래그/명령
셸 스크립트 셸 스크립트 시작 부분에 set -x를 추가하여 명령이 실행되기 전에 출력합니다.
Maven mvn clean install -X(광범위한 디버깅의 경우) 또는 mvn clean install -e(스택 추적의 경우)를 사용하세요.
Gradle ./gradlew build --debug 또는 ./gradlew build --stacktrace를 사용하세요.

원격 셸 액세스

정책에서 허용하는 경우 젠킨스 에이전트 머신에 직접 SSH 세션을 설정하세요. 이를 통해 파일 권한을 검사하고, 실시간 리소스 사용량(df -h, top)을 확인하고, 젠킨스 사용자와 동일하게 명령을 실행할 수 있습니다.

실제로 도움이 되는 예방

젠킨스 실패 문제 해결은 콘솔 출력에서 시작하여 SCM, 환경, 종속성 및 리소스 확인을 체계적으로 진행하는 체계적인 접근 방식이 필요합니다. 대부분의 실패는 환경 드리프트 또는 인증 문제에서 비롯됩니다.

향후 실패를 최소화하려면 다음 모범 사례를 채택하세요.

  1. 컨테이너 사용(Docker): Docker 컨테이너 내에서 빌드를 실행하여 모든 작업에 대해 일관되고 격리된 환경을 보장하고 대부분의 환경 경로 및 도구 설치 문제를 제거합니다.
  2. 명시적 환경 정의: 모든 필요한 환경 변수(예: JAVA_HOME)를 젠킨스 작업 또는 파이프라인 스크립트 내에서 명시적으로 정의합니다.
  3. 강력한 정리 구현: 체크아웃 전에 작업 공간을 지우거나 빌드 후에 정리하여 오래된 데이터 충돌을 방지합니다.

처음 10분 동안의 빌드 실패 분류

처음 10분은 문제 해결이 침착하게 진행될지 아니면 무작위 재실행으로 바뀔지를 결정합니다. 먼저 네 가지 사실을 수집하세요: 실패한 빌드 번호, 에이전트 이름, 커밋 SHA, 첫 번째 실제 오류 줄. 변경을 가하기 전에 이를 인시던트 노트나 티켓에 기록하세요.

그런 다음 동일한 커밋이 다른 곳에서 통과했는지 물어보세요. 동일한 커밋이 다른 브랜치나 에이전트에서 통과하면 문제는 환경, 자격 증명, 타이밍 또는 인프라일 가능성이 높습니다. 동일한 커밋이 모든 곳에서 실패하면 코드, 종속성 잠금 파일 또는 파이프라인 정의일 가능성이 더 높습니다. 하나의 에이전트만 실패하면 이유를 이해할 때까지 해당 에이전트를 격리하세요. 의심스러운 에이전트에 더 많은 작업을 할당하면 노이즈가 많은 실패가 발생합니다.

실패가 알려진 불안정한 외부 종속성처럼 보이면 한 번 다시 실행하세요. 증거를 수집하지 않고 다섯 번 다시 실행하지 마세요. 재실행은 명확한 실패를 운 좋은 통과로 대체하여 유용한 패턴을 지울 수 있습니다.

체크아웃 실패는 별도의 경로가 필요합니다.

프로젝트 명령이 실행되기 전에 빌드가 실패하면 소스 제어에 집중하세요. 일반적인 징후로는 원격 리포지토리에서 읽을 수 없음, 인증 실패, 리포지토리를 찾을 수 없음, 호스트 키 확인 실패, 빌드할 개정판을 찾을 수 없음이 있습니다.

SSH 기반 Git 체크아웃의 경우 노트북이 아닌 에이전트에서 테스트하세요.

ssh -T [email protected]
git ls-remote [email protected]:org/repo.git

가능하면 동일한 젠킨스 사용자를 사용하세요. 터미널에서 관리자에게 작동하는 자격 증명이 젠킨스가 작업에 사용하는 자격 증명과 다를 수 있습니다. HTTPS 체크아웃의 경우 만료된 개인 액세스 토큰과 변경된 리포지토리 권한이 일반적입니다. 멀티브랜치 파이프라인의 경우 브랜치 인덱싱과 빌드 체크아웃이 다른 자격 증명을 사용할 수 있음을 기억하세요.

젠킨스가 브랜치를 찾을 수 없으면 브랜치가 여전히 존재하고 refspec에 포함되어 있는지 확인하세요. 풀 리퀘스트 작업은 제공자에 따라 다른 병합 참조 또는 변경 참조를 사용할 수 있습니다.

빌드 도구 실패는 일반적으로 젠킨스 실패가 아닙니다.

Maven, Gradle, npm, pip, Go, Docker 또는 다른 도구가 실행되기 시작하면 젠킨스는 주로 출력과 종료 상태를 수집합니다. 도구 자체의 오류를 읽으세요. Maven 종속성 해결 오류는 Java 컴파일 오류와 다르게 해결됩니다. npm 잠금 파일 불일치는 누락된 Node 바이너리와 다르게 해결됩니다.

종속성 실패의 경우 에이전트가 레지스트리에 연결할 수 있는지 확인하세요.

curl -I https://repo.maven.apache.org/maven2/
curl -I https://registry.npmjs.org/

회사 네트워크에서 수정 사항은 프록시 구성 또는 내부 아티팩트 미러에 대한 액세스일 수 있습니다. 하나의 종속성만 실패하는 경우 삭제, 이동, 정책에 의해 차단되었거나 잘못된 체크섬으로 게시되었는지 확인하세요.

컴파일 실패의 경우 로컬 및 CI 도구 버전을 비교하세요. 로컬에서 Java 21로 빌드되는 프로젝트가 여전히 Java 17을 사용하는 에이전트에서 실패할 수 있습니다. Node 프로젝트는 package.jsonpackageManager를 통해 커밋된 정확한 패키지 관리자 버전에 의존할 수 있습니다. 파이프라인 초기에 버전을 출력하여 향후 실패를 더 쉽게 읽을 수 있도록 하세요.

작업 공간 문제는 눈에 띄지 않습니다.

오래된 파일은 이상한 실패를 유발합니다. 이전 브랜치의 생성된 파일이 작업 공간에 남아 이후 빌드에 영향을 줄 수 있습니다. 테스트 보고서는 이전 실행에서 가져올 수 있습니다. Docker Compose 프로젝트는 컨테이너를 남길 수 있습니다. 임시 파일이 디스크를 채울 수 있습니다.

작업 공간을 지운 후 실패가 사라지면 거기서 멈추지 마세요. 작업이 항상 깨끗하게 시작해야 하는지 아니면 특정 정리 단계가 누락되었는지 결정하세요. 모노레포 또는 대규모 프로젝트의 경우 매번 전체 삭제는 너무 비쌀 수 있지만 대상 정리는 여전히 필요합니다.

유용한 확인:

pwd
ls -la
df -h .
find . -maxdepth 2 -type f -name '*.log' -size +50M

여러 작업이 사용자 지정 작업 공간을 공유하는 경우 중단하고 재고하세요. 공유 작업 공간은 작업 간 오염의 일반적인 원인입니다. 공유가 의도적이고 보호되지 않는 한 별도의 작업 공간을 사용하세요.

리소스 실패는 젠킨스 외부에 증거가 있습니다.

명확한 애플리케이션 오류 없이 빌드가 중단되면 에이전트 호스트를 검사하세요. 젠킨스는 프로세스가 종료되었거나 채널이 닫혔다는 것만 표시할 수 있습니다. 운영 체제가 실제 원인을 보여줄 수 있습니다.

메모리 부족 종료 확인:

dmesg -T | grep -i -E 'out of memory|killed process'

디스크 및 inode 소진 확인:

df -h
df -i

에이전트 프로세스가 다시 시작되었는지 확인:

journalctl -u jenkins-agent --since '1 hour ago'

컨테이너화된 에이전트는 또 다른 계층을 추가합니다. Kubernetes는 메모리, 임시 스토리지 또는 노드 압력으로 인해 파드를 축출할 수 있습니다. 이 경우 kubectl describe pod가 일반적으로 젠킨스 콘솔보다 더 많은 정보를 제공합니다.

다음 번에 실패를 더 쉽게 진단할 수 있도록 만드세요.

좋은 파이프라인은 큰 소리로 실패하고 원인에 가깝게 실패합니다. 긴 빌드 전에 버전 확인을 추가하세요. 통합 테스트 전에 상태 확인을 추가하세요. 외부 서비스 주변에 명시적 시간 제한을 사용하세요. 사람들이 실제로 필요한 로그를 보관하지만 비밀이나 거대한 관련 없는 파일을 덤프하지 마세요.

시작 부분 근처의 작은 진단 단계는 시간을 절약할 수 있습니다.

stage('빌드 컨텍스트') {
    steps {
        sh '''
          hostname
          whoami
          pwd
          git rev-parse HEAD
          java -version || true
          node --version || true
          df -h .
        '''
    }
}

짧게 유지하세요. 목표는 모든 빌드를 시스템 감사로 바꾸는 것이 아닙니다. 목표는 다음 실패를 추측 없이 이해할 수 있을 만큼 충분한 단서를 남기는 것입니다.