본문 바로가기
CI.CD/Jenkins

[Jenkins] Jenkins Workspace 완벽 청소 가이드 (디스크 풀 장애의 늪 탈출하기)

반응형

젠킨스를 도입하여 무중단 자동화 배포 파이프라인의 달콤함을 맛보고 있을 무렵, 보통 서비스 런칭 3개월에서 6개월 차 쯤에 모두가 똑같이 겪게 되는 거대한 재앙이 하나 찾아옵니다. 개발자가 코드를 푸시했는데 젠킨스가 아무런 응답을 하지 않고 뻗어버리는 현상입니다. 황급히 서버에 들어가 로그를 확인해 보면 어김없이 "No space left on device" (디스크 용량 100% 초과)라는 끔찍한 에러가 붉게 물들어 있습니다. 원인은 바로 젠킨스의 작업 공간인 Workspace(워크스페이스) 관리에 실패했기 때문입니다.

이번 [Jenkins 실무 완벽 가이드] 시리즈에서는 인프라 관리자의 수명을 갉아먹는 이 고질적인 문제를 원천 봉쇄하고, Workspace Cleanup 플러그인을 활용하여 항상 쾌적하고 깔끔한 서버 환경을 유지하는 실무 최적화 기법에 대하여 3,000자 분량으로 아주 치밀하게 딥다이브 해보겠습니다.

🚨 1. 디스크 풀(Disk Full) 현상의 정체: 무한히 증식하는 쓰레기 더미

젠킨스가 코드를 빌드할 때는 가상의 공간이 아니라 서버의 실제 물리적 하드디스크 공간을 갉아먹습니다. 기본적으로 /var/jenkins_home/workspace/ 경로 아래에 각 잡(Job)의 이름으로 폴더가 생기며, 젠킨스는 이 곳에 Github에서 소스 코드를 클론(Clone)받고, 필요한 의존성 패키지들(Java의 .m2, Node.js의 node_modules)을 기가바이트 단위로 다운로드받습니다. 그리고 컴파일을 거쳐 무거운 .jar 빌드 산출물이나 임시 이미지 파일들을 생성해 냅니다.

치명적 문제: 젠킨스는 파이프라인 빌드가 끝나더라도 기본적으로 이 Workspace 폴더를 스스로 지우지 않습니다. 만약 프론트엔드 프로젝트 하나의 Workspace 용량이 1GB인데 하루에 개발자들이 10번씩 빌드를 돌린다면? 일주일이면 70GB, 한 달이면 수백 GB의 쓰레기 데이터가 고스란히 쌓이게 됩니다. 결국 서버 디스크 할당량을 100% 꽉 채우게 되고, OS는 새로운 로그 파일조차 쓸 공간이 없어져 젠킨스 데몬 자체가 크래시(Crash)나며 마비되어 버립니다. 이때 복구하려면 서버 터미널에 접속해 강제로 폴더들을 날려주어야 하는 엄청난 쌩고생을 동반합니다.


🧹 2. 구원투수: Workspace Cleanup 플러그인 도입

이러한 참사를 막기 위한 업계 표준 해결책이 바로 Workspace Cleanup Plugin을 사용하는 것입니다. 이 플러그인은 파이프라인의 생명주기가 끝날 때, 해당 빌드가 어질러 놓은 작업 공간을 말끔히 포맷(삭제)해주는 역할을 합니다.

플러그인 설치 방법:
[Jenkins 관리] -> [플러그인 관리] 메뉴로 들어가 Workspace Cleanup을 검색하여 설치합니다. (초기 설정 시 'Install suggested plugins'를 선택했다면 이미 설치되어 있을 확률이 높습니다.)

전략적 위치 선정 (Post 블록 100% 활용):
이 청소 코드를 steps 내부에 적으면 앞서 14단계 포스팅에서 설명했듯 빌드가 중간에 에러가 났을 때 실행되지 않고 넘어갈 수 있습니다. 따라서 반드시 파이프라인 맨 하단의 post { always { ... } } 블록 안에 선언해야 합니다. 그래야 성공하든 실패하든, 젠킨스는 퇴근하기 전에 무조건 자기 자리를 청소하고 나가게 됩니다.


💻 3. 실무 적용 코드 파헤치기: `cleanWs()`

플러그인이 설치되었다면 cleanWs() 라는 내장 함수를 호출할 수 있습니다. 단순 호출뿐만 아니라, 다양한 옵션을 파라미터로 넘겨 세밀한 청소 정책을 설정할 수 있습니다.

