라즈베리파이 + MSA(Spring Cloud) + CI/CD 배포

2025. 4. 17. 23:26·프로젝트에서 일어난 일

1. 개요

졸업 프로젝트로 교내 키오스크를 개발하고 있다.

이때 MSA를 CI/CD 자동화 배포에 성공한 경험을 기록하고자 이 글을 작성한다.

 

2. 시스템 아키텍처

빠른 이해를 위해 시스템 아키텍처를 보자!

만든이: 송우석

 

시스템 아키텍처는 다음과 같고

내가 작성한 CI/CD 흐름은 다음과 같다.

1. MicroService별로 변경 감지
2. 변경 감지된 MicroService-CI.yml job 실행
3. docker compose image pull
4. docker compose up -d

아쉬운 점은 마이크로서비스 별로 yml을 작성했다는 점과 젠킨스를 사용안해본 것.

자동화 배포에 성공은 했지만 유지보수는 조금 힘들 거 같다는 생각이 들었다.

 

3. 실제 CI.yml 코드 예시

name: User Service CI

on:
  push:
    branches: [ main ]
    paths:
      - 'User-Service/**'

env:
    SERVICE_NAME: ${{ secrets.USER_SERVICE }}

jobs:
  build:
    name: Build MicroService
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Set up JDK 17
      uses: actions/setup-java@v4
      with:
        distribution: 'temurin'
        java-version: '17'

    # Gradle 캐시 설정 추가
    - name: Gradle Caching 
      uses: actions/cache@v3
      with:
        path: |
          ~/.gradle/caches
          ~/.gradle/wrapper
          ${{ env.SERVICE_NAME }}/.gradle  # 프로젝트별 Gradle 캐시 디렉토리
        key: ${{ runner.os }}-gradle-${{ hashFiles('${{ env.SERVICE_NAME }}/gradle/wrapper/gradle-wrapper.properties', '${{ env.SERVICE_NAME }}/build.gradle') }}
        restore-keys: |
          ${{ runner.os }}-gradle-

    # Gradle Build를 위한 권한 부여
    - name: Grant execute permission for gradlew
      run: chmod +x ./${{ env.SERVICE_NAME }}/gradlew

    - name: Build User Service
      run: |
        cd ./${{ env.SERVICE_NAME }}
        ./gradlew clean build -x test

    # DockerHub 로그인
    - name: Docker Hub Login
      uses: docker/login-action@v2
      with:
        username: ${{ secrets.DOCKER_USER_NAME }}
        password: ${{ secrets.DOCKER_PASSWORD }}

    - name: Docker build & push
      run: |
        cd User-Service
        docker buildx create --use
        docker buildx build --platform linux/amd64,linux/arm64 -f Dockerfile-dev -t ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_USER_REPOSITORY }}:${{ secrets.DOCKER_TAG }} --push .

 

on:
  push:
    branches: [ main ]
    paths:
      - 'User-Service/**'

main 브랜치의 User-Service가 변경이 감지되면 실행한다.

env:
    SERVICE_NAME: ${{ secrets.USER_SERVICE }}

MicroService 경로로 들어가서 build 작업, 권한 부여 등의 여러 작업이 있기 때문에

미리 환경 변수로 빼둬서 유지보수가 편의하도록 작성 했다.

 

    # DockerHub 로그인
    - name: Docker Hub Login
      uses: docker/login-action@v2
      with:
        username: ${{ secrets.DOCKER_USER_NAME }}
        password: ${{ secrets.DOCKER_PASSWORD }}

    - name: Docker build & push
      run: |
        cd User-Service
        docker buildx create --use
        docker buildx build --platform linux/amd64,linux/arm64 -f Dockerfile-dev -t ${{ secrets.DOCKER_USER_NAME }}/${{ secrets.DOCKER_USER_REPOSITORY }}:${{ secrets.DOCKER_TAG }} --push .

1. 도커 허브에 로그인을 미리 한다.

2. Dockerfile-dev를 이용해 도커 이미지를 만든다.

3. Docker Hub에 Push

 

5. CD 코드 예시

사용한 Deploy.sh 코드이다.

  deploy:
    runs-on: ubuntu-latest
    needs: build
    if: github.event_name == 'push'

    steps:
      # SSH를 사용하여 원격 서버에 배포
      - name: Deploy to server
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          password: ${{ secrets.SERVER_PASSWORD }}
          port: ${{ secrets.SERVER_PORT }}
          script: |
            echo "Deploy 쉘 스크립트 실행"
            sudo ./deploy.sh

 

