Github Actions를 사용해서 CICD 구축해보기 실습 with GCP - 실행편

서론

이전 시간에 우리는 Springboot로 만든 애플리케이션을 도커 이미지로 만들고 그 이미지를 GCP의 컨테이너 저장소에 푸시하는 것까지 성공하였다.

이번 시간에는 우리가 로컬에 만든 프로젝트를 깃허브 원격 저장소에 등록하고 거기서 Github Actions를 사용해 마스터 브랜치로 push를 할 경우 자동 빌드와 자동 배포를 하도록 설정해볼 것이다.

GCE (Google Compute Engine)

GCP에서는 사용자가 간편하게 사용할 수 있는 VM 인스턴스를 생성할 수 있는 서비스를 제공하고 있다.

그러한 VM(가상머신)의 이름을 GCP에서는 GCE라고 부른다.

우리는 지금부터 이 GCE를 만들 것이다. 단, 우리가 이전 시간에 올려뒀던 이미지를 실행시키는 용도로써 말이다.

GCE 만들어보기

스크린샷 2020-08-29 오후 6 02 59

Compute Engine 탭에서 인스턴스 만들기를 클릭

스크린샷 2020-08-29 오후 6 04 25

인스턴스 이름은 아무거나 편한걸로, 필자는 test로 했다

머신 구성은 아무래도 싼게 좋으니까(?) CPU 2개에 1기가 메모리로 골랐다.

어차피 현재 배포할 애플리케이션은 컴퓨팅 파워가 그렇게 중요하지는 않으니 싼걸로 하자.

스크린샷 2020-08-29 오후 6 05 37

가장 중요한 옵션인 컨테이너 배포를 체크하자.

컨테이너 이미지에 방금 우리가 올린 이미지를 넣어주어야한다.

스크린샷 2020-08-29 오후 6 07 33

앞서 우리가 푸시해놓은 이미지 이름을 옆에 마우스를 대면 복사 기능이 나온다

스크린샷 2020-08-29 오후 6 07 39

이미지 저장소 이름을 복붙해주자

스크린샷 2020-08-29 오후 6 08 45

그리고 나서 HTTP 트래픽 허용에 체크하고 모든 액세스 허용을 한 다음 생성을 해보자.

인스턴스가 생성고 나면 해당 인스턴스에 대한 유동 IP가 발급되게 된다.

그 전에 우리가 셋팅해줄게 있다.

스크린샷 2020-08-29 오후 6 09 52

메뉴 탭에서 방화벽을 눌러서 방화벽을 해제해주어야한다.

스크린샷 2020-08-29 오후 6 10 19 스크린샷 2020-08-29 오후 6 10 46

다음과 같이 모든 IP와 포트에 대한 방화벽 설정을 해제해주어야 우리가 해당 인스턴스에 브라우저로 접근이 가능하다.

스크린샷 2020-08-29 오후 6 11 34

외부 IP가 생성되었을 것이고 이 IP에 포트번호 8080를 브라우저에 입력하면?

스크린샷 2020-08-29 오후 6 11 44

짜잔 우리가 만든 웹서비스가 잘 배포되었는 것을 확인할 수 있다.

스크린샷 2020-08-29 오후 6 13 24 스크린샷 2020-08-29 오후 6 13 30 스크린샷 2020-08-29 오후 6 13 48

그리고 아까 방화벽 설정한 VPC 네트워크에서 외부 IP 주소 탭을 누르면 우리가 만든 인스턴스의 IP를 볼 수 있는데 유동 IP를 고정 IP로 등록해놓자.

이제 준비는 끝났다 오랜만에 Intellij 프로젝트를 열어 해당 프로젝트를 깃허브에 저장소를 만들자.

깃허브 원격 저장소에 프로젝트 등록 With Intellij

로컬 프로젝트를 원격 저장소에 등록하는 여러가지 방법이 있지만, 필자의 경우 인텔리제이에서 제공하는 깃허브를 주로 사용하는 편이다.

스크린샷 2020-08-29 오후 6 17 18

