본문 바로가기

Github-actions 사용기 (with GCP) 본문

개발/GCP

Github-actions 사용기 (with GCP)

자전하는명왕성 2023. 5. 27. 03:35
반응형

github-actions를 통해 GCE 인스턴스를 자동화 배포했던 과정을 포스팅한다.
 
github-actions
github-actions(이하 깃허브 액션)은 빌드/테스트/배포를 자동화할 수 있는 CI/CD 플랫폼이다.
구동방식은 다음과 같다.
특정 조건(events)에 따라, 원하는 작업 흐름들(workflows)를 실행시킨다.
이후 workflows내에 존재하는 작업(jobs)을 단계(steps)에 따라 명령어를 수행한다.(actions)
 
event / workflows / jobs / steps / actions 에 대해
events
- 특정 이벤트 (push, merge, issue) 발생 시 workflow를 실행시키는 역할
- workflow 실행을 트리거하는 특정 활동이나 규칙을 의미하기도 함
workflows
- 이밴트 발생 시 실행되는 것을 정의한 파일
- 하나 이상의 job으로 구성되며, event에 의해 트리거될 수 있는 자동화된 프로세스
- 레포지토리는 여러 개의 workflow를 가지고 각기 다른 작업으로 수행할 수 있다는 특징
- .github/workflows 폴더 내에 저장되어 실행됨
jobs
- 여러가지 steps으로 구성되고 가상환경의 인스턴스에서 실행
- 병력적으로 실행되나 원하면 순차적 / 순서 지정 / 의존 관계 지정이 가능함
- actions 를 사용
steps 
- actions을 실행시키는 순서들을 나타내며, actions을 실행
actions
- workflow의 가장 작은 요소로 step들을 구성함
- 명령어 그 자체로 보아도 무방
 
github-actions 적용 전 환경
먼저, docker image를 container registry 를 사용해서 배포를 진행한 것이 아니라, 
git clone / git pull을 활용하여 github에 올린 소스코드를 가져와 배포하는 과정이었음을 밝힌다.
 
github-actions을 사용하기 전 상황
- 배포된 인스턴스(GCE)
- 방화벽 설정
- 인스턴스에 docker가 설치됨
- env 설정을 인스턴스 내 설정
- 서버 인스턴스 / mySQL 인스턴스 / redis 인스턴스 인스턴스 그룹화
- VPC 페어링
- DNS 연결
- 로드밸런서 (with SSL 인증서)
- GCP 서비스 계정 생성 (json 파일 key)
 
github-actions 사용
1. 환경변수 설정
먼저, workflows 파일을 작성하기 전에, 환경 변수의 설정이 필요하다.

이는 좌측 사이드바에서 설정이 가능한데, 이를 선택한 뒤 New repository secret 버튼을 누른다.
나의 경우에는 환경 변수에는 다음과 같은 요소를 집어넣었다.

GCP_PROJECT_ID : GCP 프로젝트의 아이디 (인스턴스 ID랑 헷갈리면 안됨)
GCP_SA_KEY : GCP 서비스 계정 생성 시 발급된 JSON 파일을 전체 붙여넣기하면 된다
GCP_VM_NAME, GCP_VM_NAME2와 같은 경우에는 인스턴스 접속 시 좌측에 나오는 계정을 복사해서 입력해주면 된다
(왼쪽은 NAME / 오른쪽은 NAME2)

GCP_ZONE : GCP 인스턴스가 실행되고 있는 지역을 의미한다. 

 
2. workflows / yml 파일 작성
내가 작성한 내용은 다음과 같다.
 

name: githubaction-cd // "name" 태그는 자신이 원하는대로 작성해도 좋다.

on:
  push:
    branches: [ "master" ] // "master" 브런치에 "push" 시 실행. (event)

