Jenkins를 이용한 CI/CD 파이프라인 구축 과정과 트러블슈팅
EC2 인스턴스에서 Jenkins를 이용한 CI/CD 파이프라인을 구축하는 과정에서 겪었던 문제들과 해결 방법에 대해 공유하고자 한다.
🚀 접근 방법과 목표
구축하고자 했던 CI/CD 파이프라인은 다음 단계로 구성되어 있다
- Build & Test: 코드를 빌드하고 테스트
- Docker Image Build & Push: ARM64 아키텍처용 Docker 이미지를 빌드하고 Docker Hub에 푸시
- Deploy: 빌드된 이미지를 실제 서버에 배포
이러한 파이프라인을 구축하기 위해 Jenkins를 선택했고, 초기에는 Docker 컨테이너로 Jenkins를 실행하는 방식을 선택
🔧 트러블슈팅 여정
1. Docker 컨테이너로 Jenkins 실행
처음에는 Docker 컨테이너로 Jenkins를 실행했다. EC2 인스턴스에 Docker를 설치하고, 다음 명령어로 Jenkins 컨테이너를 시작
docker run -d -p 8080:8080 -p 50000:50000 --name jenkins jenkins/jenkins:lts
초기 설정을 마치고 프로젝트를 추가한 후 빌드를 시도
2. JDK 버전 불일치 문제 발생
첫 번째 문제에 직면했다. 사용한 Jenkins 이미지는 JDK 11을 기본으로 사용하고 있었는데, 프로젝트는 Java 17로 개발되어 있었습니다.
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.UnsupportedClassVersionError:
has been compiled by a more recent version of the Java Runtime (class file version 61.0),
this version of the Java Runtime only recognizes class file versions up to 55.0
빌드 과정에서 위와 같은 오류가 발생했고, 이는 Java 17 프로젝트가 JDK 11에서 빌드될 수 없었기 때문
결국 이미지를 지우고 초기 설정을 다시 시작..
3. JDK 17 기반 Jenkins 이미지로 교체
이 문제를 해결하기 위해 JDK 17이 설치된 Jenkins 이미지를 사용하기로 결정
docker stop jenkins
docker rm jenkins
docker run -d -p 8080:8080 -p 50000:50000 --name jenkins jenkins/jenkins:jdk17
Jenkins 컨테이너를 다시 설정하고 프로젝트를 빌드했습니다. 이번에는 Java 컴파일 오류가 발생하지 않았다.
4. Docker in Docker 문제 발생
하지만 새로운 문제가 발생했습니다. CI/CD 파이프라인은 Docker 이미지를 빌드하고 Docker Hub에 푸시하는 단계를 포함하고 있는데
Docker 컨테이너 내부에서 Docker 명령어를 실행해야 하는 상황이 되었습니다 (Docker in Docker).
파이프라인 실행 중에 다음과 같은 오류가 발생
docker: command not found
또는
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
Docker in Docker는 설정이 복잡하고 보안 문제를 야기할 수 있다.
호스트의 Docker 소켓을 마운트하는 방식으로 해결할 수도 있지만, 이는 Jenkins 컨테이너에 호스트 시스템에 대한 과도한 권한을 부여하게 되기에 좋지 않은 방법이다..
5. 직접 Jenkins 설치로 해결
여러 방법을 시도해 본 후, 가장 간단하고 안정적인 해결책을 선택했습니다: EC2 인스턴스에 직접 Jenkins를 설치하는 것
sudo apt update
sudo apt install openjdk-17-jdk -y
curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | sudo tee /usr/share/keyrings/jenkins-keyring.asc > /dev/null
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian-stable binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list > /dev/null
sudo apt-get update
sudo apt-get install jenkins -y
sudo systemctl start jenkins
Jenkins를 직접 설치한 후, Docker도 동일한 호스트에 설치
sudo apt install docker.io -y
sudo usermod -aG docker jenkins
sudo systemctl restart jenkins
이제 Jenkins가 Docker 명령어를 사용할 수 있게 되었고, CI/CD 파이프라인이 원활하게 작동하기 시작
📝 결론 및 교훈
이 경험을 통해 몇 가지 중요한 교훈을 얻었다.
- 환경 호환성 확인: 프로젝트와 CI/CD 도구의 JDK 버전 등 환경 호환성을 미리 확인하는 것이 중요
- Docker in Docker의 복잡성: Docker 컨테이너 내에서 Docker를 사용하는 것은 생각보다 복잡할 수 있습니다. 특히 CI/CD 파이프라인을 구축할 때 이 점을 고려해야 한다.
- 단순한 해결책의 가치: 때로는 컨테이너화와 같은 고급 기술보다 직접 호스트에 서비스를 설치하는 것이 더 간단하고 효과적인 해결책이 될 수 있다...
이제 CI/CD 파이프라인은 안정적으로 다음 단계를 수행합니다:
- Build & Test: Java 17로 코드를 빌드하고 테스트
- Docker Image Build & Push: ARM64 아키텍처용 Docker 이미지를 빌드하고 Docker Hub에 푸시
- Deploy: 빌드된 이미지를 실제 서버에 배포
너무 도커에 의존하며 편하게 살려고 하면 더욱 더 낭패를 보게 된다.
반드시 .. 과정을 생각해보고 실행하자는 교훈을 얻게 되었다..
'DevOps' 카테고리의 다른 글
자자 AWS 인스턴스에서 Jenkins + DockerContainer 돌리기 드가자~ (0) | 2025.03.28 |
---|---|
젠킨스 서버가 죽었다.. (0) | 2025.03.28 |
개발 환경과 서버 환경의 아키텍처 일치성: 스프링 부트 관점에서 (0) | 2025.03.19 |
Github Action arm64 아키텍처로 ci/cd 구축하기 (0) | 2025.03.19 |