인텔리제이 환경설정 탭에서 git을 검색하면 github라는 탭이 있는데 여기에 자신의 깃 계정을 추가해주자.

스크린샷 2020-08-29 오후 6 18 13

그리고 나서 상단 탭에 보이는 share on github를 눌러 원격 저장소에 내 로컬 프로젝트를 공유하도록 하자.

스크린샷 2020-08-29 오후 6 19 44

필자는 대충 이런 이름으로 만들었다.

스크린샷 2020-08-29 오후 6 24 20

그럼 깃허브 원격 저장소에 잘 올라와있을 것이고, 이제부터 본격적으로 Github Actions를 사용해 CI/CD를 구축해보자.

Github Actions를 사용하기 위한 서비스 계정 생성 및 등록

Github Actions는 사용하기가 정말 쉽다.

스크린샷 2020-08-29 오후 6 25 33

우선, Github Actions 탭에서 마우스 휠을 슥슥 내리다보면 이미 다양한 클라우드에 배포할 수 있는 예제들이 많은 것을 확인할 수 있다.

그런데 대표 예제중에 GCE 배포 예제 스크립트는 보이지 않는 것 같다.

구글에 부랴부랴 검색을 해보면 구글에서 별도의 저장소로 GCE 배포에 대한 예제 스크립트를 제공하고 있는 것을 확인할 수 있다.

https://github.com/GoogleCloudPlatform/github-actions

그리고 (역시 구글) 아주 친절하게 사용법이 나와있다.

https://github.com/GoogleCloudPlatform/github-actions/blob/master/example-workflows/gce/README.md

그러나 영어 울렁증이 있는 사람들은 대략 머리가 어지럽고 멍해질 것이라 생각해 필자가 하나씩 알려줄 것이니 너무 걱정하지 말자.

우선 Github Actions와 GCP를 연동하기 위해서는 서비스 계정이라는 것을 만들어두어야한다.

이 서비스 계정에 대한 정보를 yaml 파일에 입력함으로써 Github Actions가 내 GCP 프로젝트에 접근 권한을 갖게 하는 플로우인 것 같다. (이 부분은 필자의 뇌피셜이니 신뢰하지 말자)

결과부터 말하자면 위의 서비스 계정 발급 절차를 통해 우리는 최종적으로 .json 파일을 하나 얻는게 목적이다.

아래의 링크로 접속하자.

https://cloud.google.com/iam/docs/creating-managing-service-accounts

스크린샷 2020-08-29 오후 6 31 27

그러면 서비스 계정 페이지로 이동이라는 버튼을 눌러 서비스 계정을 하나 만들자.

스크린샷 2020-08-29 오후 6 33 16 스크린샷 2020-08-29 오후 6 33 26 스크린샷 2020-08-29 오후 6 34 39

우리는 여기서 생성될 서비스 계정에 총 세 가지 권한을 주어야한다.

  • Compute Instance Admin - GCE MV 접근 권한

  • Storage Admin - 컨테이너 저장소 푸시 권한

  • Service Account User - 컴퓨팅 스토리지 권한으로 명령 실행 권한

이 세 권한을 잘 넣어서 만들어주면 다음과 같은 모습이 나온다. 잘 따라고 있기를 바란다.

스크린샷 2020-08-29 오후 7 26 36

(편집자 권한은 권장하는 권한은 아니다. 그러나 계속 서비스 계정 권한 에러가 나서 편집자 권한을 넣어버렸다. 어떤 권한을 넣어줘야하는지 잘 아는 사람이 있다면 댓글로 알려주시길… ㅜㅜ)

스크린샷 2020-08-29 오후 6 42 41

(빈 칸으로 둔 채 무시하고 완료)

스크린샷 2020-08-29 오후 6 43 12

그러면 서비스 계정이 완성된 것을 확인할 수 있다.

스크린샷 2020-08-29 오후 6 43 52 스크린샷 2020-08-29 오후 6 43 56

처음 생성하면 키가 없을텐데 점 세개 (뭐라고 부르지 이걸?)를 클릭해서 키 만들기를 눌러 JSON 키를 생성해주자.