jobs:
  cd:
    name : gitaction-cd
    runs-on: ubuntu-latest // github-action을 실행하기 위한 컴퓨터

    steps:
    - name : checkout
      uses: actions/checkout@v3 // 레포지토리 최신 버전의 코드를 가져오는 라이브러리. 

    - id : "auth"
      name : Authenticate to GCP
      uses : google-github-actions/auth@v0 // GCP인증을 위한 라이브러리.
      with:
        credentials_json: ${{ secrets.GCP_SA_KEY }} // 아까 변수로 입력한 json파일이 이곳에서 사용된다.
    
    - name : server-on
      run : |-
        gcloud compute ssh --project=${{ secrets.GCP_PROJECT_ID }} --zone=${{ secrets.GCP_ZONE }} ${{ secrets.GCP_VM_NAME }}@${{ secrets.GCP_VM_NAME2 }} -- \
        "cd github-action && \
        docker-compose stop && \
        docker system prune -a && \
        git pull && \
        docker-compose -f docker-compose.prod.yaml build && \
        docker-compose -f docker-compose.prod.yaml up -d
        "
        
	// 위 run을 요약하면 다음과 같다.
    // gcloud 를 통해 내가 가지고 있는 인스턴스에 ssh로 접속
    // github-action 파일이동 후 
    // docker 정지 / image 초기화 / 레포지토리 git pull / docker build & up

이때 && 연산자는 앞의 명령어가 완료된 이후 다음 명령어를 실행할 수 있도록 한다. (이 문제에 대해 너무 오래 붙잡고 있었음 ㅠ.ㅠ)
 
github-actions 실행과 자동화 배포 확인
https://zyno.store/cd 접속 시 "해치웠나" 라는 문구가 등장해야 자동화 배포가 정상적으로 시행되게끔 간단한 기능을 추가했다.
이후 정상 배포가 진행되었음을 확인하고, 

30초 정도 지나면 인스턴스에 수정내용이 반영이 된다.

클리셰를 온몸으로 부수어 결국 승리했다.
 
약 28번의 삽질 간 발생했던 오류들과 해결 방법

사실 yml 파일을 작성하는 과정이 쉽지는 않았다.
나타난 오류들을 몇 가지 나열하면 다음과 같으며, 모두 구글링을 통해 해결했다.
 
1. 서비스 계정을 위한 Key 가 등록되지 않은 경우.
이 경우에는, 위에서 언급한 바와 같이 서비스 계정으로 JSON파일을 발급받아 등록했다.

 
2. 환경 변수로 설정한 GCP_ZONE이 올바르지 않은 경우.
ZONE의 의미를 DNS의 주소로 오해하고 잘못 등록해서 발생했던 오류였다. 지역을 의미하는 ZONE이라는 것을 찾아낸 뒤 수정해서 해결했다.

 
3. --command를 반복적으로 사용하여 runner 작성 시 마지막 command만 실행되는 경우.
이전에 작성했던 runner 코드.

  - name : server-on
      run : |-
        gcloud compute ssh --project=${{ secrets.GCP_PROJECT_ID }} --zone=${{ secrets.GCP_ZONE }} ${{ secrets.GCP_VM_NAME }}@${{ secrets.GCP_VM_NAME2 }} \
        --command "cd github-action" \
        --command "docker-compose stop" \
        --command "docker system prune -a" \
        --command "git pull" \
        --command "cd github-action" \
        --command "docker-compose -f /home/zynomark1/github-action/docker-compose.prod.yaml up -d --build" \

이렇게 작성할 경우, 마지막 command만 반영되어 적용되는 문제점이 있었다. 
이 경우, 위에 게시한 내용과 같이 &&연산자를 사용하여 해결할 수 있었는데, 이 연산자는 이전 명령어 완료 후 다음 명령어에 --command 를 적용하는 것과 같은 의미라고 한다. 
 
3. docker-compose.prod.yaml 의 경로를 찾지 못해 발생한 오류.
위의 20번의 workflow 중, 17번은 이 오류때문에 야기되었다.
인스턴스에서는 cd 파일명을 통해 직접 이동 후, build & up을 실행할 수 있었지만
여기서는 절대적인 파일의 위치를 알아야만 해결이 가능했다.

여기서 절대 위치를 파악하는 방법은 인스턴스 내에서 아래 명령어를 입력하면 되는데,
이때 2>/dev/null의 의미는 표준 에러(2)를 find명령어에서 오류 메시지를 출력하고 싶지 않은 경우, 작성한다고 한다. (feat, GPT)

find / -name "찾고자 하는 파일" 2>/dev/null

 

반응형

'개발 > GCP' 카테고리의 다른 글

github-actions CI/CD 사용기  (0) 2023.05.27
GCE - SSL PROVISOINING 문제  (0) 2023.05.26
Comments