Jenkins를 활용한 CI/CD 파이프라인 구성 -week13

seulg1004·2025년 3월 30일
post-thumbnail

🐣 13주차 총정리
Jenkins와 Kubernetes, AWS를 한꺼번에 활용해보면서 알찬 시간을 가졌다. CI/CD로 자동적으로 빌드, 배포하고, Kubernetes를 통해 master node와 worker node 등을 활용하는 방법을 배웠다. 새롭게 배우는 것들이 많아서 매번 공부한 뒤 집와서 복습하기 바빴던 것 같다. 🥹 금주에 배운 것들의 양이 많고 혼자 탐구한 부분도 있어서 포스트를 나눠서 올리기로 했다.

1. Jenkins

1-1. Jenkins란?

Jenkins는 CI/CD 통합 관리 소프트웨어로, pipeline을 구축하여 자동으로 빌드, 배포가 가능하도록 하는 툴이다. 개발과 설계를 하다보면, 모든 작업들을 수작업으로 할 수 없기 때문에 Jenkins와 같은 CI/CD 툴이 필요하다.

Jenkins의 대시보드는 아래와 같으며, 아래 UI에서 pipeline 스크립트 작성 및 설계가 가능하다.

1-2. Jenkins의 장단점 알아보기

Jenkins를 사용하게 되면 Github과 연동하여 자동으로 빌드, 배포할 수 있다. 해당 부분만으로도 충분히 Jenkins를 쓸 이유가 있지만 Jenkins를 더욱 깊게 활용하기 위해서 장점들을 익힐 필요가 있다.

Jenkins의 장점
- 각종 배치 작업들을 간소화시킬 수 있다.
- Build 작업을 자동화시킬 수 있다.
- 컴파일 환경에서 컴파일 오류 검출을 가능하게 한다.
- Github Actions와 달리, 자체 서버에서 실행이 가능하다.

☑️ Jenkins의 단점
- 기본 설정이 부족하고, 대부분 플러그인에 의존하기 때문에 호환성 문제 발생 가능 → 플러그인 관리 필요.
- 기본적으로 보안 설정이 없기 때문에 추가적으로 방화벽 설정이 필수이다.

1-3. 🔍 Github repo 변경사항을 Jenkins로 자동으로 반영시키기

CI/CD 파이프라인을 구축하기 위해 Jenkins 관리 및 플러그인에서 추가한 것들은 아래와 같다.

  1. jdk17 - Java 기반 어플리케이션이 실행되도록 도와준다.
  2. Gradle 13 version - gradle로 Build 관리가 가능하다.
  3. Stage View - Build 과정을 Stage로 볼 수 있도록 도와준다.

Jenkins Dashboard에서 item을 추가할 때 아래와 같이 "github hook for GITScm polling" 옵션을 추가해준다. 이렇게 GitHub Webhook을 추가하면 GitHub이 Jenkins에 직접 변경 사항을 알림으로써, 변경 사항이 있을 때 Jenkins가 자동으로 실행되도록 할 수 있다.

그리고 ngrok을 사용해 Jenkins를 공개 인터넷에서 접근할 수 있도록 터널링해주어, 공개 URL을 얻는다. 나는 Windows 로컬을 사용하고 있어서 관련 버전을 다운로드 받았다.

ngrok 다운로드 받기

$ngrok config add-authtoken <token>
$ngrok http http://localhost:8080

여기에서 http://localhost:8080 부분에는 Jenkins의 dashboard URL을 넣어준다. forwarding 된 URL이 나오면, github repo의 Webhook에 추가한다.

이렇게 Webhooks 를 추가해주고, github repo의 파일들을 바꿔주면 자동으로 jenkins에서 빌드가 수행되고, ngrok이 동작하는 것을 볼 수 있다.

1-4. 🔍 Jenkins 활용해 다른 서버에 파일 보내고 배포하기

현업에서 일하다보면, 특정 시간이 되면 다른 서버에 파일을 보내주는 스케줄링 작업이 자주 필요하다. Jenkins를 활용하면 다른 네트워크에 있는 서버와 해당 VM에 파일을 자동으로 전송하고, 빌드/배포하는 파이프라인을 구성할 수 있다.

Develop environment

  • OS : Ubuntu 24.04.02
  • Virtual Machine : VMware WorkStatation Pro

우선, VM이 DHCP를 사용하지 않고 Static IP를 사용할 수 있도록 네트워크 설정을 해주자. 이미 고정 IP로 설정되어있다면 이 과정은 생략해도 좋다.

$sudo nano /etc/netplan/01-netcfg.yaml

netplan 설정을 위 명령어로 변경한다.

