PREVIEW
이번 프로젝트에서 배포를 맡게되어 aws 인스턴스 생성 후 CI/CD 도구로 젠킨스를 선택했다
이유는 젠킨스가 무료이다보니 정보가 많다고 생각해서 선택을 했는데 하루종일 삽질을 하고 후회를 했고
젠킨스에서 만난 문제와 깃허브 액션을 선택한 이유에 대해 기록을 남겨보겠다.
AWS 인스턴스 생성하기
우선 AWS에서 OS를 선택할 때도 고민이 있었다.
Amazon Linux가 AWS에서 최적화되어 있기 때문에, 성능이나 보안 패치가 AWS에서 가장 빠르게 제공된다고 하여 처음에는 Amazon Linux를 선택했다.
하지만 인스턴스 생성 후 첫 명령어부터 내가 아는 명령어인 apt가 되지 않아 찾아보니 ubuntu랑 명령어가 달랐다.
그래서 생각한 게 배포를 진행하다가 막히면 구글링을 하게 될텐데 정보는 아마존 리눅스보다는 ubuntu가 더 많다고 생각하여 ubuntu를 선택하였다.
Docker 설치
CI/CD를 진행할 때 도커를 사용하여 진행할 거기 때문에 도커르 설치해준다.
sudo apt update
sudo apt install docker.io -y
sudo systemctl enable --now docker // 시스템 부팅 시 자동으로 도커 시작
sudo usermod -aG docker ubuntu // 현재 사용자를 Docker 그룹에 추가하여, sudo 없이 docker 명령어 실행
젠킨스 설치와 실행은 CI/CD 툴을 깃허브 액션으로 옮기기로 했기 때문에 따로 기록을 하진 않고,
CI/CD 툴로 Jenkin와, Github Actions중 고민하는 사람들을 위해 내가 겪은 상황을 공유를 해본다.
문제상황
우선 젠킨스 pipeline을 작성하야 배포를 진행하고 있었는데 Build 단계에서 무한로딩 후 서버가 다운되는 현상이 발생됐다.
pipeline {
agent any
environment {
DOCKER_HUB_USERNAME = 'jaew0n'
DOCKER_HUB_ACCESS_TOKEN = credentials('docker-hub-access-token') // Jenkins credentials plugin 사용
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Build') {
steps {
sh 'chmod +x gradlew'
sh './gradlew build'
}
}
stage('Docker Build & Push') {
steps {
script {
def imageName = "jaew0n/thiscoding"
def imageTag = "latest"
// Dockerfile 실행하여 도커 이미지 빌드
sh "docker build -t ${imageName}:${imageTag} ."
// 도커허브에 로그인
sh "echo ${DOCKER_HUB_ACCESS_TOKEN} | docker login -u ${DOCKER_HUB_USERNAME} --password-stdin"
// 도커 허브에 이미지 푸시
sh "docker push ${imageName}:${imageTag}"
}
}
}
stage('Deploy') {
steps {
script {
def imageName = "jaew0n/thiscoding"
def imageTag = "latest"
def containerName = "thiscoding-container"
// Docker Hub에서 최신 이미지 풀
sh "docker pull ${imageName}:${imageTag}"
// 기존 컨테이너가 있다면 종료하고 제거
sh "docker rm -f ${containerName} || true"
// 새 컨테이너 실행
sh """
docker run -d \
--name ${containerName} \
--restart unless-stopped \
-p 80:8080 \
-v thiscoding-data:/app/data \
-e SPRING_PROFILES_ACTIVE=prod \
${imageName}:${imageTag}
"""
// 배포 확인
sh "docker ps | grep ${containerName}"
}
}
}
}
}
처음에는 파이프라인에 문제가 있는 건가?? 하고 파이프라인을 계속 수정을 해보고 젠킨스 설정도 계속 수정을 했다.
하지만 ec2가 느려지고 젠킨스에서 빌드가 계속 무한로딩인 상황에서 단순하게 생각해보면 ec2의 자원이 부족한 것이다.
해결 과정
free -h 을 사용하여 자원 상황을 확인해봤다.
total used free shared buff/cache available
Mem : 957Mi 645Mi 72Mi 0.0Ki 238Mi 159Mi
Swap : 0B 0B 0B
위에 Mem 부분을 보면 총 967중 645를 사용하였고 72를 더 사용할 수 있다고 한다.
여기서 볼수 있듯 메모리 용량이 부족해서 빌드 멈춤 현상과 ec2 다운 현상이 계속 생겼던 거다.
그와 동시에 근데 밑에 보이는 Swap이 뭐지?란 생각이 들어서 찾아본 결과
Swap은 메모리가 부족할 때 사용되는 가상 메모리라고 한다.
이걸 안 순간 이제 드는 생각은 아~ Swap을 사용하면 빌드에 성공할 수도 있겠다 라는 생각이 들어
Swap 메모리를 확보하여 빌드를 해봤다.
다행히 빌드는 성공을 했지만 3분? 정도 걸렸다.
아마 배포가 처음이였다면 성공에 의미를 두고 다음 작업을 진행했겠지만
이전 프로젝트에서 NCP 무료 크레딧을 받아 배포를 진행했을 때 프로젝트 단순 배포는 1분도 안 걸렸던 경험이 있어 이건 문제가 있다고 판단되어 cpu 사양을 높히거나 깃허브 액션을 사용해야겠다 라는 고민이 생겻다.
Github Actions과 Jenkins
결국엔 두 개의 툴중 어떤 툴을 사용하냐는 고민을 많은 사람들이 할 것이다.
여기서 결과부터 말하자면 나는 깃허브 액션을 사용할 것이다.
깃허브액션 역시 퍼블릭 레포지토리는 무료로 이용할 수 있고 EC2 내부에 설치하지 않고 따로 구동되기 때문에
EC2에 젠킨스를 설치하여 진행할 때 EC2에서도 같이 부담하던 빌드단계와 도커 허브에 푸시하는 단계를 ec2가 부담하지 않게된다.
그리고 소나큐브도 사용할 거기 때문에 더더욱 EC2에서 사용하는 자원을 최소한으로 사용해야 한다.
마무리
이 글은 어떤 툴을 선택할 때 나처럼 작은 것만 보고 선택을 하는 일을 하지 않았으면 하는 마음에 작성한 글이다.
하지만 이렇게 부딛혀보지 않고 선택하게 되면 나중에 또 선택해야되는 상황에서 머리부터 아파올 것이다.
'개발' 카테고리의 다른 글
ec2 환경에서 도커 스크립트 작성 (0) | 2025.03.21 |
---|---|
OAuth2.0 로그인 정보 (1) | 2025.03.20 |
HandlerInterceptor 사용하여 권한체크 (0) | 2024.12.21 |
@JoinColumn의 name 속성과 referencedColumnName 속성의 기본 값 (2) | 2024.11.22 |
ansible 기본 실행 옵션 (1) | 2024.10.04 |