앞서 구축한 infra 서버를 바탕으로 본격적으로 ci/cd 구축을 시작하자.
Jenkins에서 하나의 ci/cd를 구축하기 위해서는 하나의 아이템(item)을 생성해야 한다.
하나의 jenkins 서버에는 여러개의 item을 만들 수 있고, 각각의 item은 설정에 따라 다르게 동작한다.
펀잇은 jenkins의 item을 만들기 위해 Pipeline
방식을 사용했다.
pipeline : script파일에 코드를 작성해 item을 관리할 수 있다.
jenkins에 접속해 '새로운 item'을 클릭한다.
item 이름을 지정해주고 pipeline 방식을 선택한다.
item을 생성하면 자동으로 설정 페이지로 이동한다.
스크롤을 쭉 내려서 pipeline 파트를 보자.
이곳에서 pipeline의 script를 작성할 수 있다.
일단 전체 ci/cd script는 다음과 같다.
pipeline {
agent any
tools {
gradle 'gradle'
}
stages {
stage('Git Clone') {
steps {
git branch: 'develop', url: {git url}
}
}
stage('Build') {
steps {
dir("./backend") {
sh "./gradlew clean build"
}
}
}
stage('Deploy') {
steps {
sshagent(credentials: ['aws-key']) {
sh '''
ls
pwd
ssh -o StrictHostKeyChecking=no ubuntu@{개발서버ip} uptime
scp /var/jenkins_home/workspace/{item이름}/backend/build/libs/funeat-0.0.1-SNAPSHOT.jar ubuntu@{개발서버ip}:/home/ubuntu/funeat
ssh -t ubuntu@{개발서버ip} ./deploy.sh
'''
}
}
}
}
}
각 stage 별로 살펴보자.
stage('Git Clone') {
steps {
git branch: 'develop', url: {git url}
}
}
Git에 올라가있는 프로젝트의 develop
브랜치를 clone한다.
stage('Build') {
steps {
dir("./backend") {
sh "./gradlew clean build"
}
}
}
clone한 프로젝트의 backend
디렉터리로 이동 후 프로젝트를 빌드한다.
여기까지 하면 CI 구축은 끝이난다 👏
마지막 스테이지인 Deploy를 위해서는 몇가지 설정이 필요하다 ⚠️
설정 후에 다시 Deploy 스테이지를 살펴보도록 하겠다.
Jenkins가 설치된 infra 서버에서 스프링 어플리케이션이 실행될 develop 서버에 접속하기 위해서는
다양한 SSH plugin을 사용할 수 있다.
펀잇은 그중 SSH Agent
라는 플러그인을 사용했다.
☁️ Jenkins 관리 → Plugins → Available plugins에서 SSH Agent를 검색해서 설치할 수 있다.
우리가 개인 pc에서 ec2에 접속할 때 ssh -i {pem키} ubuntu@{ec2의ip}
로 접근했던 것처럼,
infra서버(Jenkins)에서 develop서버로 접속하기 위해서도 pem 키
가 필요하다.
☁️ Jenkins관리 → Credentials
☁️ Stores scoped to Jenkins → System
☁️ Global credentials (unrestricted) → Add Credentials
cat {pem키}
를 통해 나오는 값을 BEGIN~END까지 모두 입력다시 script로 돌아와 Deploy 스테이지를 살펴보자.
stage('Deploy') {
steps {
sshagent(credentials: ['aws-key']) {
sh '''
ls
pwd
ssh -o StrictHostKeyChecking=no ubuntu@{개발서버ip} uptime
scp /var/jenkins_home/workspace/{item이름}/backend/build/libs/funeat-0.0.1-SNAPSHOT.jar ubuntu@{개발서버ip}:/home/ubuntu/funeat
ssh -t ubuntu@{개발서버ip} ./deploy.sh
'''
}
}
}
develop 서버로 배포하기 위해 sshagent 플러그인을 사용한다.
우리가 jenkins에 설정해둔 credentials중 'aws-key'라는 키를 사용해 접근한다.
infra 서버에서 develop 서버에 접근할 수 있도록 StrictHostKeyChecking을 no로 설정한다.
그리고 scp
명령어를 통해 infra 서버에 빌드된 jar파일을 develop서버에 전송한다.
scp란?
- ssh를 이용하여 네트워크로 연결된 호스트간에 파일을 주고받는 명령어
- 원격지에 있는 파일과 디렉터리를 보내거나 가져올 때 사용하는 파일 전송 프로토콜
마지막으로 develop 서버에 있는 deploy.sh 파일을 작동해 빌드된 jar 파일을 실행시킨다.
참고로 우리팀의 deploy.sh
파일은 다음과 같다.
#!/bin/bash
pid=$(pgrep -f funeat)
if [ -n "${pid}" ]
then
kill -15 ${pid}
echo kill process ${pid}
else
echo no process
fi
chmod +x ./funeat/funeat-0.0.1-SNAPSHOT.jar
nohup java -jar ./funeat/funeat-0.0.1-SNAPSHOT.jar >> application.log 2> /dev/null &
여기까지 하면 CD도 완료!! 👏
Jenkins를 이용한 CI/CD pipeline 만들기는 끝이 났다!
하지만 지금 상태에서는 사용자가 직접 jenkins 웹에 접속하여 지금 빌드
를 눌러야만 해당 pipeline이 실행된다..
이제 정말 마지막으로
Github의 Webhook
기능을 이용하여 develop branch에 뭔가가 merge되었을 때 자동으로 pipeline이 실행되도록 설정해보자.
☁️ 프로젝트 repository → Settings → Webhooks
Add Webhook
을 클릭한다.
https://{젠킨스 url}/github-webhook/
application/json
또한 Which events would you like to trigger this webhook?는
펀잇의 경우 develop브랜치에 push(merge)되었을 경우에만 pipeline을 발동시킬 것이기 때문에
Just the push event
로 설정했다.
☁️ Configuration → General → Build Triggers
GitHub hook trigger for GITScm polling
을 체크한다.
해당 옵션을 통해 github에서 webhook이 왔을 때 자동으로 pipeline이 실행된다.
이제 펀잇팀의 작업은 pr이 merge될 때마다 테스트, 빌드를 거쳐 배포까지 자동으로 진행된다 😋
또한 jenkins 웹에 접속하여 밑의 이미지처럼 한눈에 pipeline 진행상황을 확인할 수 있다!