Post

[CICD] Springboot GCP(Google Cloud Platform) 적용기

GCP - Compute Engine

GCP Computer Engine 은 구글에서 제공하는 EC2 라고 보면 된다. EC2 는 프리티어라 속도의 한계가 있지만, GCP 를 사용하면 무료크레딧을 사용해 좀 더 고성능으로 사용할 수 있다. GCP 생성 방법은 간략하게 소개하고 넘어가겠다. 자세히 알고싶으면 맨아래 Reference 를 보자.

  1. Google Cloud 홈페이지 > 신규회원가입이라면 무료로 300달러를 지급한다.
  2. Computer Engine 으로 들어가 새로운 인스턴스를 만든다.
  3. 인스턴스는 region 은 서울, 머신은 저렴한 E2-small 로 저성능을 선택했다.
  4. 부팅디스크는 Github action 에서도 Ubuntu 를 사용하므로 동일하게 Ubuntu 를 사용했다.(암드가 아닌 인텔환경이다)
  5. 방화벽의 경우 http, https, 로드밸런스 모두 체크해주었다.

고정 IP 할당

VPC 네트워크 > IP 주소로 가서 외부 고정 주소 예약을 통해 IP 를 고정하자. 고정 안하면 대참사 일어난다. 참고로 인스턴스를 삭제하게 되었을때 고정한 IP 도 따로 삭제해주어야 한다. 안그러면 계속 비용이 청구된다.

방화벽 설정

EC2 에서 해줬듯이 필요한 방확벽을 설정하면 된다. EC2 와 다른점은 기본으로 80/443/3389/22 가 설정되어있다. 나는 SpringBoot 를 사용하기에 8080 을 추가로 등록해 주었다.

GCP - Cloud SQL

GCP Cloud SQL 은 구글에서 제공하는 RDS 라고 보면 된다. GCS 생성 방법도 간략하게 소개하고 넘어간다.

  1. Cloud SQL 으로 들어가 새로운 인스턴스를 만든다.
  2. DB 에서 사용할 id, password 를 설정한다.
  3. 머신 구성은 개발모드와 커스텀을 통해 최대한 싼걸로 선택했다. Cloud SQL 은 생각보다 비용이 비싸다..
  4. region 은 서울로 설정한다. 나는 단일영역을 사용해 최대한 비용을 줄였다.

데이터베이스 생성

EC2 는 기본으로 데이터베이스를 하나 만들어주지만, GCP 는 그런거없다. 데이터베이스 탭으로 가서 기본으로 사용할 데이터베이스를 생성해두자.

네트워크 승인

연결 > 네트워킹 으로 들어가 허용해줄 ip 를 등록하자. 앞서 생성했던 Computer Engine 인스턴스의 고정 ip 를 등록하고, 본인 로컬에서 작업할 수 있게 로컬 ip 도 등록하자. 내 로컬 ip 를 모르겠다면 구글에 들어가서 “Whis is my ip address” 라고 검색해서 사이트 들어가면 알려준다. 해당 ip 등록해두는거 잊고서 카페가서 왜 안돼지? 하지말고 기억해두자.

ip 접속

EC2 에서는 주소 비슷한걸 주었었지만, 기본적으로 GCP 는 ip 를 통해 접속한다.

CD

나는 Github Action 을 이용해 GCP 로 배포했는데 기본적으로 과정은 EC2 와 동일하다. 아래 코드는 Github Action 의 Workflow 에서 작동할 코드이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
name: action-production-cd

# 언제 이 파일의 내용이 실행될 것인지 정의
on:
  push:
    branches:
      - main

# 코드의 내용을 이 파일을 실행하여 action을 수행하는 주체(Github Actions에서 사용하는 VM)가 읽을 수 있도록 권한을 설정
permissions:
  contents: read

