[학습] 젠킨스 프리스타일 vs 파이프라인
- 국비지원 (스파르타)
- 2025. 4. 27. 01:07
왜 이름을 프리스타일로 했는지는 알 수 없지만 젠킨스 프리스타일은 젠킨스에서 GUI로 CI/CD를 할 수 있게 제공하는 기능이라고 생각하면 된다.
그러면 프리스타일을 어떻게 하면 파이라인으로 바꿀 수 있을지 생각해보자.
일단 CI/CD를 하기 위해서는 코드가 필요하다. 코드를 가져올 수 있는 방법은 크게 2가지가 있는데
직접 가져오는 방법이 있겠고 깃에서 가져오는 방법이 존재한다.
근데 사실상 직접 넣으면 젠킨스로 CI/CD를 하는 이유가 전혀 없을 거 같다.
그렇다면 젠킨스는 어떻게 코드를 가져올 수 있을까?
이 그림은 젠킨스-프리스타일로 할때 깃에서 코드를 가져오는 구문이다.
이렇게 되면 깃에서 코드를 가져올 수 있게 된다.
다른 방안이 있는지는 잘모르겠지만 아무튼 이것을 프리스타일이 아닌 파이프라인으로 변경하면 어떻게 될까?
stage('Git Clone') {
steps {
git branch: 'develop', url: 'https://github.com/sparta-MOIM/MOIM-Server.git/'
}
}
요렇게 작성하면 된다. 아래에 프리스타일 문법을 적어놓을 예정이기 때문에 지금은 1:1 대응으로 보면 좋을거 같다. (지금 이걸 그대로 쓴다고 정상적으로 실행은 안될거다... 아마도??? 그렇지 않을까..)
이것을 하게 되면 특정 브랜치에서 깃 코드를 가져올 수 있게 된다.
이렇게 코드를 가져오면 젠킨스내에 저장되어지게 된다.
/var/lib/docker/volumes/jenkins_jenkins_home/_data/workspace/test/build/libs/**
요 밑으로 가져오는거 같다.
그럼 이제 어떻게 해야 할까?
코드를 가져왔으니 이걸 옮겨야 할까?
아님 실행을 시켜봐야 할까?
두가지 모두 할 수 있겠지만 수 많은 파일을 옮기는 건 쉽지 않을 수도 있다. 또, 자바는 어떤걸로 실행이 되는지 생각을 해봐야 한다.
자바는 java -jar을 통해 자바를 실행시킨다.
우리가 ide에 찌들여서 java -jar을 망각하는 경우가 있는데 ide로 실행하게 되어도 빌드 과정이 무조건 진행이 되어진다.
아무튼 우리가 필요한건 수많은 소스코드를 서버로 옮기냐 jar파일을 옮기냐의 차이인데
jar파일을 옮기는 것이 더 간단한 작업일지도 모른다.
아니 그럴 확률이 높다.
그래서 나는 jar파일을 만드는 방법을 선택했다. 그러면 이걸 어떻게 해야 할까?
바로 빌드를 하면 된다.
자바를 위에서 말한것처럼 java -jar을 할 수 도 있겠지만
우리는 그레들,메이븐....같은 빌드 도구들이 존재한다. 엔트라는게 있다는 소문은 들었지만 잘 모르겠다.
얘네를 이용하게 되면 빌드를 쉽게 할 수 있다.
그러면 젠킨스에서 얘네를 어떤 기준으로 결정하는지 생각해보면 그냥 어떤걸로 만들었는지 생각을 해보면된다.
메이븐은 메이븐으로 그레들은 그레들로..
그러면 어떻게 할 수 있을까?
바로 요렇게 할 수 있는데 지금 task쪽을 보면 알 수 있듯이 gradle같은 건 생략이 되어있다. 그러니까 저걸로 빌드를 하면 된다.
또한 저기는 그레들 문법을 작성하면 되기 때문에 생략한다!!
그러면 요걸 파이프라인으로 바꿔보면...
stage('Gradle Build') {
steps {
sh "./gradlew :${SERVICE_NAME}:clean :${SERVICE_NAME}:build -x test"
}
}
요렇게 작성할 수 있다. 저 가려진게 머냐고 물어볼수 있는데 저거는 추후에 설명예정이다.
이렇게 작성하면 위에서 확인한 /var/lib/docker/volumes/jenkins_jenkins_home/_data/workspace/test/build/libs/**
요기에 jar파일이 옮겨졌다는것을 확인 할 수 있다. 물론 경로는 사람마다 다를 수 있으니
sudo find / -name "*.jar" 요걸 통해 알 수 도 있다.
참고로 *은 전체를 뜻하니 특정 파일의 이름을 넣어서 찾으면 된다.
여기까지가 CI다 이렇게 젠킨스 내부에서 코드를 통합하는 과정이 있다.
요걸 응용하면 git push가 들어올때 CI까지 하게 만들 수 도 있는데 젠킨스에 대한 이해도가 떨어져서 고건 힘들지도..
이제 CD다. CD는 쉽게 말해 배포다. 단지 내가 아니라 젠킨스가 대신 해주는 고런 느낌으로 생각하면 된다.
이걸 내가 다 작성하는게 맞는지는 모르겠지만 지금 너무 힘들다.
그냥 플러그인 알려줄테니 알아서 찾기를...
일단 서버에 접속을 하려면 SSH를 통해 접속할 수 있다.
근데 ec2에 접근을 하려면 ssh만으로는 부족하다 바로 pem키라는게 필요한데 ssh -i {key.pem} 요렇게 접근 해야 ec2에 접근할 수 있다. 문제는 요게 잘안먹힐 수 있다는.. 저 방법이 젠킨스에서 문제가 뭐냐면 저파일이 젠킨스 내에 어디에 정확히 알고 있어야 저 명령어가 의미가 있는데 pem키를 생성할때마다 젠킨스에 넣는 건 좀 거추장스럽다.
그러면 어떻게 할까 제일 먼저 소개할 플러그인은 Publish Over SSH 요거다. 요거는 system에 pem키를 넣을 수 있다. 자세한건 생략ㅎ
등록을 하게 되면 프리스타일에서는 요런것을 추가할 수 있다.
요기서 시스템에서 지정한 ssh-server의 이름을 넣고 souce file은 내가 보낼 jar파일을 넣는데 문제는 저걸 어떤 기준으로 작성했는지 까먹었다. ㅎㅎㅎ
그리고 Remote directory 요건 보낼곳 (서버 -ec2젠킨스 서버아님) 을 정해놓으면 된다.
마지막으로 Exec command 이 cmd명령어를 작성하면 된다. 이곳은 젠킨스 환경이 아닌거롤 명심해야 한다.
이걸 파이프라인으로 가져다 사용하면 잘 되지는 않는다.
왜냐하면 파이프라인에서는 ssh over publish가 잘 안먹혔던걸로 기억하기 때문이다. 내가 방법을 모르는거 일 수도 있는데
두번째 소개할 플러그인이 바로 ssh agent다.
요것도 ec2에 접근할 수 있게 도와주는 녀석이다.
두가지의 큰 차이점은 pemkey에 있다. 전자의 경우 하나의 pemkey만 등록이 가능하지만, 후자는 여러개가 등록이 가능하다. 어케하는지는 여기에 작성이 되지 않는다. 귀찮다
stage('SSH 접속 및 확인') {
steps {
sshagent (credentials: ['ec2-ssh-key']) {
sh "scp -o StrictHostKeyChecking=no ${JAR_FILE} ubuntu@${sever}:${REMOTE_PATH}/"
}
}
}
stage('Run Deploy Script') {
steps {
sshagent (credentials: ['ec2-ssh-key']) {
sh """
ssh -o StrictHostKeyChecking=no ubuntu@${sever} '
chmod +x /home/ubuntu/deploy/deloly.sh &&
/home/ubuntu/deploy/deloly.sh
'
"""
}
}
}
요 부분으로 ssh을 사용할 수 있게 되었다.
sshagent (credentials: ['ec2-ssh-key']) 여기에 잘 등록만 해주면 된다.
코드를 보고 딜로이가 머냐고 생각할 수 있다 저건 deploy의 오타이며 sh내용은 ec2에 저장되어있다.
그니까 접근해서 저 cmd명령어를 전달한다. 머 요런뜻이다.
+ 파이프라인 문법 (요거는 gpt로 대체합니다.)
pipeline {
agent any
stages {
stage('Stage 이름') {
steps {
sh '명령어'
}
}
}
}
기본적으로 요런 코드를 작성해야 한다.
구성요소설명
pipeline | 파이프라인 전체 정의 시작 |
agent | 어떤 머신(노드)에서 실행할지 지정 (any면 아무데나) |
stages | 작업 단계들 묶음 |
stage | 각 단계 (ex: 빌드, 테스트, 배포) |
steps | 각 단계 안에서 실제 실행할 명령어들 |
1. agent :
- 아무 에이전트에서 실행
agent any - 특정 노드 지정하려면:
agent { label 'my-server' }
2. stages + stage + steps
stages {
stage('Build') {
steps {
sh './gradlew build'
}
}
stage('Deploy') {
steps {
sh 'scp app.jar 서버로 복사'
}
}
}
- 여러 stage가 순서대로 실행돼.
3. 환경변수 environment
environment {
SERVICE_NAME = 'chat-service'
DEPLOY_PATH = '/home/ubuntu/deploy'
}
- SERVICE_NAME 같은 값을 steps 안에서 쓸 수 있어.
4. 조건부 실행 when
stage('Deploy') {
when {
branch 'main'
}
steps {
sh './deploy.sh'
}
}
- 특정 브랜치(main) 에서만 실행되게 할 수 있어!
5. 트리거 triggers
triggers {
githubPush()
}
- git push 되면 자동으로 빌드 시작!
6. 병렬 실행 parallel
stage('Test') {
parallel {
stage('Unit Test') {
steps {
sh './gradlew test'
}
}
stage('Integration Test') {
steps {
sh './gradlew integrationTest'
}
}
}
}
여러 테스트를 동시에 병렬로 돌릴 수 있어.
기본구조
pipeline {
agent any
environment { 변수 정의 }
triggers { 이벤트 설정 }
stages {
stage('1') { steps { 명령어 실행 } }
stage('2') { steps { 명령어 실행 } }
stage('3') { when { 조건 } steps { 명령어 실행 } }
}
}
7. post: stages가 다 끝나고 빌드 성공, 실패, 항상(always) 등에 따라 실행되는 블록
조건설명
always | 성공, 실패 상관없이 무조건 실행 |
success | 빌드 성공했을 때만 실행 |
failure | 빌드 실패했을 때만 실행 |
unstable | 빌드 결과가 unstable(성공은 했지만 경고 있음)일 때 실행 |
changed | 이전 빌드랑 결과가 다를 때 실행 |
8. 파라미터: 배포시 선택값 사용
Jenkins Pipeline에서 파라미터 사용하는 방법
기본은 이렇게 작성해:
pipeline {
agent any
parameters {
choice(name: 'DEPLOY_ENV', choices: ['dev', 'stage', 'prod'], description: '배포 환경을 선택하세요.')
booleanParam(name: 'ROLLBACK', defaultValue: false, description: '롤백 실행 여부')
string(name: 'VERSION_TAG', defaultValue: 'latest', description: '배포할 버전 태그 입력')
}
stages {
stage('Print Parameters') {
steps {
echo "선택한 배포 환경: ${params.DEPLOY_ENV}"
echo "롤백 여부: ${params.ROLLBACK}"
echo "버전 태그: ${params.VERSION_TAG}"
}
}
}
}
여기서
choice | 여러 옵션 중 선택할 수 있게 한다 | dev, stage, prod |
booleanParam | true/false 체크박스 | 롤백 실행 여부 같은 거 |
string | 자유 입력 문자열 | 버전 이름, 태그 등 |
Jenkins 빌드 버튼을 누르면 → 파라미터 입력 화면이 먼저 떠!
흐름 부드럽게 요약
- Jenkinsfile 안에 parameters 블록 추가
- Jenkins Job 생성할 때 "This project is parameterized" 자동 활성화
- 빌드 누르면 선택/입력하는 화면 나옴
- params.변수이름 으로 파이프라인 안에서 사용 가능
아주 쉬운 예시
- DEPLOY_ENV가 "prod" 이면 진짜 배포하고,
- 아니면 그냥 빌드만 하고 넘어가고 싶을 때!
stage('Deploy') {
when {
expression { params.DEPLOY_ENV == 'prod' }
}
steps {
echo "프로덕션에 배포 시작!"
// 배포 스크립트 실행
}
}
이렇게 파라미터 값에 따라 분기할 수 있어.
추가적으로
sh는 리눅스 명령어 실행할 때 쓰인다
Jenkins Pipeline에서 알아두면 좋은 블록 모음
environment | 환경변수 선언 (ex: SERVICE_NAME) | 값 관리가 편해지고, 수정할 때 한 곳만 바꾸면 됨 |
options | 파이프라인 옵션 설정 (ex: timeout, retry 등) | 빌드 제한, 재시도 같은 제어가 쉬워짐 |
parameters | 사용자 입력값 받을 때 사용 | "이 서비스만 배포" 같은 선택지를 주고 싶을 때 |
tools | 빌드 툴 설정 (ex: Gradle, Maven 설치 자동화) | 개발환경 맞춰주기 좋음 |
triggers | 외부 이벤트로 파이프라인 자동 실행 (ex: Git push) | Webhook이나 주기적 빌드에 필요 |
when | 조건부 실행 (ex: 특정 브랜치일 때만 배포) | Stage 실행 제어할 때 필수 |
각각 부드럽게 예시도 들어줄게
1. environment
- 변수를 선언해서 어디서든 ${SERVICE_NAME}처럼 쓸 수 있어.
2. options
- 빌드가 너무 오래 걸리거나 잠깐 실패했을 때 다시 시도할 수 있게 해.
3. parameters
- 빌드할 때 사용자가 dev/stage/prod 중에 선택할 수 있어.
예를 들면:
"prod만 진짜 배포하고, dev는 그냥 테스트 빌드" 이런 분기 만들 수 있어!
4. tools
- Jenkins 서버에 설치된 Gradle, Maven 등을 자동으로 잡아줄 수 있어.
5. triggers
- GitHub에 Push 발생하면 자동으로 파이프라인 실행!
또는 스케줄링도 가능해:
6. when
- "main 브랜치에만 진짜 배포" 같은 조건 걸 수 있어.
실무에서는 이게 없으면 잘못해서 dev 브랜치에 배포해버리는 사고가 나기도 해.
'국비지원 (스파르타)' 카테고리의 다른 글
[학습] 젠킨스 (CI/CD) (2) | 2025.04.25 |
---|---|
[면접공부] - JPA (feat.gpt) (1) | 2025.04.24 |
[면접공부] - java, spring (feat.gpt) (1) | 2025.04.23 |
[면접공부] - db (feat.gpt) (4) (1) | 2025.04.18 |
[면접공부] - db (feat.gpt) (3) (0) | 2025.04.17 |