pipeline {
    agent any
    stages {
        stage('Build Project') {
            steps {
                echo '수 기가바이트의 소스코드와 라이브러리를 받아와 빌드합니다...'
                sh 'npm install && npm run build'
            }
        }
    }
    
    // 파이프라인의 제일 끝단, 어떤 결과에도 무조건 실행되는 영역
    post {
        always {
            echo '🧹 빌드 작업 종료. Workspace를 깨끗하게 청소합니다.'
            
            // 단순하게 cleanWs() 라고만 써도 작동하지만, 
            // 아래처럼 명시적 옵션을 주는 것이 실무 Best Practice 입니다.
            cleanWs(
                cleanWhenFailure: true,    // 실패했을 때도 얄짤없이 삭제
                cleanWhenSuccess: true,    // 성공했을 때도 삭제
                cleanWhenUnstable: true,   // 불안정 상태일 때도 삭제
                cleanWhenAborted: true,    // 취소되었을 때도 삭제
                deleteDirs: true,          // 숨김 폴더나 빈 디렉토리 구조까지 싹 날림
                disableDeferredWipeout: true // 백그라운드 삭제 대신 즉시 동기식으로 삭제
            )
        }
    }
}

이 코드 한 뭉텅이만 여러분의 모든 파이프라인 하단에 붙여넣어 준다면, 젠킨스 서버의 디스크 사용량은 항상 쾌적한 10~20% 대를 유지하게 될 것이며 인프라 장애로 밤잠을 설칠 일은 영원히 사라집니다.


⚠️ 4. 중급 트러블슈팅: 지우지 말아야 할 '캐시(Cache)'의 딜레마

여기서 아주 예리한 개발자라면 딜레마에 봉착하게 됩니다. "잠깐, 빌드 끝날 때마다 Workspace를 싹 지워버리면, 다음번 빌드 때 수십 MB~GB에 달하는 npm 패키지나 maven 라이브러리를 처음부터 다시 다운로드받아야 하잖아요? 그럼 빌드 속도가 너무 느려지지 않나요?"

정확한 지적입니다. 청소를 너무 빡세게 하면 네트워크 I/O 병목이 발생하여 파이프라인 속도가 급격히 느려집니다. 그래서 진정한 상위 1% 실무자들은 캐시(Cache) 폴더 마운트 분리 기법을 사용합니다.

해결책 (Docker Agent 결합): 이전 9단계 포스팅에서 다루었던 Docker Agent 설정과 결합하는 것입니다. 도커 컨테이너를 띄울 때 패키지가 저장되는 디렉토리(예: /root/.npm 또는 /root/.m2)를 컨테이너 외부 호스트 서버의 디렉토리와 볼륨 마운트(Volume Mount)를 걸어버립니다. 이렇게 세팅하면, 파이프라인 마지막에 cleanWs()가 실행되어 소스코드 찌꺼기(Workspace)는 날려버리지만, 핵심 라이브러리 파일들은 안전한 외부 공간(호스트 서버 볼륨)에 캐시로 고스란히 남아 다음 빌드 때 즉시 재활용됩니다. 속도와 청결함, 두 마리 토끼를 모두 완벽히 잡아내는 인프라 아키텍처의 승리입니다.


🎯 5. 마무리 및 다음 단계

지금까지 수많은 데브옵스 주니어들의 멘탈을 붕괴시키는 디스크 풀(Disk Full) 현상의 근본 원인을 파헤치고, Workspace Cleanup 플러그인을 활용해 서버를 항상 쾌적하게 유지하는 노하우와 캐시 딜레마 극복 방법에 대해 3,000자에 걸쳐 아주 치밀하게 알아보았습니다. 이 작은 습관 하나가 인프라의 안정성을 수백 배 끌어올린다는 사실을 절대 잊지 마십시오.

파이프라인이 안정적으로 돌아가기 시작하면, 팀장님이나 경영진은 슬슬 새로운 요구사항을 던지기 시작합니다. "빌드 실패 알림이 매일 이메일로 오니까 보지도 않고 쌓이기만 하네요. 요즘 다들 쓰는 사내 메신저인 Slack(슬랙)으로 실패 로그가 팝업되게 해줄 수 없나요?" 인프라 담당자의 가치를 증명할 시간이 왔습니다. 이어지는 16단계 포스팅에서는 모두가 열광하는 'Slack과 젠킨스의 연동을 통한 실시간 빌드 알림(Notification) 봇 구축의 모든 것'에 대해 아주 꼼꼼하게 셋업 가이드를 제공하겠습니다. 기대해 주십시오!

반응형