서론
2025년이 되었다. Leets 에서 가치택시라는 새로운 프로젝트를 진행중이다
프로젝트의 구상은 가천대학교 학생들 대상으로 AI 공학관 또는 기숙사까지 택시를 공유해서 탑승할 수 있는 서비스를 출시하고자 하는 것이였다.

위 사진을 보면 알 수 있듯이, 네이버 지도 기준으로 가천대학교의 AI 공학관 + 기숙사 + 운동장까지 가려면
가천대학교 1번 출구 즉, 정문 기준에서 도보로 24분이나 걸리는 것을 알 수 있다.

게다가 거리뷰를 보면 알 수 있듯이 해당 거리는 엄청난 경사로 이루어져있어, 강의를 들으러 갈때에도 체력 소모가 심하고 여름에는 더더욱 문제가 심하다. 해당 내용의 대책으로 가천대 무당이라는 가천대학교 교내 셔틀버스를 운행중이지만, 1교시 전이나 붐빌때는 줄이 너무 길어 강의를 듣기위해 걸어서 올라가거나 아니면 택시를 호출하여 가는 방식을 많이 사용하고있다. 따라서 학생들에게 택시를 요금의 부담을 줄여주고, 택시 호출의 시간을 줄여주는 택시 매칭 시스템을 구현중이다.
구현사항
내가 맡은 API는 매칭 시스템인데, 해당 내용에 대한 회고도 추후에 완성되면 올리도록 하겠다. 일단 초기세팅 단계에는 개발서버의 CI/CD 구축 파트를 맡게되었다.

내가 구현하고자 하는 방식은 blue/green 방식의 무중단 배포였다.
무중단 배포란 ?
서비스가 중단되지 않은 상태를 유지하면서 새로운 개발 사항을 배포하는 방식을 의미합니다.
새로운 버전(V2)을 배포할 때, 기존에 사용 중인 서비스(V1)에
다운타임(downtime)이 발생하지 않도록 보장하는 방법입니다.
CI/CD 파이프라인
우리의 개발 서버를 라즈베리파이로 하기로 정했었기 때문에, GitHub Actions + Docker 를 이용해서 스프링 애플리케이션을 컨테이너화한 후, 라즈베리 파이에 배포하는 방식으로 파이프라인을 설계했다.
도커파일 + YML 워크플로우

개발 환경에서만 사용하기 위해서 Dockerfile-dev라는 이름으로 분리해서 도커파일을 지정해줬고, 기존에 CI/CD 구축시 사용하던 open jdk 17 버전의 alpine 리눅스 환경을 구성하는 FROM openjdk:17-alpine 가 아닌, 라즈베리파이에서 이미지를 사용하기 위해서
FROM eclipse-temurin:17-jre-focal을 사용해주었다.

develop 브랜치에 push 시 트리거되도록, 그리고 develop 브랜치에 대한 PR 시 트리거가 되도록 설계했다.

또한 배포시에는 if: github.event_name == 'push' 조건을 설정해주어서 빌드만 실행을 해주고, 코드 리뷰가 끝난뒤에, 최종적으로 dev 브랜치에 머지될 시에만 배포가 진행되도록 조건을 설정 해줬다.

그리고 무중단 배포 스크립트는 다음과 같다, 8080포트와 8081포트를 이용해서, 현재 실행 중인 컨테이너를 확인한 뒤에 BLUE 또는 GREEN 컨테이너 중 하나를 선택하여 새로운 버전을 실행하도록 했다. 새로운 컨테이너가 정상적으로 실행되면, 이전에 실행 중이던 컨테이너를 종료 및 삭제하고 사용하지 않는 Docker 이미지를 정리하여 서버 리소스를 최적화까지 구현하였다.
트러블 슈팅
먼저 맨처음 막혔던 부분은 아래의 시크릿 키 부분이다
key: ${{ secrets.DEV_SSH_SECRET_PRIVATE_KEY }}
Ec2가 아닌 라즈베리파이 환경이기 때문에 따로 AWS처럼 자동으로 .pem 파일을 제공하지않아서 어떻게 해야되지 구글링을 하다가,
라즈베리 파이에서 키 생성 후 공개 키를 authorized_keys에 등록해준 뒤에, 개인 키 파일 .pem 형태로 변환해주는 방식을 사용했다.
해당 ssh 접속 방식은 생성한 .pem 파일을 사용해 로컬에서 라즈베리 파이에 접속 테스트를 완료했다.
해당 내용은 깃헙 액션으로 DEV_SSH_SECRET_PRIVATE_KEY 라는 이름으로 환경변수를 등록해주었다.

그리고 추가적인 내용으로 아래 사진처럼 깃헙액션 동적 ip 대역이 서버에서 자동으로 차단돼서 배포 과정에 문제가 생겨서

/etc/hosts.deny 파일에서 # sshd: ALL 설정으로 인해 기본적으로 모든 SSH 요청이 차단되고 있었던것을 확인하고, 해당 설정을 주석 처리하여 문제를 해결했다. 대신에 SSH 접근 시도에 대한 보안을 강화하기 위해 Fail2Ban을 도입하여 비인가 IP의 접근 시도를 방지해주는 방식을 사용했다.
느낀점


기존에 주로 사용하던 EC2 기반 환경이 아닌 라즈베리 파이를 개발 서버로 활용하면서, 라즈베리 파이는 EC2에 비해 하드웨어 스펙이 제한적이어서, CI/CD를 구축하며 고려할 점도 많았지만 성공적으로 세팅을 완료하게돼서 뿌듯했다. 이제 추후에 매칭 기능을 완성하고 해당 게시글에 대한 회고록으로 돌아오겠다.
참고한 자료
'Spring > DevOps' 카테고리의 다른 글
Weeth(무중단 배포, DevOps) (1) | 2025.01.18 |
---|