# 실제 실행될 내용들을 정의합니다.
jobs:
  build:
    runs-on: ubuntu-latest # ubuntu 최신 버전에서 script를 실행
    steps:
      # 지정한 저장소(현재 REPO)에서 코드를 워크플로우 환경으로 가져오도록 하는 github action
      # submodule 을 사용하기 위한 설정을 추가
      - name: Checkout repository
        uses: actions/checkout@v3
        with:
          token: ${{secrets.ACTION_TOKEN}}
          submodules: true

      # open jdk 17 버전 환경을 세팅
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: "corretto"

      # 캐시를 사용하기위해 buildx 를 사용
      - name: Setup docker buildx
        uses: docker/setup-buildx-action@v2

      # gradle을 통해 소스를 빌드.
      - name: Build with gradle
        run: |
          chmod +x ./gradlew
          ./gradlew clean build -x test

      # 도커 컴포즈 설정 파일 서버로 전달
      - name: Send docker-compose.yml
        uses: appleboy/scp-action@master
        with:
          username: ${{ secrets.KCS_USERNAME_PROD }}
          host: ${{ secrets.KCS_HOST_PROD }}
          key: ${{ secrets.KCS_KEY_PROD }}
          source: "src/main/resources/backend-submodule/docker-compose.yml"
          target: "/home/g22203/"

      # Docker hub 로그인
      - name: Login to dockerHub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME}}
          password: ${{ secrets.DOCKER_TOKEN}}

      # Docker Hub 에 푸시
      - name: Build and push
        uses: docker/build-push-action@v4
        with:
          context: .
          file: ./Dockerfile
          push: true
          tags: ${{ secrets.DOCKER_REPOSITORY_PROD }}:latest
          cache-from: type=gha
          cache-to: type=gha, mode=max

      # appleboy/ssh-action@master 액션을 사용하여 지정한 서버에 ssh로 접속하고, script를 실행합니다.
      # 실행 시, docker-compose를 사용합니다.
      - name: Deploy to server
        uses: appleboy/ssh-action@master
        with:
          username: ${{ secrets.KCS_USERNAME_PROD }}
          host: ${{ secrets.KCS_HOST_PROD }}
          key: ${{ secrets.KCS_KEY_PROD }}
          script: |
            docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
            sudo docker pull {{ secrets.DOCKER_REPOSITORY_PROD }}:latest
            docker-compose -f docker-compose.yml down
            docker rmi $(docker images -q)
            cp -f ./src/main/resources/backend-submodule/docker-compose.yml .
            rm -r src
            docker-compose -f docker-compose.yml up -d


GCP 준비

나는 docker, docker-compose 를 이용한다. 따라서 GCP 에서도 docker, docker-compose 를 설치해주어야 한다.

GCP 접속

GCP 접속을 위해서는 USERNAME, HOST, KEY 가 필요해진다. HOST 는 생성한 인스턴스의 고정 IP 를 적어주면된다.

그리고 GCP 를 ssh 를 통해 접속해보자. 아래그림처럼 GCP 는 브라우저를 통해 ssh 연결을 할 수 있다.

이미지

그리고 ssh-keygen -t rsa -f ~/.ssh/[KEY_FILENAME] -C [USERNAME] 해당 명령어를 통해 키를 만들자.

이미지

여기서 g22203 이 USERNAME 이다. 키를 만들었다면 키를 만든곳으로 들어가서 확인해보자. GCP 는 개인키와 공개키를 만들어준다. 위에서 key1 이 개인키, key1.pub 가 공개키이다. 여기서 key1 이 KEY 이다. cat key1 명령어를 사용해서 나온 키값을 다 넣어주면된다. (몇몇분이 begin, end 안 넣는분 있는데 다 넣어야 된다.)

이미지

공개키의 경우도 cat key1.pub 를 통해 나온 내용을 복사해서 메타데이터 > ssh키에 넣어주자. 여기에 등록해주어야 키가 정상적으로 작동한다.

로컬에서 접속

로컬에서 ssh 에 접속하고 싶다면 로컬 터미널창에서 키를 만들어주면 된다. 그리고 퍼블릭키를 메타데이터 > ssh키에 등록해주면 된다. 참고로 계정이 다르면 다른 계정으로 접속되니 같은 계정으로 들어가고싶다면 USERNAME 을 동일하게 해서 생성하자.

로컬에서 접속할때는 터미널로 아래를 명령어를 입력해주면 된다.

ssh -i [키파일경로] [계정]@[외부IP]

마무리

AWS 프리티어는 개발환경에 사용하고, GCP 는 운영환경에서 사용하고자 GCP 를 사용하게 되었다. AWS 프리티어는 아무래도 성능이 제한되다 보니 무료로 좋은성능을 낼려면 GCP 를 사용해야 된다. EC2 를 사용해봤다면 GCP 를 쓰는데 익숙하지만, 조금씩 다른차이가 있어 해당 글을 작성하게 되었다.

Reference

https://choo.oopy.io/5c999170-dde5-4418-addc-00a0d263287c https://minimin2.tistory.com/172

This post is licensed under CC BY 4.0 by the author.