티스토리 뷰

CICD

[CI/CD] Jenkins cleanws 문제 해결 과정

SungminKim 2024. 2. 20. 15:53

 

 

 

 

개요

본 글에서는 Jenkins Pipeline과 Docker를 이용하여 빌드하는 과정에서 다루어진 디렉터리 또는 파일이 삭제되지 않고 남는 문제에 대한 원인 추적 및 해결 사항을 공유해드리려 합니다. 

 

 

문제 사항

현재 소속된 사내에서는 여러 개의 VM에 Jenkins 실행시켜 다중으로 운영 중이며 Jenkins의 Pipeline을 사용하여 워크플로우를 정의하고 정의된 파이프라인 워크플로우를 실행하여 빌드 및 배포를 수행시키고 있습니다.

문제는 정의된 파이프라인 워크플로우의 모든 작업이 수행된 이후 작업 과정에서 발생한 결과물이 제거되도록 구현되어 있었지만 특정 결과물만이 삭제되지 않고 남아 디스크를 차지하고 있다는 점이였습니다.

Workflow(워크플로우)
빌드, 테스트, 배포 등의 과정을 일련의 단계로 자동으로 실행하는 일련의 작업을 의미합니다.

Workspace(워크스페이스)
Jenkins에서 워크플로우가 실행되는 동안 발생하는 코드와 결과물을 저장하는 디렉토리를 의미합니다.

워크스페이스 내부에 '~ws-cleaup~'과 같은 명칭의 디렉터리로 남아있는 상태

 

적지 않은 크기로 garbage file이 남아 있는 상태

 

 

 

원인 분석

원인을 추적 해본 결과, 빌드 과정에서 도커를 사용한 파이프라인 워크플로우의 결과물들만이 남아 있는 것을 확인했으며, 해당 결과물의 공통적인 사항으로는 root 권한으로 소유권으로 가진다는 것을 확인 할 수 있었습니다.

 

워크스페이스 내부 garbage file의 소유권한이 root

 

위와 같은 사실을 근거로 garbage file이 생성된 근원지를 찾기 위해 파이프라인 스크립트를 분석해본 결과, docker image를 빌드 하는 과정에서 생성 또는 복제된 결과물의 소유권한이 --privileged -u 옵션을 사용해  root(0)로 할당되는 것을 확인 할 수 있었습니다.

 

...
echo "----------- BUILD -----------"

dir("sources_build-5") {
	docker.withRegistry("https://registryUri", "harborcred") {
		docker.image("https://registryUri/java-node-gradle:0.1")
			  // --privileged -u 옵션으로 컨테이너 권한을 root로 지정한 상태
			  .inside("--network host --privileged -u 0") {
			sh """
				chmod a+x ./gradlew
                ./gradlew -DsendCredentialsOverHttp=true
                mkdir target
			"""
		}
	}
	...
}

 

최종적으로는 보안 정책상 일반 계정으로 실행되는 워크플로우로 인하여 위 파이프라인 스크립트을 통해 생성된 소유권한이 root인 결과물이 삭제되지 않았던 것이 문제의 원인인 것을 깨닫게 되었습니다.

 

 

 

해결 방법

garbage file이 생성되는 워크플로우에서 도커를 사용하는 방식은 Docker In Docker(도커 위에 도커컨테이너를 생성하는) 방식으로 도커 컨테이너에 대한 관리자 권한 설정이 필요하며 --privileged -u 옵션으로 특정 사용자를 컨테이너 관리자 권한으로 설정할 수 있습니다. 이러한 사항을 기반으로 수정된 스크립트는 아래와 같습니다.

echo "----------- BUILD -----------"

dir("sources_build-5") {

    // 현재 파이프라인 워크플로우 실행의 주체가 되는 OS 사용자의 uid와 gid를 변수로 할당
    def uid = sh(script: 'id -u', returnStdout: true).trim()
    def gid = sh(script: 'id -g', returnStdout: true).trim()
            
	docker.withRegistry("https://registryUri", "harborcred") {
		docker.image("https://registryUri/java-node-gradle:0.1")
			  // 할당된 변수를 컨테이너 관리자 권한으로 대체
			  .inside("--network host --privileged -u ${uid}:${gid}") {
			sh """
				chmod a+x ./gradlew
                ./gradlew -DsendCredentialsOverHttp=true
                mkdir target
			"""
		}
	}
    ...

워크플로우를 실행시키는 일반 계정의 uid, gid를 변수에 담에 컨테이너 관리자 권한으로 대체하는 방식으로 스크립트를 작성한 후 워크플로우를 실행시킨 결과, garbare file이 남지 않고 정상적으로 삭제되는 것을 확인 할 수 있었습니다.

 

 

 

마무리

이번 문제를 분석하는 과정에서 Jenknins가 제공하는 Workspace Cleanup 플러그인이 지연 삭제 방식으로 동작한다는 점을 알게 되었으며, 해당 사항으로 인하여 특정 플러그인이 정상적으로 역할을 수행하지 않았음에도 불구하고 로그가 남지 않을 수도 있다는 것을 깨닫게 되었습니다.

 

 

 

참고자료

'CICD' 카테고리의 다른 글

[CI/CD] Harbor 간단 사용법  (0) 2024.06.23
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday