CI/CD의 필요성
프로젝트가 거의 완성이 되어가며 배포와 테스트 자동화의 필요성을 느꼈습니다. 이전에 했던 프로젝트는 직접 jar파일을 빌드한 후, FTP를 사용하여 서버에 올린 후 java -jar로 직접 실행시켰던 기억이 납니다. 자잘한 변경사항이 생긴다면 또다시 빌드 - 전송 - 직접 실행.. 을 반복해야 했죠. 서버에 올라간 후 문제가 없는지 직접 url을 기반으로 테스트까지 해야 했습니다. 했던 테스트를 또 반복하는게 상당히 귀찮은 일이였습니다.
최근 CI/CD의 개념을 배우며 위와 같은 귀찮은 문제를 쉽게 해결할 수 있다는 것을 알게 되었습니다. Github에 commit을 push하면 자동으로 소스코드를 통합하여주고, 배포까지 할 수 있는 편리한 툴이였죠. 바로 Jenkins였습니다. 이러한 툴이 있는걸 보니 저한테 귀찮은 일은 다른 개발자들에게도 귀찮은 일이였나봅니다.
Cloud Server 선택
Jenkins를 사용하겠다고 생각한 것 까지는 좋았습니다. 하지만 언제 어디서나 자동으로 통합, 배포를 하기 위해서는 24시간 돌아가는 저만의 서버가 필요했습니다. 컴퓨터를 항상 켜 놓을수는 없는 노릇이니 클라우드 서버를 사용해보기로 결정했습니다.
우선적으로 생각해 본 클라우드 서버는 AWS였습니다. 가장 유명하기도 했고 이전에 프리티어 EC2를 사용해본 경험이 있어서 익숙했기 때문입니다. 다만 제 프로젝트인 Delfood도 클라우드 서버에 배포할 예정이였기 때문에 비용 문제를 우선 생각해게 되었습니다. Delfood는 서버가 최소한 3대 이상(CI/CD서버, 메인 서버, DB서버) 필요했습니다. AWS에서 월단위 비용을 미리 계산해보니 학생인 저로서는 감당하기 어려운 금액이 필요했습니다.
그래서 Naver Cloud Platform(이하 Ncloud)를 사용해보기로 했습니다. 다른 점보다 우선 가입하면 10만원 상당의 크래딧을 사용할 수 있게 해주었기 때문에 보다 자유로운 서버 아키텍처를 선택할 수 있었기 때문입니다.
가입하며 받은 10만크래딧은 실제로 서비스를 진행할 때 사용하기로 하고 무료로 사용할 수 있는 마이크로 서버를 사용하여 Jenkins 서버를 구현하기로 했습니다.
Jenkins로 CI와 자동 테스트 구현
소스코드의 Commit시 즉시 서버에서 통합되는 것을 원했습니다. 그렇기 때문에 구글링을 통해 Github에서 Jenkins 서버로 hook을 날리는 방법을 찾아 설정하였습니다.
Jenkins에서는 hook을 받으면 즉시 maven의 clean, test, package를 진행하도록 설정하였습니다. JUnit을 이용해 작성한 테스트코드들이 Jenkins에서 돌아가다가 실패하면 언제든 제 메일로 알림을 줄 수 있도록 SMTP포트를 열고 관련 플러그인을 설정해두었습니다.
실제로 개발한 소스코드를 commit하니 자동으로 빌도가 시작되었고, 초반에는 설정문제인지 자꾸 빌드가 실패했습니다. 각종 옵션들을 바꿔보고, Profile에 따라 변경되는 파라미터도 주며 결국 자동으로 CI를 성공시켰습니다.
구현한 Jenkins 서버는 http://106.10.51.119:8080/job/Delfood/ 에서 누구나 열람할 수 있습니다.
Shell script와 Docker를 사용하여 CD까지 구현
지속적으로 소스코드를 통합하는 것 까지는 쉬웠지만 생성된 jar파일을 메인 서버로 옮겨야했고, 각종 파라미터 도 같이 실행시켜야 했습니다. 메인 서버와 실행되는 환경이 바뀐다면 오류가 날 가능성도 있었습니다.
그렇기 때문에 Delfood를 Docker 이미지로 생성하여 OS 환경에 종속적이지 않을 수 있도록 만들기로 했습니다. Docker에서 jdk-8버전이 있는 베이스 이미지를 jenkins서버에 설치하였고 jenkins 빌드가 종료될 때 이 베이스패키지에 delfood 프로젝트를 올려 이미지로 빌드하도록 스크립트를 작성하였습니다.
도커 이미지 작성이 끝난다면 docker hub에 저장하고, 메인 서버에 있는 스크립트를 실행하면 자동으로 이미지를 다운로드받고 실행할 수 있도록 하였습니다.
echo "copy jar to /home/delfood/docker/"
cp /var/lib/jenkins/.m2/repository/com/delfood/food-delivery/0.0.1-SNAPSHOT/food-delivery-0.0.1-SNAPSHOT.jar /home/delfood/docker/delfood.jar
cd /home/delfood/docker
echo "build docker image.."
docker build --tag yyy9942/delfood:0.1 ./
echo "delfood build success"
echo "docker push..."
docker push yyy9942/delfood:0.1
echo "push finished"
echo "ssh script start..."
ssh root@10.41.3.239 sh /home/delfood/scripts.sh
스크립트 작성을 완료하기까지 jenkins의 권한, ssh로 원격 스크립트 로그인 없이 실행하기 등 여러 이슈가 있었습니다.
해당 스크립트는 jenkins가 실행하기 때문에 jenkins로 ssh 연결을 하기 위해 key 파일을 메인 서버에 등록하고, 각종 디렉토리에 접근할 수 있는 권한을 주는 등 생각보다 쉬운 일이 아니였습니다.
자동 CI/CD의 완성
며칠에 걸친 수 많은 삽질과 공부로 결국은 자동화된 CI/CD에 성공할 수 있었습니다. 메인 어플리케이션 서버를 구축하고 서버 아키텍처를 설계하여 실제 서버 배포도 완료할 수 있었습니다. 이렇게 제 Delfood 프로젝트는 1차 배포를 완료하게 되었습니다.
실제 적용한 서버 구조는 다음과 같습니다.
'Project > DelFood' 카테고리의 다른 글
[DelFood] Ngrinder로 진행한 성능 테스트 (0) | 2020.02.13 |
---|---|
[이슈 #10] 푸시 메세지를 비동기로 처리하여 성능 개선하기 (3) | 2019.12.31 |
[이슈 #9] Mybatis <collection> 태그 N+1 문제 없이 사용하기 (4) | 2019.12.18 |
[이슈 #8] 1:N:M 관계 INSERT 시 N + M번의 쿼리 발생을 리팩토링하기 (1) | 2019.12.18 |
[이슈 #7] 서버 부하를 줄이기 위한 캐싱 적용 (0) | 2019.11.21 |
댓글