앞서 공부한 CI/CD 개념과 Jenkins를 사용하여 CI/CD를 위한 Jenkins Pipeline을 단계적으로 구현해볼것이다. 처음이라 많이 부족한거 같다🤣
Jenkins Pipeline을 크게 아래와 같이 설계해보았다.
Prepare:git clone
-> Build:Gradle
-> Test:프로젝트에 작성해논 단위,통합 테스트
-> Deploy:AWS EC2 서버 배포
추가적으로 Github Webhooks
를 이용한 빌드 유발로 Jenkins의 Pipeline의 시작점이 시작되도록 연결해보았다.
Jenkins가 나 대신 공유 레포지토리에서 git clone을 하려면 해당 공유 레포지토리에 대한 접근 권한이 필요하다.
Jenkins Credential에 필요한 리소스 private key들을 등록한후 추후 사용하는 것이 안전하기 때문에 Credentials에 등록해보았다.
github 엑세스 토큰 발급은 검색을 하게 되면 상세히 쉽게 찾아볼수 있기 때문에 발급 부분은 넘어가도록 하겠다.
기본적으로 엑세스 토큰의 유효 기간을 무한대로 설정해놓았다. 또한 엑세스 토큰을 한번 발급하면 잊어버렸을 경우 찾을수 없기 때문에 따로 저장해두는것이 좋다.
이렇게 발급한 엑세스 토큰을 Jenkins Credentials에 kind:Username with password, ID: 추후 Jenkins에서 사용될 key이름으로 설정하여 아래와 같이 등록하였다.
또한 이렇게 등록한 엑세스 토큰을 생성한 Pipeline Project의 Script에 아래와 같이 작성하였다.
pipeline {
agent any
stages {
stage('Prepare') {
agent any
steps {
git branch: 'main',
credentialsId: 'github_access_token',
url: 'https://github.com/YNCB/backEnd.git'
}
post {
failure{
error "Fail Cloned Repository"
}
}
}
}
git clone을 받아올 uri
와 branch
을 적고 앞서 등록한 credentialsId
를 적는다.
PostSections
은 앞에 Steps
가 종료되고 실행하게 되는데 만약 실패시 failure
가 실행하게 되고 error
옵션을 통해 뒤의 작업들을 실행시키지 않고 종료되도록 작성하였다.
또한 Script를 작성할때 Pipeline Syntax를 기능을 이용하면 자동으로 스크립트를 완성해주어 편하게 사용할수 있다.
webhooks이란?
특정 이벤트(git push,commit등)가 발생하였을때 서비스나 응용프로그램으로 알림을 보내주는 기능이다.
웹훅을 사용하지 않으면 깃허브 공유 레포지토리에 업데이트가 발생하였는지 직접 주기적으로 확인을 하여야 된다. 웹훅을 사용하게 되면 깃허브의 변경사항을 Jenkins에게 알람을 보내주기 때문에 직접 레포지토리의 변경사항을 주기적으로 확인할 필요가 없어진다.
github webhooks
를 사용하여 특정 이벤트를 감지하게 되면 Jenkins Pipeline의 시작점으로 연결시켜 시작하도록 추가하였다.
ngrok
어플리케이션을 사용하여 외부에서 접근할수 있는 도메인을 사용하였다.추가적으로 Jenkins Pipeline project에 아래와 같이 체크를 한다.
그렇게 되면 github에 이벤트가 발생하였을때 jenkins에 설정한 github 레포지토리와 일치하는지 확인한후 일치하다면 pipeline의 Script를 실행하게 된다.
jenkins
가 프로젝트를 build,Test하기 위해서는 프로젝트에 해당하는 빌드 도구들을 설정해두어야된다.
해당 프로젝트는 Springboot를 이용하였고 Springboot는 JDK기반이기 때문에 JDK설정과
빌드 도구인 Gradle을 Jenkins Global Tool Confituration에 등록해줘야된다.
Jenkins 자체에서 필요한 JDK를 다운받을수 있도록 설정할수도 있지만 이미 PC에 JDK가 있기 때문에 JDK 경로를 설정해두었다.
빌드 도구로 사용될 Gradle은 Gradle Plugin을 먼저 설치한후 설치한 Gradle의 설정에서 사용할 버전을 선택하였다.
pipeline {
agent any
stages {
stage('Prepare') {
agent any
steps {
git branch: 'main',
credentialsId: 'github_access_token',
url: 'https://github.com/YNCB/backEnd.git'
}
post {
failure{
error "Fail Cloned Repository"
}
}
}
stage('Build') {
agent any
steps{
bat '''
echo 'start bootJar'
./gradlew clean bootJar
'''
}
post{
failure{
error 'Fail Build'
}
}
}
}
}
빌드는 앞서 레포지토리에서 clone해오 소스코드에 포함되어있는 gradlew wrapper를 활용하였다.
bootJar명령어를 사용하여 소스코드의 .jar
파일을 만들었다.
현재 Jenkins server를 로컬에서 실행시키고 로컬은 Microsoft이기 때문에 Script를 실행하기 위해 bat를 사용하였다.
다음시간에는 Docker를 공부한후 프로젝트에 적용할 예정이다. Docker를 이용하여 프로젝트,jenkins를 뛰울때는 sh명령어를 사용하면된다.(Linux서버이기 때문에)
얼른 Docker를 공부해야겠다.🤣
또한 Build 실패시 Post Sections을 통해 종료되도록 하였다.
pipeline {
agent any
stages {
stage('Prepare') {
agent any
steps {
git branch: 'main',
credentialsId: 'github_access_token',
url: 'https://github.com/YNCB/backEnd.git'
}
post {
failure{
error "Fail Cloned Repository"
}
}
}
stage('Build') {
agent any
steps{
bat '''
echo 'start bootJar'
./gradlew clean bootJar
'''
}
post{
failure{
error 'Fail Build'
}
}
}
stage('Test') {
agent any
steps{
withGradle{
bat './gradlew test'
}
}
post{
failure{
error 'Fail Test'
}
}
}
}
}
별 차이 없이 Gradle wapper를 이용하여 프로젝트에 작성해논 단위, 통합 테스트들이 실행되도록 스크립트 job으로 추가하였다.
build, test가 마친후 Jenkins에서 빌드한 jar파일을 배포 서버인 AWS EC2에 전달해야 된다.
Jenkins plugin중 publish over ssh 플러그인
을 사용하여 해보았다.
먼저 플러그인을 설치한후 ssh을 통해 파일을 보내기전 pem키의 정보를 등록해야된다.
key로 AWS EC2의 pem키를 넣어준다.
Pipeline Syntax의 sshPublisher simple step 이용하여 Script를 만들어보았다.
pipeline {
agent any
stages {
stage('Prepare') {
agent any
steps {
git branch: 'main',
credentialsId: 'github_access_token',
url: 'https://github.com/YNCB/backEnd.git'
}
post {
failure{
error "Fail Cloned Repository"
}
}
}
stage('Build') {
agent any
steps{
bat '''
echo 'start bootJar'
./gradlew clean bootJar
'''
}
post{
failure{
error 'Fail Build'
}
}
}
stage('Test') {
agent any
steps{
withGradle{
bat './gradlew test'
}
}
post{
failure{
error 'Fail Test'
}
}
}
stage('Deploy'){
agent any
steps{
sshPublisher(
publishers:
[
sshPublisherDesc(
configName: 'deploy-server',
transfers:
[
sshTransfer(
cleanRemote: false,
excludes: '',
execCommand: 'sh /home/ubuntu/start_server.sh',
execTimeout: 120000,
flatten: false,
makeEmptyDirs: false,
noDefaultExcludes: false,
patternSeparator: '[, ]+',
remoteDirectory: '/deploy3',
remoteDirectorySDF: false,
removePrefix: 'build/libs',
sourceFiles: 'build/libs/*.jar')],
usePromotionTimestamp: false,
useWorkspaceInPromotion: false,
verbose: true
)
]
)
}
post{
failure{
error 'Fail Deploy'
}
}
}
}
}
build/libs/
에 위치하므로 sourceFiles를 build/libs/*jar
로 작성하였다.shell명령어
를 execCommand에 작성해두었다.
start_server.sh
쉘은 미리 EC2 서버에 정의해둔 파일이다. 간단하게 살펴보겠다.
현재 실행하고 있는.jar
프로세스를 종료한후 배포를 마친 디렉토리에서 새로운.jar
파일을 백그라운드로 실행하는 스크립트이다. 추가로 log도 설정해둔 모습이다.
현재는 단순히 CI/CD를 위해서 Jenkins를 사용하여 pipeline에 맞게 구현해보았다. 다음시간에 Docker를 사용하여 가상컨테이너 환경을 만들어본후 무중단 배포까지 되도록 공부한후 구현해 볼 예정이다.
공부 많이 해야겠다.🤣
참고자료 : https://sihyung92.oopy.io/e5300d92-1a4e-40f4-b927-a93b2bbb17d2