본문 바로가기

개발기술/빌드, 배포, 운영

Jenkins CI/CD 자동화

https://youtubetranscript.com/?v=6YZvp2GwT0A&t=150

 

YouTube Transcript - read YouTube videos

 

youtubetranscript.com

 

Jenkins는 오픈소스 기반의 자동화 서버로, CI/CD(Continuous Integration/Continuous Delivery) 파이프라인을 구축하고 관리하는 데 널리 사용됩니다. Jenkins를 활용하면 소프트웨어 개발, 빌드, 테스트, 배포 과정을 자동화하여 개발 속도와 품질을 크게 향상시킬 수 있습니다.

Jenkins CI/CD란?

  1. CI(Continuous Integration):
    • 코드 변경 사항을 지속적으로 통합하고 빌드 및 테스트를 자동화하는 프로세스입니다.
    • Jenkins는 개발자가 변경한 코드를 지속적으로 통합하여 문제를 빠르게 발견하고 해결할 수 있도록 돕습니다.
    • 예: 개발자가 코드를 푸시할 때 Jenkins가 코드를 빌드하고 유닛 테스트를 실행.
  2. CD(Continuous Delivery/Deployment):
    • CI 이후 코드를 배포 가능한 상태로 만드는 자동화 과정(CD).
    • Continuous Delivery는 수동 배포를 위한 준비를 의미하며, Continuous Deployment는 완전한 자동 배포를 포함합니다.
    • Jenkins는 자동화된 테스트를 통과한 코드를 다양한 환경(스테이징, 프로덕션)에 배포할 수 있습니다.

Jenkins CI/CD의 주요 구성 요소

  1. Pipeline: Jenkins Pipeline은 CI/CD 작업을 코드(Script)로 정의한 것입니다.Declarative PipelineScripted Pipeline 두 가지 스타일을 제공합니다. 예: Jenkinsfile을 사용해 빌드, 테스트, 배포 단계를 코드로 작성.
  2. Job/Build: Jenkins에서 특정 작업(빌드, 테스트, 배포)을 수행하는 단위입니다. 프리 스타일 프로젝트 또는 멀티브랜치 파이프라인 형태로 구성.
  3. Plugins: Jenkins는 플러그인 기반으로 작동하며, Git, Docker, Maven, Kubernetes 등 다양한 플러그인으로 기능을 확장할 수 있습니다.
  4. Triggers: 코드 변경 사항(예: Git 푸시, Pull Request)을 감지하거나, 예약된 시간에 작업을 자동 실행할 수 있습니다.
  5. Nodes/Agents: Jenkins Master(Node)는 파이프라인 실행을 관리하며, Agent(Node)는 작업을 실행합니다. 분산 빌드를 지원하여 작업 부하를 여러 서버로 분산.

 

Jenkins 실행

1. 도커로 컨테이너 실행

docker run -d --name jenkins -p 8080:8080 -p 50000:50000 jenkins/jenkins:lts

 

  • 8080 : Jenkins 웹 UI 접속 (관리자 페이지, 브라우저에서 접근)
  • 50000 : Jenkins Agent(슬레이브)와의 통신 포트

 

2. 초기관리자 비밀번호 확인

컨테이너 내에 접속하여 초기비밀번호를 확인한다.

cat /var/jenkins_home/secrets/initialAdminPassword

3. 플러그인 설정(추천플러그인 설치) 

4. Job설정

 

Jenkins UI

젠킨스는 톰 캣 웹 애플리케이션으로 동작하며, 이를 통해 여러 사용자가 동시에 접근하고 쉽게 관리할 수 있는 중앙 서버의 역할을 수행할 수 있습니다. 웹 기반 인터페이스는 사용자가 별도의 클라이언트 소프트웨어를 설치하거나 설정할 필요 없이 브라우저만으로 접근할 수 있게 합니다.  즉, 젠킨스를 실행시키고 브라우저를 활용해서 해당 IP의 포트로 GUI에 접속하여 Task(Job)를 설정하는 방식

 

1. 대시보드 (Dashboard)

Jenkins UI에 로그인하면 처음 보이는 화면으로, 주요 기능들을 관리할 수 있어.

주요 기능

  • 현재 실행 중이거나 완료된 빌드(Job) 목록 확인
  • 새로운 Job(프로젝트) 생성 및 관리
  • 빌드 상태(성공/실패) 시각적으로 표시
  • 최근 실행된 빌드 및 큐 대기 중인 작업 확인

