Jenkins Pipeline 으로 빌드하고 배포하기
Jenkins pipeline 으로 빌드하고 배포하기
젠킨스 세팅하고 웹훅 설정하기 의 다음 포스팅으로 이전 작업을 먼저 진행해주셔야 이번 포스팅 따라하기가 원할합니다.
pipeline 방식
Jenkins pipeline 은 배포과정을 자동화하는 일련의 단계를 정의한 워크플로우입니다. groovy 언어로 작성하고,이전 step 이 완료되어야 다음 step 이 실행되어 빌드, 테스트 등 여러 작업을 순차적으로 실행할 수 있습니다.
파이프 라인을 Declarative Pipeline과 Scripted Pipeline 두가지 방식으로 작성할 수 있습니다.
Declarative Pipeline
Declarative Pipeline 은 yaml 과 비슷한 방식으로, 구조가 명확하고 읽고 쓰기 쉽습니다.
또한 Declarative Pipeline 은 groovy 언어를 기반으로 하지만, 젠킨스 파이프라인을 정의할 때는 필요한 필수적인 구문만 구조를 미리 정해둔 형태로 사용합니다.
pipeline {
agent any
stages {
stage('Build') {
steps {
sh './gradlew clean build'
}
}
stage('Test') {
steps {
sh './gradlew test'
}
}
stage('Deploy') {
steps {
sh 'scp my-app user@server:/path/to/deploy'
}
}
}
}
Scripted Pipeline
Scripted Pipeline 는 groovy 언어를 전체를 사용하여 복잡한 로직을 유연하게 구현할 수 있습니다.
node {
stage('Build') {
sh './gradlew clean build'
}
stage('Test') {
sh './gradlew test'
}
stage('Deploy') {
sh 'scp my-app user@server:/path/to/deploy'
}
}
Pipeline 작성하기
파이프라인은 Declarative Pipeline 방식으로 작성해보겠습니다.
pipeline {
agent any
environment {
JAR_NAME = 'echoeco-0.0.1-SNAPSHOT.jar'
CONFIG_CREDENTIAL_ID = 'application-prod-properties'
CONFIG_CREDENTIAL_TEST_ID = 'application-test-properties'
}
stages {
stage('Cleanup Workspace') {
steps {
deleteDir()
}
}
stage('Clone Repository') {
steps {
git branch: 'master',
url: 'https://github.com/swyp-lucky7/echo-eco.git'
}
}
stage('Create Config in workspace') {
steps {
withCredentials([file(credentialsId: CONFIG_CREDENTIAL_ID, variable: 'CONFIG_FILE')]) {
sh "cp $CONFIG_FILE ${WORKSPACE}/src/main/resources/application-prod.properties"
}
withCredentials([file(credentialsId: CONFIG_CREDENTIAL_TEST_ID, variable: 'CONFIG_FILE')]) {
sh "cp $CONFIG_FILE ${WORKSPACE}/src/test/resources/application-test.properties"
}
}
}
stage('Build') {
steps {
sh './gradlew clean build'
}
}
stage('Deploy') {
steps {
script {
// 파일 전송 및 명령 실행
sshPublisher(
failOnError: true,
publishers: [
sshPublisherDesc(
configName: 'ec2 server',
verbose: true,
transfers: [
sshTransfer(
cleanRemote:false,
sourceFiles: 'build/libs/echoeco-0.0.1-SNAPSHOT.jar',
removePrefix: 'build/libs',
remoteDirectory: '/project/deploy/'
),
sshTransfer(
execCommand: 'bash /home/ec2-user/project/deploy/deploy.sh'
)
]
)
]
)
}
}
}
}
post {
always {
archiveArtifacts artifacts: '**/build/libs/*.jar', allowEmptyArchive: true
junit 'build/test-results/**/*.xml'
}
}
}
먼저 environment 를 보시면 CONFIG_CREDENTIAL_ID, CONFIG_CREDENTIAL_TEST_ID 가 있는데 젠킨스 global setting 값으로 바로 뒤에 서술할 예정입니다.
- Cleanup Workspace
- deleteDir 함수는 기존 workspace [ ex) /home/ec2-user/project/docker/jenkins/data/workspace/echo-eco-v2 ] 폴더 내부를 초기화 해주는 함수입니다.
- Clone Repository
- 깃 프로젝트와 연결하는 지점이며, 해당 깃 프로젝트에서 master 브랜치로 git clone 명령어를 사용하는 부분입니다.
- Create Config in workspace
- 우리가 다운로드 받은 프로젝트에는 config 파일의 중요한 정보때문에 config 파일이 프로젝트에 들어가있지 않습니다. ( gitignore 로 제외 ) 따라서 그 파일을 직접 넣어주는 부분입니다.
- Build
- gradlew 을 사용해서 Build 하는 부분입니다.
- clean 옵션을 사용하면 build 폴더가 삭제됩니다
- 위에서 deleteDir 함수를 이용했기 때문에 이 옵션을 삭제하고 진행해도 아무 이상없습니다.
- Deploy
- ssh 를 통해서 파일을 서버로 옮기고, 배포까지 하는 방식입니다.
- 밑에서 자세히 서술할 예정입니다.
환경설정하기
위에서 언급했듯이 깃 프로젝트를 다운로드 받았을때 프로젝트에서 gitignore 를 사용해서 제외시켰기에 중요한 파일들이 없습니다.
그래서 빌드하기전에 미리 중요한 파일들을 넣어줘야 합니다.
Jenkins 관리 > Credentials 를 눌러줍니다.
그다음 global 을 눌러줍니다.
그 다음 Add Credentials 버튼을 눌러줍니다.
- Kind
- Secret file
- File
- 사용할 파일
- ID
- 파이프라인에서 사용할 이름 ( CONFIG_CREDENTIAL_ID )
그 다음 Create 버튼을 눌러 저장해줍니다.
아까 파이프라인을 참조해 이름을 변경해 사용하시면 됩니다.
배포 스크립트 작성하기
배포 스크립트는 젠킨스에서 ssh 를 통해 서버와 연결하고 스크립트를 실행시켜 서버가 해당 스크립트를 직접 실행시키도록 하기 위해 작성하는 것입니다.
배포 스크립트를 작성하기 전에 먼저 폴더를 만들어 보겠습니다.
$ cd ~/project
$ mkdir -m 755 deploy
저의 경우 project 하위에 만들었으며, 폴더를 만듦과 동시에 권한을 부여해주었습니다.
그 다음 다음 명령어를 입력해 deploy.sh 스크립트를 만들어보겠습니다.
$ vi deploy.sh
위 명령어를 입력하면 vi 창이 나올텐데 밑의 명령어를 복사 붙혀 넣기합니다.
echo "start deploy.sh"
pkill -f "java -jar" || true # 기존 애플리케이션 종료
if [ $? -eq 0 ]; then
echo "old application stopped successfully"
else
echo "Failed to stop the old application" >&2
fi
nohup java -jar /home/ec2-user/project/deploy/echoeco-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod > /dev/null 2>&1 &
if [ $? -eq 0 ]; then
echo "New application started successfully"
else
echo "Failed to start the new application" >&2
exit 1
fi
echo "Deployment finished"
pkill -f "java -jar" || true
- 기존 서버에 떠 있는 프로젝트를 종료시키는 역할입니다.
|| true
옵션을 사용해서 종료할 프로젝트가 없더라도 0 을 반환합니다.
nohup java -jar /home/ec2-user/project/deploy/echoeco-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod > /dev/null 2>&1 &
- nohup
- no hang up 의 줄임말로, ssh 가 종료되어도 해당 프로세스를 계속 실행시킬때 사용합니다.
- java -jar /home/ec2-user/project/deploy/echoeco-0.0.1-SNAPSHOT.jar
- Java 애플리케이션을 실행할 때 사용하는 명령어입니다.
- –spring.profiles.active=prod
- profile 을 prod 로 설정하는 부분입니다. prod 로 설정되어 있으면 application-prod.properties 를 읽을 수 있습니다.
- > /dev/null
- 표준 출력은 리디렉션하는 명령입니다. /dev/null 은 아무것도 기록하지 않는 특수 파일로, 출력 내용을 무시하고 삭제합니다.
- 따라서 아무것도 기록하지 않겠다는 명령어입니다.
- 2>&1
- 2 는 표준 오류 출력을 의미하고, 2>&1는 표준 오류출력을 1(표준 출력) 으로 리디렉션하는 명령어입니다.
- 따라서 오류 출력도 기록하지 않겠다는 명령어입니다.
- &
- 명령을 백그라운드에서 실행시켜라는 명령어입니다.
- 터미널이 제어권을 가지게되고, 사용자가 다른 작업을 할 수 있습니다.
- nohup
$? -eq 0
- 리눅스에서 $? 는 직전에 사용된 명령어의 종료 상태를 의미합니다.
- -eq 는 == 으로 같은지 확인합니다.
- 0 은 성공했을 때 반환하는 응답값입니다.
- 정리하면 이전 명령이 성공이 되었는지 확인하는 명령어입니다.
웹서버로 젠킨스 SSH 세팅하기
해야 할 작업은 젠킨스가 웹 서버에 접근할 수 있도록 ssh key 를 발급하고, 서버에 pub 을 등록하는 부분입니다.
그리고 젠킨스에서 ssh 플러그인을 설치하고, 설정에서 젠킨스가 웹 서버로 접근할 수 있도록 등록해야 합니다.
먼저, jenkins 서버에 접근합니다.
저의 경우 docker 로 실행시키고 있기때문에 다음 명령어로 접근하였습니다.
docker exec -it jenkins-master /bin/bash
그 다음에 .ssh 폴더를 만들어주고, 다음 명령어를 통해 ssh key 를 만들어줍니다.
$ mkdir -m 755 .ssh
$ cd .ssh/
$ ssh-keygen -t rsa -b 4096 -C "deploy-key-for-ec2"
위 명령어를 입력하면 어떻게 파일을 저장할지 나오는데 저는 .ssh 폴더안에 deploy-key-for-ec2 라는 이름으로 사용했습니다.
참고로 id_rsa 가 기본값입니다. 만약 기본값을 사용하지 않으면 ssh 접근시 -i 옵션으로 이름을 직접 입력해줘야 합니다.
비밀번호는 입력하지 않고 바로 엔터, 엔터로 만들어줍니다.
비밀번호를 입력하면 접속할때마다 비밀번호를 입력해줘야하는 불편함이 존재하고, 젠킨스 서버가 해킹당하지 않는한 안전합니다.
$ cat deploy-key-for-ec2.pub
cat 명령어를 통해 공개키를 복사합니다. 참고로 공개키에서 ssh-rsa 부터 deploy-key-for-ec2 까지 모두 복사해주시면 됩니다.
이제 웹 서버( ec2 ) 로 넘어가줍니다.
$ exit
저의 경우 docker 로 접근해 있음으로 간단하게 exit 명령어로 나와줍니다.
$ echo <위에서 복사한 공개키> >> ~/.ssh/authorized_keys
그 다음 복사한 공개키를 authorized_keys 에 등록해줍니다.
authorized_keys 에 등록하는 이유는 간단하게 설명해서 개인키로 서명(암호화)한 것을 등록한 공개키로 복호화할때 사용하기 위함입니다.
다 등록이 되었으면 젠킨스에서 ssh 로 웹서버에 들어가봅니다.
$ ssh -i deploy-key-for-ec2 ec2-user@ec2-<ip 주소>-ap-northeast-2.compute.amazonaws.com
참고로 처음 들어가는 거면 known_list 가 아니라서 Are you sure you want to ~
이렇게 뜨는데 yes
를 입력해주시면 됩니다.
그럼 다음과 같이 ec2 에 연결된 것이 보이는데 이렇게 되면 성공적으로 끝난 것 입니다.
젠킨스에서 SSH Server 설정하기
플러그인 설치하기
Jenkins 관리 > Plugins 를 눌러줍니다.
Available plugins > Publish Over ssh 검색 후 설치해줍니다.
저는 이미 설치되어 있기때문에 위처럼 Installed plugins 에 있습니다.
SSH Server 세팅하기
Jenkins 관리 > System 을 눌러줍니다.
ssh server 파트에서 추가 버튼을 누르면 위 화면이 뜨는데 다음과 같이 설정해주시면 됩니다.
- Name
- 이 부분은 파이프라인에서 입력한 configName 과 일치해야 합니다.
- Hostname
- hostname 은 ssh 접근할때 사용하는 ip 주소를 입력해주시면 됩니다.
- Username
- ssh 접근할때 사용할 유저를 입력해주시면 됩니다.
그 다음 고급을 눌러 다음과 key 의 경로를 입력해줍니다. ( key 에 직접 입력해도 됩니다. )
그리고 Test Configuration 버튼을 눌러 Success 가 나오는지 확인해줍니다.
그리고 저장을 눌러줍니다.
테스트하기
긴 설정이 끝났습니다!! 따라오느라 고생많으셨습니다.
이제 모든 설정이 끝났음으로 자동으로 CD (Continous Deploy) 가 되는지 확인해야 합니다.
master 에서 commit 을 남깁니다.
그럼 웹훅을 통해 자동으로 빌드가 되는 것을 확인할 수 있습니다
빌드가 다되면 밑에 #숫자 를 눌러 detail 로 들어가줍니다.
그 다음 Console output 을 누르면 다음과 같이 정상적으로 잘 작동하고 있는 것을 볼 수 있습니다.
그리고 보시면 ssh 로 파일을 잘 전달하는 것을 볼 수 있습니다.
그리고 명령이 잘 실행이 되었고 다음 명령어로 서버가 잘 띄어져 있는지 확인할 수 있습니다.
$ lsof -i :8080
or
$ ps aux | grep "java -jar"
Leave a comment