728x90
여러개의 서비스(MSA)으로 운영중이여서 서비스가 최소 20개가 넘는다.
그래서 이걸 반영할 때 개발자들이 하나하나 자신의 PC에서 빌드해서 .war 파일을 sftp로 올린 후에 반영했다.
그걸 해결하기 위해서 Jenkins를 이용해 사내에서 사용하는 Gitlab서버에서 빌드하고 배포하도록 하는게 좋겠다 생각했다.
처음엔 Jenkins에서 Item Type을 Freestyle project로 만들어서 사용했다.
근데 제약사항들도 많고 생각보다 병렬처리하는 과정에서 너무 복잡했다. 아무래도 Jenkins에서 제공하는 틀안에서만 해야 하다 보니까 더 그랬던것 같다.
그와중에 정말정말 옛날버전으로 사용하고 있다가 플러그인 업데이트를 했는데 갑자기 Jenkins가 맛이 갔다.
그래서 오히려 잘됬다 싶어 이걸 Pipline으로 구성해보자 생각했다.
Jenkins버전도 올리고, JAVA버전도 21로 올렸다.
문법적인건 https://www.jenkins.io/doc/book/pipeline/ 를 참고했고 나머지 코드들은 Claude와 함께 했다.
내가 하고 싶은 구조 설명
우리 회사에서는 maven, gradle을 사용해 서비스를 빌드한다. 그리고 빌드가 완료되면 .war 파일을 운영, 베타 서버에 이동 시켜야 한다.
그리고 원하는 디렉토리에 기존 .war 파일을 백업하고 새로 빌드한 .war 의 이름을 변경해줘야 했다.
또한 일부 서비스 서브 모듈을 사용하고 있고, 일부는 Gradle파일에서 코드를 작성해 Pprofile옵션에 베타인지 리얼인지 파라미터로 던져줘야 하는 것도 있다.
이 과정을 작성하겠다. 다 같은 환경이 아니기 때문에 참고만 하면 될 것 같다.
젠킨스 설치
젠킨스 설치는 최신 버전으로 설치했다.
Download Jenkins 2.462.3 LTS for 에 가서 다운로드 받으면 된다.
그리고 자바 버전은 젠킨스 홈페이지에 Java Support Policy 를 보고 선택했다. 난 JDK21버전을 설치했다.
젠킨스를 설치하는 방법은 여러 방법이 있지만 난 Tomcat을 이용해 war를 풀어 사용했다.
인터넷에 많은 사람들이 젠킨스 설치하는 방법을 많이 올려두어서 그런 사소한 내용들은 담지 않겠다.
필요하다면 댓글 남겨주시면 가이드 문서 공유는 가능하다. 이전에 구축할 때 작성한 문서가 있어서...
이제 설치까지 완료가 되고 젠킨스 관리자 계정으로 로그인했다는 가정하여 작성하겠다.
필수 플러그인 설치 및 설정
아래 새 개의 플러그인을 설치하고 빌드할 JDK버전 선택을 해야 한다.
우선 설치 방법은 Jenkins 관리 → Plugins → Available Plugins에 들어가서 검색해 설치하면 된다.
만약에 없다면 설치되어 있는 것이니 Installed plugins에 들어가서 확인하면 된다.
- SSH Agent Plugin
- Maven Integration plugin
- Gradle Plugin
Gradle, Maven 플러그인 설정 및 자바 버전 설정
이제 설치한 Gradle과 Maven의 어떤 버전을 사용할 지 지정해주어야 한다.
Jeknins 관리 → Tools 에 들어간 후에 플러그인이 정상적으로 설치 되었다면 Gradle installations와 Maven installations가 있을 것이다.
Gradle installations 버전 선택
- Gradle installations 선택
- Add Gradle 선택
- name에 그래들을 구별할 수 있도록 이름을 지어주자
- install automatically 체크 선택
- Version은 자신이 사용하고 있는 버전을 선택한다.
Maven installations 버전 선택
- Maven installations 선택
- Add Maven 선택
- name에 그래들을 구별할 수 있도록 이름을 지어주자
- install automatically 체크 선택
- Version은 자신이 사용하고 있는 버전을 선택한다.
JDK installations 버전 선택
빌드 할 때 사용할 자바 버전을 선택할 수 있는 JDK installations 설정도 함께 해준다.
- Name: JDK도 여러개 등록이 가능하기 때문에 이를 식별하기 위해 식별자 이름을 지정해주는 것이다.
- JAVA_HOME: JDK가 설치된 경로를 적어둔다. 빌드하는 서버에 사용할 자바 버전을 적어야 한다.