대시보드에서 가장 많이 하는 작업 

  • 새로운 프로젝트(Job) 생성
  • 기존 프로젝트 설정 변경
  • 빌드 기록 및 로그 확인

 

2. Job(프로젝트) 관리

Jenkins에서는 CI/CD 파이프라인을 "Job(작업)" 단위로 관리해.

주요 기능

  • Freestyle 프로젝트: 간단한 빌드 및 스크립트 실행용
  • Pipeline 프로젝트: 코드 기반의 CI/CD 파이프라인
  • Multibranch Pipeline: 여러 브랜치별로 다른 빌드 파이프라인 관리
  • Folder: 여러 Job을 그룹화하여 관리 가능

Jenkins agent관리

Jenkins에서 특정 에이전트 노드에서 빌드를 실행하려면, 마스터(Jenkins 서버)와 에이전트(노드) 양쪽에서 설정이 필요합니다. 

  • CI/CD에서 '에이전트'와 '배포 환경'은 다른 개념입니다
  • 에이전트: 작업을 실행하는 환경 (예: 빌드, 테스트)
  • 배포 환경: 애플리케이션이 실행되는 환경 (예: 개발, 스테이징, 프로덕션)

1) Jenkins Master에서 노드 추가

  1. Jenkins 웹 UI 접속 (http://<Jenkins 서버 IP>:8080)
  2. "Manage Jenkins" → "Manage Nodes and Clouds" 클릭
  3. "New Node" 클릭하여 새 노드 추가
    • Node 이름: linux-server (예제)
    • "Permanent Agent" 선택 후 "OK"
    • 설정 입력
      • Remote root directory: /home/jenkins-agent (에이전트에서 사용할 작업 디렉토리)
      • Labels: linux-server (이 값을 agent { label 'linux-server' }에서 사용)
      • Launch method: SSH or Java Web Start (JNLP)
  4. "Save"를 클릭하여 노드 추가 완료.

2) 에이전트 서버에서 Jenkins 에이전트 실행

 SSH를 이용한 에이전트 연결 (추천)

  1. 에이전트 서버(Linux)에 JDK 8 이상 설치
  2. bash
    복사편집
    sudo apt update sudo apt install openjdk-11-jdk -y java -version # JDK 설치 확인
  3. Jenkins 서버에서 SSH Key를 등록 (Jenkins → "Manage Nodes"에서 SSH 설정)
    • 에이전트 서버에서 Jenkins 서버의 SSH 연결을 허용해야 함.
  4. 에이전트 서버에서 jenkins-agent 디렉토리 생성
  5. bash
    복사편집
    mkdir -p /home/jenkins-agent
  6. Jenkins가 에이전트에 연결되면 자동으로 실행됨.

 

Jenkins Job관리

Freestyle 프로젝트

  •   Freestyle 프로젝트는 GUI를 사용하여 간단한 빌드 및 스크립트 실행을 설정하는 방식.초보자도 쉽게 사용할 수 있으며, Jenkins에서 가장 기본적인 프로젝트 유형.

Freestyle 프로젝트 생성 예시

  • Jenkins 대시보드 → New Item 클릭
  • Freestyle project 선택 → 프로젝트 이름 입력 → OK 클릭
  • Git 저장소 연결 : Source Code Management → Git 선택 → 저장소 URL 입력
  • Build 단계 추가 : Build 섹션에서 Execute Shell 추가
  • 저장 후 Build Now 클릭

