개발이군고구마

Jenkins 구조와 원리 정리 본문

Cloud Deploy

Jenkins 구조와 원리 정리

김구황 2026. 7. 1. 23:40
728x90

1. Jenkins가 하는 일

한 줄로 요약하면: "특정 조건(버튼 클릭, 코드 push 등)이 되면, 미리 정해둔 작업(빌드/테스트/배포)을 순서대로 실행해주는 자동화 서버".

  • Controller (Jenkins 서버 본체): UI 제공, Job 설정 저장, 실행 스케줄링을 담당하는 Java 프로세스
  • Job (=Project): "무엇을 어떻게 실행할지"에 대한 정의 단위. 화면에서 하나씩 만드는 그 대상
  • Build: Job을 한 번 실행한 결과물. Job이 "레시피"라면 Build는 "그 레시피로 만든 요리 한 접시" (빌드로그)

 

 

2. Jenkins 서버 구조 — JENKINS_HOME

Jenkins(war 파일 or 패키지)를 설치하고 실행하면, Java 프로세스 하나가 뜨면서 기본적으로 JENKINS_HOME 디렉토리(보통 /var/lib/jenkins 또는 지정 경로)를 생성/사용.  Jenkins의 모든 상태(Job 설정, 빌드 이력, 플러그인)가 여기 저장됨.

경로 내용 생성 시점
jobs/<job명>/config.xml Job 설정 원본 Job 화면에서 Save 누를 때
jobs/<job명>/builds/<번호>/ 빌드 로그, 결과 빌드 실행 완료 후
workspace/<job명>/ 실제 소스코드 (Git clone 결과) 빌드 실행할 때마다 갱신
plugins/ 설치된 플러그인 플러그인 설치 시

 jobs/ 밑에 있는 것과 workspace/ 밑에 있는 것은 성격이 다름.

  • jobs/config.xml → 설정 (Git URL, credential, 파라미터 등). Jenkins가 원본을 직접 소유
  • workspace/ → 결과물 (Git 리포지토리를 그대로 받아온 사본). 매 빌드마다 새로 갱신되므로 "원본"이 아님

참고 : https://sweetjhpotato.tistory.com/556 빌드실행 완료 후에 빌드 로그와 서버 실행 로그는 다름 

 

3. Job 실행 흐름 — 저장 시점과 실행 시점은 다르다

  1. Job 생성 (1회성): 웹 화면에서 설정 입력 → Save 클릭 → config.xml 즉시 저장. 아직 빌드는 한 번도 안 돌아간 상태
  2. Build 버튼 클릭 (매번 반복): config.xml을 읽어서 이 Job이 뭘 해야 하는지 파악
  3. Git clone/pull: 설정에 지정된 리포지토리를 workspace/로 받아옴
  4. Jenkinsfile 파싱 & 실행: workspace 안의 Jenkinsfile을 읽어서 그 안의 stage들을 순서대로 실행
  5. 로그 기록: 실행 결과와 콘솔 출력을 builds/<번호>/에 저장

①은 한 번, ②~⑤는 빌드할 때마다 처음부터 반복되는 구조. 매 빌드가 "새로 클론 → 새로 실행"에 가까움.

 

4. Pipeline 정의 방식 — 화면에 스크립트가 보이는 것과 안 보이는 것의 차이

  • Job 설정 화면에 파라미터 + node, stage 코드가 그대로 입력되어 있는 경우
  • Job 설정 화면엔 Git URL, credential, 브랜치, 실행 파일 경로만 있고 실제 코드는 안 보이는 경우

방식 1. Pipeline script (Directly)

  • 스크립트 원문을 Job 설정 화면에 직접 작성
  • config.xml 안에 스크립트 텍스트가 그대로 저장됨
  • Git 리포지토리와 무관, 원본 소유자는 Jenkins 자신
  • 화면에서 스크립트를 고치면 = 코드를 고치는 것과 동일함

방식 2. Pipeline script from SCM

  • Job 설정 화면엔 "어디서 가져올지"에 대한 정보(Git URL, credential, branch, script path)만 지정
  • 실제 stage 로직은 리포지토리 안의 Jenkinsfile에 있음
  • 빌드할 때마다 그 리포지토리를 clone해서 Jenkinsfile을 읽어 실행
  • 원본 소유자는 Git 리포지토리. Jenkins는 실행기 역할만 함
  • 화면을 고쳐도 stage 로직에는 영향 없음 (애초에 화면에 로직 자체가 없음). 반대로 리포지토리의 Jenkinsfile을 고치면 다음 빌드부터 바로 반영됨

예외 하나: Jenkinsfile에 parameters { ... }를 정의해두면, 빌드 1회 후 Job 설정 화면에 "Build with Parameters" 입력 폼이 자동으로 생김. 코드 → 화면으로 반영되는 유일한 케이스. 다만 화면에서 그 파라미터 기본값을 바꿔도 다음 빌드 때 Jenkinsfile 쪽 정의로 다시 덮어써짐.

 

5. Jenkinsfile이란

Pipeline 정의를 담는 텍스트 파일. Groovy 문법 기반 DSL로 작성.

// Scripted Pipeline — 자유도 높음, 코드처럼 작성
node {
    stage('Build') {
        sh 'mvn clean package'
    }
    stage('Deploy') {
        sh './deploy.sh'
    }
}
// Declarative Pipeline — 구조 정형화, 최근 표준
pipeline {
    agent any
    stages {
        stage('Build') {
            steps { sh 'mvn clean package' }
        }
        stage('Deploy') {
            steps { sh './deploy.sh' }
        }
    }
}

파일명은 관례일 뿐 강제 아님. Job 설정에서 Script Path를 다르게 지정하면 다른 이름도 가능. 보통 리포지토리 루트에 Jenkinsfile이라는 이름으로 둠.

 

6. 실습 순서 — Job 하나 만들어서 실행까지

  1. Jenkins 접속 → 새로운 Item → Freestyle project 또는 Pipeline 선택
  2. Pipeline 선택 시 "Definition" 항목에서 방식 결정
    • Pipeline script → 화면에 직접 Groovy 코드 작성
    • Pipeline script from SCM → Git URL, credential, branch, Script Path 입력
  3. Save
  4. "지금 빌드" 클릭
  5. 콘솔 출력(Console Output)에서 실행 로그 확인. 어느 stage에서 뭘 했는지 순서대로 나옴

 

7. 도커 위에서 Jenkins를 띄우면

Controller를 Docker 컨테이너로 운영하면 얻는 것.

  • 환경을 Dockerfile로 코드화 → 서버 교체/장애 복구 시 재현 쉬움
  • 호스트 OS와 격리 → Java 버전, 의존성 충돌 없음
  • 이미지 태그 변경만으로 업그레이드/롤백
  • JENKINS_HOME을 volume으로 분리하면 컨테이너를 갈아끼워도 데이터 보존

주의할 점.

  • Volume 마운트 안 하면 컨테이너 삭제 시 Job 설정/빌드 이력 전부 소실
  • 컨테이너 안에서 Docker 빌드까지 하려면(docker.sock 마운트) 호스트 Docker 데몬 제어권을 넘기는 셈이라 보안 검토 필요
  • 리소스 제한 안 걸면 빌드 폭주 시 호스트 전체에 영향