그러면 키 JSON 파일이 생성될텐데 이 파일을 잘 보관해두자.

그리고 나서 깃허브에 시크릿 키를 등록하러 가자.

스크린샷 2020-08-29 오후 6 45 48

생성한 프로젝트에 Settings 탭에서 Secrets를 클릭해보자.

스크린샷 2020-08-29 오후 6 46 15

여기서 New Secret을 클릭해 새로운 시크릿 키를 생성하자.

우리가 생성해야하는 시크릿 키는 총 두개이다.

  • GCE_PROJECT: 프로젝트 ID, 저번 시간에도 사용했으니 기억 날 것이다.

  • GCE_SA_KEY: 아까 로컬에 다운받아진 JSON 파일을 그대로 복-붙 해서 넣어주면 된다.

스크린샷 2020-08-29 오후 6 47 51 스크린샷 2020-08-29 오후 6 48 18

그러면 다음과 같이 두 개의 시크릿키가 생성된 것을 확인할 수 있다.

스크린샷 2020-08-29 오후 6 48 33

자 이제 준비는 끝났다.

혹시나 못찾을까봐 workflow .yaml 파일을 아래에 첨부해두겠다.

# Copyright 2020 Google, LLC.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: Build and Deploy to Google Compute Engine

on:
  push:
    branches:
      - master

env:
  PROJECT_ID: $
  GCE_INSTANCE: my-githubactions-vm # TODO: update to instance name
  GCE_INSTANCE_ZONE: us-central1-a # TODO: update to instance zone

jobs:
  setup-build-publish-deploy:
    name: Setup, Build, Publish, and Deploy
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      # Setup gcloud CLI
      - uses: GoogleCloudPlatform/github-actions/setup-gcloud@master
        with:
          version: '290.0.1'
          service_account_key: $
          project_id: $

      # Configure Docker to use the gcloud command-line tool as a credential
      # helper for authentication
      - run: |-
          gcloud --quiet auth configure-docker
      # Build the Docker image
      - name: Build
        run: |-
          docker build --tag "gcr.io/$PROJECT_ID/$GCE_INSTANCE-image:$GITHUB_SHA" .
      # Push the Docker image to Google Container Registry
      - name: Publish
        run: |-
          docker push "gcr.io/$PROJECT_ID/$GCE_INSTANCE-image:$GITHUB_SHA"
      - name: Deploy
        run: |-
          gcloud compute instances update-container "$GCE_INSTANCE" \
            --zone "$GCE_INSTANCE_ZONE" \
            --container-image "gcr.io/$PROJECT_ID/$GCE_INSTANCE-image:$GITHUB_SHA"

GCE 인스턴스에 서비스 계정 등록

앞서 우리가 만든 GCE 인스턴스에 서비스 계정이 등록되어있지 않았으므로 등록해주자.

스크린샷 2020-08-29 오후 6 53 02

등록을 위해서 우선 장비를 정지해야한다.

스크린샷 2020-08-29 오후 6 56 08

서비스 계정을 방금 만들어둔 서비스 계정으로 수정하고 인스턴스를 다시 시작해주자.

Github Actions를 사용해 GCP에 CI/CD 구축

이제 본격적으로 위 yaml을 수정해 CI/CD를 구축할 것인데 보일러 플레이트 코드가 너무나 완벽하기 때문에 우리는 환경변수만 몇개 수정해주면 되니 너무 걱정하지 말자.

name: Build and Deploy to Google Compute Engine

on:
  push:
    branches:
      - master

env:
  PROJECT_ID: $
  GCE_INSTANCE: test # TODO: update to instance name
  GCE_INSTANCE_ZONE: us-central1-a # TODO: update to instance zone

사실상 이 부분만 수정하면 된다.

yaml 주석에도 나와있듯이 GCE 인스턴스 이름을 적어주자 필자의 경우 test였다.

그리고 GCE 인스턴스 ZONE을 적어주면 되는데 필자와 동일한 설정을 가져갔다면 us-central1-a일 것이고 다른 존이라면 그 존 이름을 적어주면 된다.

이거면 끝이다!