Pipeline 프로젝트

  •  Pipeline 프로젝트는 코드 기반으로 CI/CD 워크플로우를 자동화할 수 있는 강력한 방식. Jenkinsfile을 사용하여 CI/CD 파이프라인을 코드로 관리할 수 있어.
  •  Git 저장소와 연동 가능 (Jenkinsfile을 직접 저장소에 포함 가능)
  • Groovy 기반 스크립트 사용

 Pipeline 프로젝트 생성 예제:

  • 1.Jenkins 대시보드 → New Item 클릭
  • 2. Pipeline 선택 → 프로젝트 이름 입력 → OK 클릭
  • 3. General 설정
    • (선택) GitHub project 설정: GitHub 저장소 URL 입력 : 단순히 Jenkins Job에서 GitHub 저장소 URL추가.
    • (필수) Do not allow concurrent builds (동시 빌드 방지) 체크 여부 결정
    • (선택) 오래된 빌드 자동 삭제 설정 (빌드 로그가 계속 쌓이는 걸 방지
  •  4.  Build Trigger (빌드 트리거) 설정
    • , Jenkins는 Git 저장소에 설정된 Jenkinsfile을 로드해서 자동으로 빌드를 트리거함.
    • GitHub Webhook (가장 많이 사용) : GitHub에서 코드가 push/pull request 될 때 자동 빌드
    • Poll SCM (주기적으로 Git 저장소 변경 확인) : H/5 * * * * → 5분마다 변경 확인
    • Build Periodically (정해진 시간에 빌드) :  특정 시간에 자동 빌드
    • 다른 프로젝트 빌드 후 실행 : 특정 Job이 빌드된 후 자동 실행
    • Remote Trigger (Jenkins API를 사용한 원격 빌드) : Jenkins REST API를 호출하여 외부에서 빌드 실행
  •  5.  Pipeline 설정 (Jenkinsfile 연결)
    • Pipeline 정의 방식 선택
      • Pipeline script → 직접 입력하는 방식
      • Pipeline script from SCM → Git 저장소에서 Jenkinsfile을 불러오는 방식 (추천)
        • GitHub Webhook을 연동하려면 Pipeline script from SCM을 선택해야 함. 아니면 수동셋팅이 필요
          1. SCM 선택: Git 선택
          2. Repository URL: GitHub 또는 GitLab의 저장소 URL 입력
          3. Credentials 추가: 필요하면 Git 계정 추가
          4. Branches to build: main 또는 develop 입력 (현재 사용하는 브랜치)
          5. Script Path: Jenkinsfile 입력 (프로젝트 루트에 Jenkinsfile이 있어야 함)
  •  5.  Jenkinsfile 작성
    • pipeline {} → agent {} → stages {} → steps {}의 구조로 작성.
    • agent any를 사용하면 현재 컨테이너에서 실행, 특정 노드에서 실행하려면 agent { label '노드이름' } 사용.
    • jenkins CI/CD 파이프라인은 일반적으로 체크아웃 → 테스트 → 빌드 → 도커 이미지 생성 → 도커 이미지 푸시 → 배포
    • 빌드, 테스트, 배포 단계를 stage {}로 나누고 steps {}에서 명령어 실행.
    • 환경 변수, 조건문, 후처리(post) 기능도 지원.

 

pipeline {
    agent any

    environment {
        DOCKER_IMAGE = "your-dockerhub-username/your-app"  // Docker Hub 또는 개인 레지스트리에 올릴 이미지 이름
        DOCKER_TAG = "latest"  // Docker 태그 (보통 latest 또는 특정 버전)
        REMOTE_SERVER = "your-server-ip"  // 원격 서버의 IP 또는 도메인
        REMOTE_USER = "your-ssh-user"  // 원격 서버에서 실행할 사용자 계정
        DEPLOY_DIR = "/home/${REMOTE_USER}/deploy"  // 원격 서버에서 앱이 배포될 디렉토리
        CONTAINER_NAME = "your-app-container"  // 실행할 컨테이너 이름
    }

    stages {
        stage('Checkout') { // 1️⃣ Git 저장소에서 코드 가져오기
            steps {
                echo "Checking out source code from Git..."
                git branch: 'main', url: 'https://github.com/your-repo/your-project.git'
            }
        }

        stage('Build & Test') { // 2️⃣ 코드 빌드 및 테스트 실행
            steps {
                echo "Building project and running tests..."
                sh './gradlew clean build test'  // Gradle 프로젝트의 경우
                // sh 'mvn clean install'  // Maven 프로젝트의 경우 (필요시 변경)
            }
        }

        stage('Build Docker Image') { // 3️⃣ Docker 이미지 빌드
            steps {
                echo "Building Docker image..."
                sh "docker build -t ${DOCKER_IMAGE}:${DOCKER_TAG} ."
            }
        }

        stage('Push Docker Image') { // 4️⃣ Docker Hub 또는 개인 레지스트리에 이미지 푸시
            steps {
                echo "Pushing Docker image to registry..."
                sh "echo ${DOCKER_PASSWORD} | docker login -u ${DOCKER_USERNAME} --password-stdin"  // Docker 로그인
                sh "docker push ${DOCKER_IMAGE}:${DOCKER_TAG}"  // 이미지 푸시
            }
        }

        stage('Deploy on Remote Server') { // 5️⃣ 원격 서버에서 컨테이너 실행
            steps {
                echo "Deploying application on remote server..."

                // SSH를 사용하여 원격 서버에서 실행
                sh """
                ssh ${REMOTE_USER}@${REMOTE_SERVER} <<EOF
                echo "Pulling latest Docker image..."
                docker pull ${DOCKER_IMAGE}:${DOCKER_TAG}

                echo "Stopping existing container (if running)..."
                docker stop ${CONTAINER_NAME} || true
                docker rm ${CONTAINER_NAME} || true

                echo "Running new container..."
                docker run -d --name ${CONTAINER_NAME} -p 8080:8080 ${DOCKER_IMAGE}:${DOCKER_TAG}

                echo "Deployment completed successfully!"
                EOF
                """
            }
        }
    }

    post {
        success {
            echo "Pipeline completed successfully!"
        }
        failure {
            echo "Pipeline failed! Check the logs for details."
        }
    }
}

1. Checkout

  • Git 저장소에서 최신 코드 가져오기

2. Build & Test

  • gradlew clean build test 또는 mvn clean install 실행 (빌드 & 테스트)

3. Build Docker Image

  • docker build -t <이미지명>:<태그> 실행하여 Docker 이미지 빌드

4. Push Docker Image

  • Docker Hub 또는 개인 레지스트리에 로그인 후 docker push 실행

5. Deploy on Remote Server

  • 원격 서버에서 기존 컨테이너 중지 및 삭제
  • 새로운 컨테이너 실행 (docker run -d --name <컨테이너명> -p 8080:8080 <이미지>)

 

1) pipeline {} 블록

  • Jenkins Pipeline의 시작을 의미.
  • pipeline {} 안에 agent, stages, steps 등이 들어감.
 

 2) agent (어디에서 실행할지 지정)

  • Pipeline을 실행할 노드(서버)를 지정.
  • 지금은 agent any를 사용 → 현재 Jenkins 컨테이너에서 실행.
 

