개요
우선 처음 사용해보고 느낀 점은 초기 셋팅할 때 햇갈린거만 빼면 생각보다 어렵지 않다는 것이다.
워낙 유명한 툴이다 보니 인터넷에 정보도 많고 다양한 플러그인과 GUI 덕분에 처음 사용해보는 사용자도
어려움 없이 사용할 수 있는거 같다. 물론 어느 정도 스크립트를 작성하긴 해야한다.
아마 이전에 Github Actions를 사용해본 사람이라면 스크립트를 짜는 것이 어렵진 않을거다.
CI/CD Pipeline
당장은 EC2 인스턴스는 Jenkins 서버용과 SpringBoot 서버용으로 두 개만 사용 중이고
프로젝트가 어느 정도 완성되어 가면 추후에 아키텍처를 수정할 생각이다.
Jenkins는 도커를 사용해 환경을 구성하는게 편해 해당 방식을 사용했고
이후에 도커 이미지 빌드와 푸쉬를 위해 Docker를 사용해야 하지만
Jenkins 컨테이너에 Docker를 또 설치하는 것은 비효율적이라
호스트의 도커 소켓을 컨테이너와 공유하여 사용하게 컨테이너를 띄웠다.
배포 서버는 도커만 설치하여 Jenkins에서 CD 작업을 수행할 때
새로운 이미지로 컨테이너를 띄울 수 있게 구성했다.
Jenkins Pipeline
프리스타일 프로젝트를 사용해서 간단하게 만들 수도 있지만 Pipeline 방식이 뭔가 더 끌려서
해당 방식을 사용하게 되었는데, 이전에 Github Actions를 사용해봐서 그런지 생각보다 익숙했다.
Github보다 환경 변수나 인증 정보들을 관리하기도 더 편리하고, 아직 많은 플러그인을 사용해보진 못했지만
도커 이미지를 관리하거나 배포 서버의 SSH에 접근하는 것이 좀 더 간결하게 가능한거 같다.
Webhook
사실 개인적으로 가장 마음에 들었던 것은 이 웹훅인데 레포지토리에서 특정 동작이 수행될 때
Jenkins 서버에 웹훅을 날리게 되고 이때 받는 정보들을 사용해 하나의 파이프라인으로
여러 상황에서 공통적으로 사용할 수 있다는게 Github Actions와 비교 했을 때 좋다 생각한다.
Github Actions는 작성한 워크플로우가 해당 레포지토리에만 적용이 되는데
Jenkins는 웹훅을 통해 얻는 정보로 브랜치나 레포지토리 단위로 재사용을 할 수 있다.
사용한 Pipeline 예제
pipeline {
environment {
DOCKERHUB_CREDENTIALS = credentials('docker_hub')
AWS_URL = '배포 서버의 EC2 IP'
}
agent any
stages {
stage('Checkout') {
steps {
git branch: 'main',
credentialsId: 'git_id',
url: '깃허브 레포지토리 주소'
}
}
stage('Test') {
steps {
dir('디렉토리가 다른 경우') {
sh "chmod +x ./gradlew"
sh "./gradlew clean test"
}
}
}
stage('Build') {
steps {
dir('디렉토리가 다른 경우') {
sh "chmod +x ./gradlew"
sh "./gradlew bootJar"
}
}
}
stage('JUnit') {
steps {
dir('디렉토리가 다른 경우') {
junit '**/build/test-results/test/*.xml'
}
}
}
stage('Docker Build and Push') {
steps {
dir('kko-kko-noodles') {
sh 'docker login -u $DOCKERHUB_CREDENTIALS_USR -p $DOCKERHUB_CREDENTIALS_PSW'
sh 'docker build -t 이미지명:$BUILD_NUMBER .'
sh 'docker push 이미지명:$BUILD_NUMBER'
sh "docker rmi 이미지명:$BUILD_NUMBER"
}
}
}
stage('Run'){
steps{
blueDeploy(AWS_URL)
}
}
}
}
def blueDeploy(awsUrl){
sshagent(['ec2_blue']) {
sh """
ssh -o StrictHostKeyChecking=no ubuntu@${awsUrl} '
docker login -u $DOCKERHUB_CREDENTIALS_USR -p $DOCKERHUB_CREDENTIALS_PSW
docker stop \$(docker ps -a -q)
docker rm \$(docker ps -a -q)
docker rmi \$(docker images -q)
docker pull 이미지명:$BUILD_NUMBER
docker run -d -p 80:8080 --name 컨테이너명 이미지명:$BUILD_NUMBER
'
"""
}
}
마치며
컨테이너를 잘못 만들어서 중간에 날리고 다시 만든 후에 19번 만에 마칠 수 있었는데
왜 벌써 해가 뜰 시간이 다가오는 것인지...