소개
Jenkins 는 대부분의 컨트롤러 및 작업 구성을 JENKINS_HOME 하위의 파일로 저장합니다. 실무적인 백업 계획은 작업과 컨트롤러 설정을 정의하는 파일들을 포함해야 하며, 복원 계획은 복원된 파일을 Jenkins 가 정상적으로 로드할 수 있음을 입증해야 합니다.
이번 실습에서는 샘플 작업을 생성하고, 해당 작업의 config.xml을 백업한 뒤, 작업을 삭제하고, tar 아카이브에서 복원하여 Jenkins 를 리로드한 후 작업이 다시 정상적으로 작동하는지 확인합니다.
백업할 Jenkins 상태 생성
이 단계에서는 backup-restore-demo라는 이름의 Freestyle 작업을 생성합니다. 이를 통해 백업 및 복원할 실제 Jenkins 구성 파일을 확보하게 됩니다.
작업 구성을 작성합니다:
cat > /home/labex/project/backup-restore-demo-config.xml <<'XML'
<?xml version='1.1' encoding='UTF-8'?>
<project>
<actions/>
<description>Job used to practice Jenkins backup and restore.</description>
<keepDependencies>false</keepDependencies>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<canRoam>true</canRoam>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers/>
<concurrentBuild>false</concurrentBuild>
<builders>
<hudson.tasks.Shell>
<command>echo "Restored Jenkins job is running"</command>
<configuredLocalRules/>
</hudson.tasks.Shell>
</builders>
<publishers/>
<buildWrappers/>
</project>
XML
작업을 Jenkins 에 복사하고 리로드합니다:
docker exec -u root jenkins mkdir -p /var/jenkins_home/jobs/backup-restore-demo
docker cp /home/labex/project/backup-restore-demo-config.xml jenkins:/var/jenkins_home/jobs/backup-restore-demo/config.xml
docker exec -u root jenkins chown -R jenkins:jenkins /var/jenkins_home/jobs/backup-restore-demo
/home/labex/project/reload-jenkins.sh
Jenkins 가 작업을 정상적으로 로드했는지 확인합니다:
curl -fsS http://localhost:8080/job/backup-restore-demo/api/json | grep -o '"name":"backup-restore-demo"'
작업 구성 백업
이 단계에서는 Jenkins 컨테이너에서 작업 구성을 복사하여 아카이브합니다. 백업 시 jobs/backup-restore-demo/config.xml이라는 상대 경로를 유지하면 나중에 복원 경로를 명확하게 파악할 수 있습니다.
백업 작업 디렉토리를 생성하고 작업 구성을 복사합니다:
mkdir -p /home/labex/project/jenkins-backup-work/jobs/backup-restore-demo
docker cp jenkins:/var/jenkins_home/jobs/backup-restore-demo/config.xml /home/labex/project/jenkins-backup-work/jobs/backup-restore-demo/config.xml
압축된 tar 아카이브를 생성합니다:
cd /home/labex/project/jenkins-backup-work
tar -czf /home/labex/project/backup-restore-demo.tar.gz jobs/backup-restore-demo/config.xml
아카이브 내용을 확인합니다:
tar -tzf /home/labex/project/backup-restore-demo.tar.gz
출력 결과에 다음이 포함되어야 합니다:
jobs/backup-restore-demo/config.xml
데이터 손실 시뮬레이션을 위한 작업 삭제
이 단계에서는 Jenkins 에서 작업을 삭제합니다. 이는 실수로 인한 삭제 상황을 시뮬레이션하며, 복원 대상이 사라졌음을 확인하기 위함입니다.
작업 디렉토리를 제거하고 Jenkins 를 리로드합니다:
docker exec -u root jenkins rm -rf /var/jenkins_home/jobs/backup-restore-demo
/home/labex/project/reload-jenkins.sh
작업에 더 이상 접근할 수 없는지 확인합니다. 아래 명령어는 확인을 위해 404 응답을 성공으로 간주합니다:
if curl -fsS http://localhost:8080/job/backup-restore-demo/api/json >/dev/null 2>&1; then
echo "Job still exists"
exit 1
else
echo "Job is absent and ready to restore"
fi
백업에서 작업 복원
이 단계에서는 백업 아카이브를 추출하고, 복원된 작업 디렉토리를 Jenkins 에 다시 복사한 뒤 컨트롤러를 리로드합니다.
복원 디렉토리에 아카이브를 추출합니다:
rm -rf /home/labex/project/restore-work
mkdir -p /home/labex/project/restore-work
tar -xzf /home/labex/project/backup-restore-demo.tar.gz -C /home/labex/project/restore-work
복원된 작업 디렉토리를 Jenkins 에 복사하고 리로드합니다:
docker cp /home/labex/project/restore-work/jobs/backup-restore-demo jenkins:/var/jenkins_home/jobs/backup-restore-demo
docker exec -u root jenkins chown -R jenkins:jenkins /var/jenkins_home/jobs/backup-restore-demo
/home/labex/project/reload-jenkins.sh
Jenkins 가 복원된 작업을 정상적으로 로드했는지 확인합니다:
curl -fsS http://localhost:8080/job/backup-restore-demo/api/json | grep -o '"name":"backup-restore-demo"'
복원된 작업 실행
이 단계에서는 복원된 작업을 실행합니다. 복원은 Jenkins 가 복원된 구성을 로드하고 실행할 수 있을 때만 의미가 있습니다.
빌드를 트리거합니다. Jenkins 는 먼저 큐 항목을 반환하므로 응답 헤더를 저장하고 Location 헤더를 읽습니다:
CRUMB=$(curl -fsS -c /tmp/jenkins-backup-build.cookies 'http://localhost:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')
curl -fsS -D /tmp/backup-restore-build.headers -o /dev/null -b /tmp/jenkins-backup-build.cookies -H "$CRUMB" -X POST http://localhost:8080/job/backup-restore-demo/build
QUEUE_URL=$(awk 'tolower($1)=="location:" {print $2}' /tmp/backup-restore-build.headers | tr -d '\r')
echo "Jenkins queued the restored job at ${QUEUE_URL}"
큐에 담긴 항목이 실제 빌드가 될 때까지 기다립니다. Jenkins 는 최종 빌드 번호를 할당하기 전에 잠시 대기할 수 있습니다:
until BUILD_NUMBER=$(python3 - "$QUEUE_URL" <<'PY'
import json
import sys
import urllib.request
with urllib.request.urlopen(sys.argv[1] + 'api/json') as response:
data = json.load(response)
executable = data.get('executable')
if not executable:
raise SystemExit(1)
print(executable['number'])
PY
); do
echo "Waiting for Jenkins to assign a build number..."
sleep 3
done
echo "The restored job is running as build #${BUILD_NUMBER}"
빌드가 완료될 때까지 기다립니다:
until curl -fsS "http://localhost:8080/job/backup-restore-demo/${BUILD_NUMBER}/api/json" >/tmp/backup-restore-build.json 2>/dev/null && grep -q '"building":false' /tmp/backup-restore-build.json; do
echo "Waiting for restored job build #${BUILD_NUMBER}..."
sleep 3
done
콘솔 출력을 확인합니다:
curl -fsS "http://localhost:8080/job/backup-restore-demo/${BUILD_NUMBER}/consoleText" | grep -E 'Restored Jenkins job is running|Finished: SUCCESS'
데스크톱 인터페이스에서 Firefox 를 열고 터미널에 표시된 빌드 번호의 콘솔 URL(예: http://localhost:8080/job/backup-restore-demo/2/console) 을 방문합니다. 콘솔 페이지에서 복원된 작업이 성공적으로 실행되었음을 확인할 수 있습니다.

요약
백업할 가치가 있는 Jenkins 구성을 생성하고, 작업의 config.xml을 아카이브했으며, 작업을 삭제한 뒤 백업 아카이브에서 복원하고, Jenkins 를 리로드하여 성공적인 빌드를 통해 복원된 작업이 정상 작동함을 확인했습니다.