너무 간단해서 놀랐겠지만 진짜다.

스크린샷 2020-08-29 오후 6 57 51

Actions 탭에 진입해서 set up a workflow yourself를 클릭해서 아까 만들어둔 .yaml을 복사해주자.

파일 이름이 디폴트가 main인데 필자는 test로 바꿔보았다.

스크린샷 2020-08-29 오후 6 58 34

이렇게 하면 준비가 끝났다.

GCP와 연동하는게 조금 번거로워서 그렇지 깃허브 액션 자체는 사용하는 것이 크게 어렵지 않다.

그리고 클라우드 플랫폼에서 Github Actions에 대한 예제들이 많고 설명이 친절해서 쉽게 적용할 수 있다는 큰 장점이 있다. (진입 장벽이 낮다)

자 이제 우리의 인스턴스가 잘 살아있는지 확인해보자.

스크린샷 2020-08-29 오후 7 00 45

아까 중지해뒀던 인스턴스가 다시 재시작이 잘 됐다면 welcome을 반환할 것이다.

이제 우리의 기획 요구사항이 바뀌어서 웰컴 페이지에서 welcome 대신 hello bro로 수정하라는 니즈가 생겼다고 가정해보자.

우리가 할일은 아주 간단하다.

인텔리제이를 키고 welcomehello bro로 바꾼 뒤 커밋-푸시 해주자

인텔리제이에서 깃허브 연동을 해두었기 때문에 Git Commit, Push를 위한 UI가 활성화 된 것을 확인할 수 있다.

필자가 자주 애용하는 기능이며 여러분들도 써보기를 바란다.

사용법은 아래와 같다.

스크린샷 2020-08-29 오후 7 02 26

애플리케이션 코드를 수정해주면 수정된 파일이 파랗게 표시된다. 원격 저장소와 변경사항이 발생했다는 것을 보여준다.

스크린샷 2020-08-29 오후 7 02 34 스크린샷 2020-08-29 오후 7 02 52

Commit 버튼(체크 버튼)을 누르면 커밋 로그를 입력할 수 있는 창이 나오고 커밋 할 수 있다.

스크린샷 2020-08-29 오후 7 03 00

그리고 옆에 있는 화살표, 딱 봐도 뭔가 밖으로 나갈 것 같이 생긴 친구를 클릭하면 푸시가 가능하다.

스크린샷 2020-08-29 오후 7 03 04

원격 저장소로 푸시해주자.

푸시를 할 때 마다 깃허브 액션이 알아서 CI/CD 과정을 진행해준다.

스크린샷 2020-08-29 오후 7 30 04

( 에러의 흔적… )

이제 잘 배포가 되었는지 확인해보자.

스크린샷 2020-08-29 오후 7 31 19

잘 바뀌었다!

어떤가 엄청 편리하지 않은가?

조금 귀찮지만 프로젝트 초반에 CI/CD를 구축해놓으면 개발하면서 바뀌는 부분을 깃허브에 커밋만 하는 것으로 배포까지 해주니 매우 매우 편리하다는 것을 느낄 수 있을 것이다.

필자도 Github Actions를 사용해 사이드 프로젝트를 진행했었는데 변경 사항이 바로 바로 반영되니까 무척이나 편리함을 느꼈었다.

덧붙여서 PR이 올라갈 때 테스트 코드를 자동으로 빌드하게 만들 수도 있는데 이 부분은 크게 어렵지 않으므로 만들어둔 .yaml 파일을 공유하면서 글을 마무리하도록 하겠다.

https://github.com/depromeet/8th-warming-up-backend-2team/blob/develop/.github/workflows/pull_request.yml

마치며

드디어 몇일에 걸려 쓰던 글을 마무리했다.

설명이 미흡한 부분이 있다면 댓글로 알려주길 바라며 여러분들의 사이드 프로젝트에 Github Actions를 도입하여 생산성 증대를 느껴보길 바란다!

GCP와 도커, k8s를 알려주신 Google 개발자 정명훈님 감사합니다.

GCP 만세



© 2022. by minkuk

Powered by minkuk