network:
  version: 2
  renderer: networkd
  ethernets:
    ens33:  # 인터페이스 이름
      dhcp4: no  # DHCP 비활성화
      addresses:
        - 10.0.2.20/24  # 원하는 고정 IP
      routes:
        - to: default
          via: 10.0.2.1  # 기본 게이트웨이 (라우터 주소)
      nameservers:
        addresses:
          - 8.8.8.8  # Google DNS
          - 1.1.1.1  # Cloudflare DNS

sudo netplan apply 명령어를 통해서 해당 netplan을 적용한다.

이렇게 설정했다면 VMware의 Network Configure에서 게이트웨이를 10.0.2.1로 설정하고, 서브넷 마스크를 255.255.255.0 으로 설정해준다. (네트워크 설정과 동일하게 설정)

jenkins에서 파일을 scp할 권한을 주기 위해 jenkins로 접속하여, RSA 키를 설정하도록 한다. jenkins를 Docker로 설치했기 때문에, 여기에서는 도커 명령어를 사용했다.

$docker exec -it <Container ID> bash
$ssh-keygen -t rsa -b 4096

SSH를 통해서 비밀번호 없이 해당 서버에 접속 가능하도록 설정해주고, scp로 파일을 보내는 것을 테스트해본다.

$ssh-copy-id username@10.0.2.20
$scp 복사할파일 username@10.0.2.20:/복사받을경로

만약 scp 명령어가 정상적으로 실행된다면, jenkins에서 원격 서버로 접속이 가능하기 때문에 Jenkins 스크립트를 아래와 같이 작성해준다.

pipeline {
    agent any

    environment {
        GIT_REPO = "https://github.com/seulg2027/jenkins_repo.git"
        BRANCH = "main"

        // 빌드 결과를 저장할 로컬 경로 (Jenkins 유저가 접근 가능한 위치로 설정)
        BUILD_DIR = "step07_cicd/bind"
        JAR_NAME = "myapp.jar"

        // 배포 대상 서버 정보
        REMOTE_SERVER = "ubuntu@10.0.2.20"
        REMOTE_DIR = "/home/ubuntu"
    }

    stages {
        stage('Checkout') {
            steps {
                echo "📥 GitHub에서 코드 가져오기"
                git branch: "${BRANCH}", url: "${GIT_REPO}"
            }
        }

        stage('Build with Gradle') {
            steps {
                echo "🔧 Gradle로 JAR 빌드"
                sh '''
                    cd step07_cicd
                    chmod +x gradlew
                    ./gradlew clean build -x test
                    mkdir -p bind
                    JAR_PATH=$(ls build/libs/*SNAPSHOT.jar | grep -v 'plain')
                    cp "$JAR_PATH" bind/myapp.jar
                '''
            }
        }

        stage('Deploy to Server') {
            steps {
                echo "📦 myserver02로 JAR 전송"
                sh '''
                    scp -o StrictHostKeyChecking=no step07_cicd/bind/${JAR_NAME} ${REMOTE_SERVER}:${REMOTE_DIR}/
                '''
            }
        }

        stage('Run on Server') {
            steps {
                echo "🚀 myserver02에서 애플리케이션 실행"
                sh '''
                    ssh ${REMOTE_SERVER} "
                        nohup /usr/bin/java -jar ${REMOTE_DIR}/${JAR_NAME} > ${REMOTE_DIR}/app.log 2>&1 & disown
                    "
                '''
            }
        }
    }
}

2. 느낀 점

✅ 이번 주차 수업에서 좋았던 점

  • 단순하게 Jenkins, k8s의 이론만 배운 게 아니라 왜 사용하는지, 실무에서 효율적으로 활용하는 방안을 생각하며 실습을 진행해서 좋았다.
  • 기존에 배웠던 네트워킹이나 지식들을 함께 사용하면서 점점 인프라 명령어에 익숙해질 수 있었다.

✅ 이번 주차 수업에서 새롭게 배웠던 점

  • 자연스럽게 사용하던 CI/CD 툴들 중 Jenkins에 대해 깊게 탐구할 수 있는 기회가 되었다.

✅ 배운 것에 관해서 내가 부족한 점

  • Kubernetes, Jenkins의 동작과정이나 이론에 대한 깊은 이해가 아직 부족하다고 느낀다..🥹 더 깊게 공부해보자 아쟈쟈..!

✅ 앞으로 뭘 더 하면 좋을까?

  • 프로젝트에서 활용하는 방안을 모색하고, Jenkins script를 더 효율적으로 구성할 수 있을지 고민해봐야겠다.

0개의 댓글