3) stages {} (단계별 실행)

  • Pipeline은 여러 개의 스테이지(stage)로 구성됨.
  • stages {} 블록 안에 stage('이름') {}을 넣어서 빌드 과정을 나눌 수 있음.
    • 각 stage {} 안에서 steps {}을 사용하여 실행할 명령어를 정의.'
    • 작업 간 의존성이나 병렬 처리 등에 필요하지 않다면 굳이 사용하는 것이 필수는 아닙니다.

4) steps {} (실행할 명령어)

  • 각 stage {} 안에서 실행할 명령어를 정의.
  • sh '...' → 리눅스/유닉스 명령어 실행.

 

5) Steps 명령어들

    • checkout scm: Git 리포지토리에서 소스 코드를 가져옵니다.  
      • scm은 Jenkins에서 자동으로 제공하는 Git 등의 소스 관리 시스템을 참조합니다.
    • sh : 쉘 명령어를 실행합니다.
    • bat : Windows 환경에서 배치 명령어를 실행합니다.
    • echo : 파이프라인에서 메시지를 출력합니다.
    • docker :  Docker 관련 작업을 할 수 있는 docker 명령어를 제공합니다
    • parallel : 병렬로 여러 작업을 동시에 실행합니다.
    • retry: 지정한 횟수만큼 실패를 반복하며 재시도합니다.

 

고급 기능

 1) 환경 변수 사용 (environment {})

  • 빌드 중에 변수를 정의하고 사용할 수 있음.

 2) 조건문 (when {})

  • 특정 조건에서만 실행되도록 할 수 있음.

3) 실패 시 동작 설정 (post {})

  • 빌드 성공/실패에 따라 후처리 수행 가능.
 

'개발기술 > 빌드, 배포, 운영' 카테고리의 다른 글

쉘 커맨드 , 쉘 스크립트  (0) 2025.03.25
원격제어  (0) 2025.03.13
Gradle 빌드 사용법  (0) 2025.01.02
빌드와 Gradle 개념  (0) 2024.11.12
빌드 파일 서버 배포  (0) 2024.11.12