라즈베리파이에 SSH로 접속해서 경로에 있는 deploy.sh를 실행하도록 작성했다.

 

라즈베리파이에 작성해둔 deploy.sh은 다음과 같다.

# 도커 컨테이너 상태 확인
echo "CI/CD 테스트1"
docker ps

# 도커 컴포즈 실행
echo "Docker-Compose 실행"
docker compose pull
docker compose up -d

# 사용하지 않는 Docker Image 제거
echo "사용하지 않는 Docker Image 제거"
docker image prune -f

 

docker compose pull로 변경된 이미지만 가져오고

docker compose up -d 로 실행한다.

또한 사용하지 않는 이미지를 제거하기 위해 docker image prune -f를 사용했다.

 

도커 컴포즈 파일은 도커 레포지토리 경로가 직접적으로 노출될 수 있어서 생략하겠다!

 

6. 실행 결과

docker 컨테이너 현황

 

discovery-server 접속

 

라즈베리파이 메모리 사용량

라즈베리파이 램은 약 2기가 정도 사용되고 있다.

그러나 아직 초기세팅만 해둔 Spring 컨테이너이기 때문에 개발을 하면 할 수록 메모리를 더 잡아먹을 거 같다.

지켜보자.

 

7. 소감

MSA 강의를 보고 실제로 프로젝트를 만들어서 CI/CD 자동화 배포까지 성공했다.

특히 내가 가지고 있는 라즈베리파이로 직접 서버를 구축까지 한 터라 아주아주 뿌듯하다.

 

두가지 아쉬운 점이 있다.

 

1. Jenkins

젠킨스로 CI 과정을 거쳐보고 싶었다. 그러나 나는 MSA 프로젝트는 처음이라서 Jenkins 까지 배울 시간이 없었다.

졸업 프로젝트를 완성 한 뒤 꼭 Jenkins를 공부해봐야겠다.

 

2. 개별로 작성된 CI.yml

마이크로 서비스별로 ci.yml을 작성했다. 이는 마이크로 서비스가 추가 될 때 마다 yml을 작성해줘야 해서 유지보수가 힘들 거 같다.

다음에는 폴더가 아닌 브랜치 별로 변경 감지를 한다거나 아니면 좀 더 공부를 해서 하나의 CI.yml로 통합해서 CI/CD 파이프라인을 설계해보고 싶다.

'프로젝트에서 일어난 일' 카테고리의 다른 글

Spring Cloud Gateway에서 인증/인가 구현하기  (0) 2025.04.25
DataGrip에서 SSH 터널링으로 MySQL Container 접속하기  (0) 2025.04.18
다수 데이터 Insert 시 성능 개선하기(37.06% 개선)  (1) 2025.04.16
같은 객체에 대해서 OneToMany를 두번 사용할 경우  (0) 2025.04.14
졸프: 라즈베리파이와 MSA를 곁들인  (0) 2025.04.10
'프로젝트에서 일어난 일' 카테고리의 다른 글
  • Spring Cloud Gateway에서 인증/인가 구현하기
  • DataGrip에서 SSH 터널링으로 MySQL Container 접속하기
  • 다수 데이터 Insert 시 성능 개선하기(37.06% 개선)
  • 같은 객체에 대해서 OneToMany를 두번 사용할 경우
송우석입니다
송우석입니다
  • 송우석입니다
    송우석
    송우석입니다
  • 글쓰기 관리
  • 전체
    오늘
    어제
    • 분류 전체보기 (136) N
      • JAVA (1)
      • 알고리즘 (83) N
        • 백준 (8)
        • String(문자열) (12) N
        • Array(1, 2차원 배열) (12)
        • Two pointers, Sliding windo.. (6)
        • HashMap, TreeSet(해쉬, 정렬지원 S.. (5)
        • Stack, Queue(자료구조) (8)
        • Sorting and Searching(정렬, 이.. (10)
        • Recursive, Tree, Graph(DFS,.. (14)
        • DFS, BFS 활용 (6)
        • 다시 시작! (1)
        • 기초 수학 (1) N
      • 일상 (19)
      • Github (1)
      • MSA 공부 (3)
      • 경제, 금융, 디지털, 시사 (3)
      • 라즈베리파이 (10)
      • 프로젝트에서 일어난 일 (13)
      • FrontEnd 공부 (3)
        • React (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
송우석입니다
라즈베리파이 + MSA(Spring Cloud) + CI/CD 배포
상단으로

티스토리툴바