Global Credentials 인증 설정
인증은 여기 설정에서 한다.
Gitlab에 접속 권한이 있는 계정이 소스를 불러오려면 Username with password 종류의 인증이 필요할 것이다.
원격지 서버에 빌드된 파일을 옮겨야 하기 때문에 SSH Username With private key 종류의 인증이 필요할 것이다.
Gitlab 인증 설정
Jenkins 관리 → Credentials → (Global)이라고 괄호 선택 → Add Credentials 선택
global이라고 적힌 괄호 아무거나 선택해도 된다.



- Kind: Username with password
- Scope: Global
- ID: 생성한 Credentials를 구별하기 위한 식별자
- Username: Gitlab에 프로젝트 권한이 있는 계정명을 입력
- Password: Gitlab에 프로젝트 권한이 있는 계정의 Access Tokens 입력
SSH 서버 인증 설정
Jenkins 관리 → Credentials → (Global)이라고 괄호 선택 → Add Credentials 선택

- Kind: SSH Username with private key
- Scope: Global
- ID: 생성한 Credentials를 구별하기 위한 식별자
- Username: 내 서버에 어떤 계정으로 붙을 것인지 계정명을 입력
- Private Key(Enter directly): Add를 누르고 원격지 서버의 Private Key를 넣으면 된다.
혹시나 없는 경우 아래에 방법을 작성했다.
(+추가) SSH Key 생성 방법
Gitlab과 Jenkins가 설치되어있는 서버에서 키를 생성해준다.
아래 적어둔 방법과 같이 진행하면 된다.
# 1. Jenkins 서버에서 새로운 키 생성
ssh-keygen -t rsa -b 4096 -C "내가원하는명칭"
# 암호구문은 비워두세요 (그냥 Enter 누르기)
# 2. 타겟 서버의 공유키 전달
# 해당 명령어 이후에 패스워드를 입력하라고 나오는데 원격지 서버 계정의 패스워드를 입력하면된다.
ssh-copy-id myservice@원격지서버ip
# 3. 테스트
# 패스워드가 없이 로그인되어야 한다.
ssh myservice@원격지서버ip 'echo "Connection successful"'
원격지 서버 (빌드된 파일을 실행할 서버)
# 서비스 서버에서 새로운 키 생성
ssh-keygen -t rsa -b 4096 -C "MyServiceServer-1"
# 암호구문은 비워두세요 (그냥 Enter 누르기)
각 두개의 서버의 SSH Key 확인
# Private Key
vi ~/.ssh/id_rsa
# Public Key
vi ~/.ssh/id_rsa.pub
Gitalb 연결 테스트
- 새로운 Item을 생성
- 이름을 지정하고 Pipline을 선택
- 하단 파이프라인에 Pipline Script를 선택하고 하단에 아래 코드에서 한글로 적어둔 부분을 자신의 환경에 맞게 작성
- 파이프라인을 실행해서 정상적으로 깃랩에 붙는지 확인
pipeline {
agent any
stages {
stage('GitLab Connection Test') {
steps {
echo 'Testing GitLab Connection...'
checkout([$class: 'GitSCM',
branches: [[name: '*/main']],
userRemoteConfigs: [[
credentialsId: '여기에 위에 만든 식별자 ID를 넣어주세요',
url: '리포지토리에서 http로 주소를 넣어주세요.'
]]
])
sh '''
echo "Repository Info:"
git remote -v
echo "\nCurrent Branch:"
git branch
echo "\nLast Commit:"
git log -1
'''
}
}
}
post {
success {
echo 'GitLab connection test successful!'
}
failure {
echo 'GitLab connection test failed!'
}
}
}
SSH 서버 연결 테스트
파이프라인을 생성해서 아래 코드를 입력해보자.
pipeline {
agent any
environment {
// Jenkins에 등록된 SSH 자격증명 ID
// 위에 SSH 인증 생성할 때 작성한 'myServerSSH'를 넣어줬다.
SSH_CREDS = credentials('myServerSSH')
// 대상 서버 정보
REMOTE_HOST = '10.100.11.135' // 실제 서버 IP로 변경
REMOTE_USER = 'username' // 실제 사용자명으로 변경
}
stages {
stage('SSH Connection Test') {
steps {
script {
// SSH 연결 테스트
sh '''
echo "Testing SSH Connection..."
# SSH 연결 테스트 (기본 명령어 실행)
ssh -o StrictHostKeyChecking=no ${REMOTE_USER}@${REMOTE_HOST} '
echo "Successfully connected to $(hostname)"
echo "Current user: $(whoami)"
echo "Current directory: $(pwd)"
echo "System info: $(uname -a)"
'
'''
}
}
}
}
post {
success {
echo 'SSH connection test completed successfully!'
}
failure {
echo 'SSH connection test failed. Please check credentials and connection settings.'
}
}
}
완성된 파이프라인
이제 위 설정을 다 합쳐서 응용해봤다. 베타 서버에 배포하는 과정이다.
여기서 더 응용해서 검증하는 로직들을 꼭 추가하자....
- JAVA1.8버전으로 maven-3.9.9 버전으로 빌드
- 파이프라인에 입력되는 명칭은 위 maven, jdk 설정할때 이름을 지정했을 것이다. 그 명칭을 적어주어야 한다. - 모든 코드에 들어가는 함수를 지정한다.
- Gitlab연결을 테스트 및 빌드할 파일을 가져온다.
- Maven을 이용해서 빌드한다.
- 빌드한 파일을 내가 배포할 서버에 옮기고 기존 파일을 백업하고 빌드된 파일명을 기존 사용하는 파일명으로 변경한다.
- 서버를 재시작 한다.
Maven 빌드 코드
pipeline {
agent any
tools {
jdk 'JAVA1.8'
maven 'maven-3.9.9'
}
environment {
REMOTE_SERVER = '10.100.11.135'
REMOTE_USER = 'myuser'
REMOTE_DIR = '/webstore/myservice/server/webapps/war'
WAR_FILE = 'target/*.war'
BACKUP_DIR = '/webstore/myservice/server/webapps/war/back'
CURRENT_WAR = 'Myservice.war'
BETA_WAR = 'Myservice_beta.war'
}
stages {
stage('GitLab Connection Test') {
steps {
checkout([$class: 'GitSCM',
branches: [[name: '*/beta']],
userRemoteConfigs: [[
url: 'http://10.100.11.100:8888/BNFC/BNFC_IF.git',
credentialsId: '여기에 젠킨스 인증 생성 시 작성했던 ID를 넣어주세요'
]],
extensions: [
[$class: 'SubmoduleOption',
disableSubmodules: false,
parentCredentials: true,
recursiveSubmodules: true,
reference: '',
trackingSubmodules: true
]
]
])
sh 'echo "GitLab 연결 테스트 성공!"'
}
}
stage('Maven Build') {
steps {
sh 'mvn clean package -P beta'
}
}
stage('Deploy to Remote Server') {
steps {
sshagent(['MyServerSSH']) {
sh """
# 원격 디렉토리 존재 확인 및 생성
ssh ${REMOTE_USER}@${REMOTE_SERVER} '[ -d ${REMOTE_DIR} ] || mkdir -p ${REMOTE_DIR}'
ssh ${REMOTE_USER}@${REMOTE_SERVER} '[ -d ${BACKUP_DIR} ] || mkdir -p ${BACKUP_DIR}'
# WAR 파일 전송
scp ${WAR_FILE} ${REMOTE_USER}@${REMOTE_SERVER}:${REMOTE_DIR}/${BETA_WAR}
# 현재 시간을 백업 파일명에 추가
ssh ${REMOTE_USER}@${REMOTE_SERVER} '
if [ -f ${REMOTE_DIR}/${CURRENT_WAR} ]; then
TIMESTAMP=\$(date "+%Y%m%d%H%M")
mv ${REMOTE_DIR}/${CURRENT_WAR} ${BACKUP_DIR}/${CURRENT_WAR}_\${TIMESTAMP}
fi
'
# beta WAR 파일을 정식 WAR 파일로 이름 변경
ssh ${REMOTE_USER}@${REMOTE_SERVER} 'mv ${REMOTE_DIR}/${BETA_WAR} ${REMOTE_DIR}/${CURRENT_WAR}'
echo "WAR 파일 배포, 백업 및 이름 변경 완료"
"""
}
}
}
stage('Server Restart') {
steps {
sshagent(['TWAS7-tmonet2k']) {
sh """
ssh ${REMOTE_USER}@${REMOTE_SERVER} '
cd /webstore/pub/DD_IF_BETA/server/bin
# shutdown 3번 실행
./shutdown.sh
sleep 5
./shutdown.sh
sleep 5
./shutdown.sh
sleep 5
# startup 백그라운드 실행
nohup ./startup.sh > /dev/null 2>&1 &
echo "서버 재시작 완료"
'
"""
}
}
}
}
post {
success {
sh 'echo "빌드 및 배포 성공!"'
}
failure {
sh 'echo "빌드 또는 배포 실패!"'
}
}
}
Gradle 빌드 코드
- JAVA1.8을 이용하고 Gradle버전은 gradle-5.6.1을 사용해 빌드한다.
(반드시 위 JDK와 Gradle플러그인 설정에서 생성할 때 작성한 식별자로 작성해야 한다.) - 빌드하는 사용자가 자신이 빌드할 브랜치명을 작성해서 빌드하도록 한다.
이유는 개발자 측의 요청이였다. - 깃랩 연결 및 어떤 깃랩을 가져올지 설정한다. 추가로 서브모듈을 사용하고 있어 서브모듈 설정을 넣어두었다.
- Gradle로 빌드한다.
- 빌드된 파일은 원격지 서버에 원하는 디렉토리에 이동시키고 기존 사용하고 있는 배포파일명으로 변경한다. 기존 파일은 백업한다.
- 서버를 재시작 한다.
pipeline {
agent any
tools {
jdk 'JAVA1.8'
gradle 'gradle-5.6.1'
}
parameters {
string(
name: 'BRANCH',
defaultValue: 'master',
description: '빌드할 브랜치명을 입력하세요 (예: master, feature/login, bugfix/issue-123)'
)
}
environment {
REMOTE_SERVER = '10.100.11.135'
REMOTE_USER = 'myuser'
REMOTE_DIR = '/webstore/myservice/webapps/war'
WAR_FILE = 'build/libs/*.war'
BACKUP_DIR = '/webstore/myservice/webapps/war/back'
CURRENT_WAR = 'myservice-1.0-SNAPSHOT.war'
BETA_WAR = 'myservice-1.0-SNAPSHOT_real.war'
SERVER_BIN_DIR = '/webstore/BCASH/bin'
}
stages {
stage('GitLab Connection Test') {
steps {
checkout([$class: 'GitSCM',
branches: [[name: "*/${params.BRANCH}"]],
userRemoteConfigs: [[
url: 'http://10.100.11.100:8888/BNFC/BCASH.git',
credentialsId: '여기에 젠킨스 인증 생성 시 작성했던 ID를 넣어주세요'
]],
extensions: [
[$class: 'SubmoduleOption',
disableSubmodules: false,
parentCredentials: true,
recursiveSubmodules: true,
reference: '',
trackingSubmodules: true
]
]
])
sh 'echo "GitLab 연결 테스트 성공!"'
}
}
stage('Gradle Build') {
steps {
sh "gradle clean war -Pprofile=real"
}
}
stage('Deploy to Remote Server') {
steps {
sshagent(['MyServerSSH']) {
sh """
# 원격 디렉토리 존재 확인 및 생성
ssh ${REMOTE_USER}@${REMOTE_SERVER} '[ -d ${REMOTE_DIR} ] || mkdir -p ${REMOTE_DIR}'
ssh ${REMOTE_USER}@${REMOTE_SERVER} '[ -d ${BACKUP_DIR} ] || mkdir -p ${BACKUP_DIR}'
# WAR 파일 전송
scp ${WAR_FILE} ${REMOTE_USER}@${REMOTE_SERVER}:${REMOTE_DIR}/${BETA_WAR}
# 현재 시간을 백업 파일명에 추가
ssh ${REMOTE_USER}@${REMOTE_SERVER} '
if [ -f ${REMOTE_DIR}/${CURRENT_WAR} ]; then
TIMESTAMP=\$(date "+%Y%m%d%H%M")
mv ${REMOTE_DIR}/${CURRENT_WAR} ${BACKUP_DIR}/${CURRENT_WAR}_\${TIMESTAMP}
fi
'
# beta WAR 파일을 정식 WAR 파일로 이름 변경
ssh ${REMOTE_USER}@${REMOTE_SERVER} 'mv ${REMOTE_DIR}/${BETA_WAR} ${REMOTE_DIR}/${CURRENT_WAR}'
echo "WAR 파일 배포, 백업 및 이름 변경 완료"
"""
}
}
}
stage('Server Restart') {
steps {
sshagent(['MyServerSSH']) {
sh """
ssh ${REMOTE_USER}@${REMOTE_SERVER} '
cd ${SERVER_BIN_DIR}
# shutdown 3번 실행
./shutdown.sh
sleep 5
./shutdown.sh
sleep 5
./shutdown.sh
sleep 5
# startup 백그라운드 실행
nohup ./startup.sh > /dev/null 2>&1 &
echo "서버 재시작 완료"
'
"""
}
}
}
}
post {
success {
sh 'echo "빌드 및 배포 성공!"'
}
failure {
sh 'echo "빌드 또는 배포 실패!"'
}
}
}
728x90
'Etc' 카테고리의 다른 글
[Onedrive] 다운로드, 동기화, 업로드 오류 (2) | 2024.10.08 |
---|---|
Elasticsearch, kibana 설치 및 연동(Zip) (0) | 2024.03.20 |
AI를 통한 웹 페이지 만들기 (make real tldraw) (2) | 2023.11.28 |