앞선 글에서 각 인스턴스별 설정들을 진행해주었다.
Jenkins 설정
- `sudo cat /var/lib/jenkins/secrets/initialAdminPassword`로 Jenkins 초기 비밀번호를 출력, 권장 설치를 진행한다.
- Jenkins 관리 - Tools - Gradle 설치 (ID는 임의로 'GRADLE'로 설정)
- Jenkins 관리 - Plugins - Available plugins에서 SSH Agent, Pipeline: Stage View 설치
- Jenkins 관리 - Credentials - Github 웹 훅 토큰과 NHN Cloud에서 인스턴스 생성 시 지정한 .pem 설정
- 깃허브 레포지토리 - webhook의 주소를 Jenkins 인스턴스의 Public IP로 변경
(ex: http://IP주소:8080/github-webhook/) - 파이프라인 코드 입
Pipeline - Rolling 배포
AWS에서 사용했던 파이프라인 코드를 거의 그대로 사용했다.
다만 스프링 어플리케이션의 .jar 파일명이 빌드 시각에 따라 바뀌므로 해당 부분을 동적으로 추출하여 `env.JAR_NAME`에 저장하고,
이를 `deployApp` 함수에 전달하여 해당 파일명을 사용하는 방식으로 바꾸어주었다.
+ 빌드가 시작되기 전, 이전의 .jar 파일은 삭제하도록 설정 추가
pipeline {
tools {
gradle "GRADLE" // Jenkins에서 설정한 Gradle의 이름
}
agent any
environment {
JAR_NAME = '' // 빌드된 JAR 파일명을 저장할 변수
}
stages {
stage('Clone') {
steps { // main인지 master인지 확인하고 Pipeline Syntax 돌려서 이중으로 확인해보기
git branch: 'main', url: 'https://github.com/lcl1380/KDT_Project3.git'
}
}
stage('Clean Up Old Artifacts') {
steps {
// 기존의 .jar 파일들을 삭제
sh 'rm -f build/custom-libs/*.jar'
}
}
stage('Build') {
steps {
sh 'chmod +x ./gradlew'
sh './gradlew clean build'
script {
// 빌드된 JAR 파일명 추출
def jarFile = sh(script: "ls build/custom-libs/*.jar | head -n 1", returnStdout: true).trim()
env.JAR_NAME = jarFile.split('/').last()
}
}
}
stage('Test') {
steps {
script {
sh './gradlew test'
}
}
}
stage('Deploy A-Private Instance') {
steps {
script {
try {
// 첫 번째 인스턴스로 배포
deployApp('192.168.2.31', 22, env.JAR_NAME)
// 두 번째 인스턴스로 배포
// deployApp('192.168.2.32', 22, env.JAR_NAME)
} catch (Exception e) {
// 오류 발생 시 롤백
rollbackApp('192.168.2.31', 22)
// rollbackApp('192.168.2.32', 22)
throw e
}
}
}
}
// stage('Deploy B-Private Instance') {
// steps {
// script {
// try {
// // 첫 번째 인스턴스로 배포
// deployApp('192.168.5.31', 22, env.JAR_NAME))
// // 두 번째 인스턴스로 배포
// deployApp('192.168.2.32', 22, env.JAR_NAME)
// } catch (Exception e) {
// // 오류 발생 시 롤백
// rollbackApp('192.168.5.31', 22)
// rollbackApp('192.168.5.32', 22)
// throw e
// }
// }
// }
// }
}
post {
success {
echo "배포가 성공적으로 완료되었습니다."
}
failure {
echo "배포에 실패했습니다. 롤백을 수행했습니다."
}
}
}
def deployApp(targetServerIp, targetServerPort, jarName) {
def deployPath = '/home/ubuntu'
def runAppCommand = "nohup java -jar $deployPath/$jarName > nohup.log 2>&1 &"
def checkLogCommand = "grep -q 'Started logging-sample-prj in' $deployPath/nohup.log"
def checkProcessCommand = "pgrep -f $jarName"
// 서버에 파일을 SCP로 전송
sshagent(['KDT_Project3_NHN']) { // 이 부분에서 'KDT_Project3_NHN'는 Jenkins에 등록한 Credential ID (NHN에서 발급한 키 페어)
// 기존 애플리케이션 프로세스 종료
sh "ssh -o StrictHostKeyChecking=no -p $targetServerPort ubuntu@$targetServerIp 'ps -ef | grep java | grep -v grep | awk \'{print \$2}\' | sudo xargs kill -9 || echo \"No process found\"'"
// 새로운 JAR 파일 배포 및 애플리케이션 시작
sh "scp -o StrictHostKeyChecking=no -P $targetServerPort build/custom-libs/$jarName ubuntu@$targetServerIp:$deployPath/"
sh "ssh -o StrictHostKeyChecking=no -p $targetServerPort ubuntu@$targetServerIp '$runAppCommand'"
}
}
def rollbackApp(targetServerIp, targetServerPort) {
def previousJarPath = 'build/libs/previous-logging-sample-prj-0.0.1-SNAPSHOT.jar'
def deployPath = '/home/ubuntu'
def runAppCommand = "nohup java -jar $deployPath/previous-inclass-spring-security-0.0.1-SNAPSHOT.jar > nohup.log 2>&1 &"
// 이전 버전의 JAR 파일을 배포하고 애플리케이션을 시작
sshagent(['KDT_Project3_NHN']) { // 이 부분에서 'KDT_Project3_NHN'는 Jenkins에 등록한 Credential ID (NHN에서 발급한 키 페어)
// 기존 애플리케이션 프로세스 종료
sh "ssh -o StrictHostKeyChecking=no -p $targetServerPort ubuntu@$targetServerIp 'ps -ef | grep java | grep -v grep | awk \'{print \$2}\' | sudo xargs kill -9 || echo \"No process found\"'"
// 이전 버전 JAR 파일 배포 및 애플리케이션 시작
sh "scp -o StrictHostKeyChecking=no -P $targetServerPort $previousJarPath ubuntu@$targetServerIp:$deployPath/"
sh "ssh -o StrictHostKeyChecking=no -p $targetServerPort ubuntu@$targetServerIp '$runAppCommand'"
}
}
'🌥️Cloud Study🌥️ > NHN' 카테고리의 다른 글
[ NHN Cloud ] 인스턴스 이미지 생성 후 사용하기 (0) | 2024.08.08 |
---|---|
[ NHN Cloud ] 3-Tier Architecture 수동 프로비저닝-3 (Grafana, Prometheus 설정) (0) | 2024.08.06 |
[ NHN Cloud ] 3-Tier Architecture 수동 프로비저닝-1 (네트워크, 보안 그룹, 인스턴스 초기 설정) (0) | 2024.08.05 |
[ NHN 클라우드 ] Jenkins Pipeline을 이용한 배포 (0) | 2024.07.11 |
[ NHN 클라우드 ] 도커 이미지 기반 배포로 전환 (0) | 2024.07.11 |