졸업 프로젝트로 개발한 OnePass는 CCNA 시험 대비를 위한 AI 기반의 문제 풀이 서비스 이다.
기본적으로 문제 풀이 기능을 제공한다. 공부의 효율성을 높이기 위해 사용자의 문제 풀이 기록을 분석하고, 문제들을 AI 기반으로 추출하여 사용자가 취약한 주제에 대한 핵심 키워드를 제공하는 것이 핵심이다.
아래는 자동화 작업 전의 배포 과정이다.
코드가 조금만 바뀌어도 동일한 배포 작업을 계속 반복해야 했기에 매우 비효율적이었다.
상당히 많은 시간이 소요되었고 사람이 하는 수작업인지라 배포 과정 중에 작은 실수라도 하면 처음부터 다시 작업해야 했다.
이러한 이유로 CI/CD의 필요성을 너무 느껴 구현하게 되었다.
개발자가 언제든 테스트를 진행할 수 있도록 24시간 가동하는 서버가 필요했다.
개인 컴퓨터를 24시간 켜 둘 수 없었고, 제가 서버를 확인할 수 없는 상황에 대비하여 팀원 모두가 쉽게 접근할 수 있는 클라우드 서비스를 선택했다.
사용한 서버는 AWS EC2와 GCP VM
AWS 프리티어 서버에 Jenkins를 설치해 자동 빌드하고, Docker로 컨테이너를 올려 자동 배포를 했으나 컨테이너가 3개 이상이 되면 CPU 사용량이 급격하게 높아지며 서버가 내려갔다...
Eureka에는 서비스가 살아있지만, 접속할 수 없는 것으로 보아 서비스 크기에 비해 서버 용량이 부족함을 알게되었다.
서버 성능과 용량을 미리 파악하지 못해 많이 헤맸다.
처음부터 잘하는 사람 없다 생각하며 스스로를 위로했다는^^...
필요한 툴을 설치하고, 모든 서비스들을 배포 시키기 위해선 큰 용량의 서버가 필요했지만 AWS 서버를 구입해 scale-up하기에는 금전적으로 부담이 됐다.
그래서 서버 작업을 분담하자는 결론을 내, scale-out을 선택했다.
서버A: 빌드 성공 시 Docker 이미지를 생성해 Docker Hub에 올리고 빌드 파일 삭제
서버B: 사용 중이던 이미지와 컨테이너 삭제 후 Docker Hub에서 새 이미지를 받아와 컨테이너 생성
데이터가 누적되지 않도록 삭제-생성을 반복하는 사이클을 만들었다.
큰 용량을 필요로 하지 않는 CI 서버는 AWS EC2를 사용했고, 약 7-8개의 서비스를 배포해야 하는 CD 서버는 90일간 300$의 크레딧을 제공해 주는 GCP를 사용했다.
최종 서버 구조이다.
자동 빌드 및 테스트 도구로 Jenkins를 사용했고, GitHub의 Webhook과 연동했다.
1) 개발자가 코드를 GitHub 저장소에 PUSH
2) Jenkins가 브랜치의 변동 사항을 자동으로 감지
3) Jenkins에서 자동 빌드 및 CI 서버 쉘 스크립트 실행
<Jenkins의 Execute Shell >
4) 빌드 된 파일 기반의 Docker 이미지 생성
5) 만든 Docker 이미지를 Docker Hub에 PUSH
6) CI 서버에 원격으로 접속해 CD 서버의 쉘 스크립트 실행 (배포)
< CI 서버의 쉘 스크립트 >
새로 생성한 Docker 이미지를 PUSH한 뒤 CD 서버에 원격으로 접속해 배포를 위한 단계를 진행한다.
개발자의 개입 없이 CI 서버에서 원격으로 접속해 실행된다.
1) 기존의 Docker 컨테이너 중지 및 삭제
2) 기존의 Docker 이미지 삭제
3) CI 서버에서 만든 새 이미지를 Docker Hub에서 PULL 받기
4) 새 이미지로 Docker 컨테이너 실행
CD 서버의 Shell scripts
이렇게 자동 빌드 및 테스트와 자동 배포가 완성되었다. 😊
사실 나의 첫 CI/CD 구현은 100% 만족스럽지 못했다. 자동 배포 시 오류가 발생하면 배포를 중단하고 이전에 배포했던 서비스를 실행해야 하는데 그러지 못했기때문이다.
다른 팀이었던 학우가 나에게 이런 말을 했었다.
"GitLab 같이 쉽고 빠르게 구현할 수 있는 방법이 있는데 왜 굳이 Jenkins를 사용하려고 해?"
요즘 CI/CD를 가능하게 해주는 좋은 툴들이 있다는 것은 이미 알고 있었다. 하지만 난 CI의 국룰(?) 이라고 할 수 있는 Jenkins를 꼭 사용하고 싶었고, 많은 기업에서 사용하고 있다는 얘기를 듣고 꼭! 경험해 보고 싶었다.
포기하지 않았던 내 고집 덕분에 잘 마무리할 수 있었다고 생각한다✌
이제 Jenkins의 기본 사용법 정도는 익힌 것 같으니 다음엔 다양한 플러그인들도 함께 사용해 보면 좋을 것 같다.