Search

Github Actions와 Docker Hub를 활용한 Google Cloud CI/CD 환경 구축하기

생성일
2025/01/09

선행 조건

CI/CD 환경을 구축하기 위해서는 몇 가지 선행 조건을 충족해야 한다.
아래는 환경 구축 전에 준비해야 할 항목들이다.
Google Cloud Compute Engine VM 인스턴스에 dockerdocker-compose 설치
Docker Hub 계정 생성
배포할 API 서버

CI/CD 파이프라인 구축 방법

위의 선행 조건을 모두 준비하면, Github Actions를 사용하여 Docker 이미지를 빌드하고, Docker Hub에 푸시한 후, Google Cloud에 자동으로 배포하는 CI/CD 파이프라인을 구축할 수 있다.

1. Compute engine SSH 키 쌍 생성

Google Cloud에 SSH를 사용하여 연결하기 위한 비밀 키 파일을 생성해야 한다.
ssh-keygen -t rsa -b 2048 -f ~/.ssh/gcp_compute_key
YAML
복사

2. Google Cloud Console에서 SSH 공개 키 추가

Google Cloud Console → Compute Engine → VM 인스턴스 → 인스턴스 선택 후 “편집” 버튼 클릭
“SSH 키” 항목에서 “항목 추가” 버튼 클릭
gcp_compute_key.pub 파일의 내용을 복사 후 붙여넣기

3. gcloud 접근 권한 설정

깃허브 액션(GitHub Actions)이 Google Cloud에 안전하게 접근하기 위해서는 워크로드 아이덴티티(Workload Identity)를 사용하여 인증을 구성해야 한다.
아래는 워크로드 아이덴티티를 설정하는 과정이다.

워크로드 아이덴티티 설정

워크로드 아이덴티티(Workload Identity)는 Google Cloud에서 GitHub Actions과 같은 외부 시스템이 Google Cloud 리소스에 안전하게 액세스할 수 있도록 하는 기능이다.
워크로드 아이덴티티 풀 생성
gcloud iam workload-identity-pools create "github-actions-pool" \ --project="${PROJECT_ID}" \ --location="global" \ --display-name="github-actions-pool"
Shell
복사
[트러블 슈팅] PERMISSION_DENIED: Request had insufficient authentication scopes
생성한 워크로드 아이덴티티 풀의 ID 조회
gcloud iam workload-identity-pools describe "github-actions-pool" \ --project="${PROJECT_ID}" \ --location="global" \ --format="value(name)"
Shell
복사
조회된 ID는 추후 깃허브 액션과의 연동을 위해 메모
워크로드 아이덴티티 풀에 인증 공급자(Github Actions) 추가
gcloud iam workload-identity-pools providers create-oidc "github-actions-provider" \ --project="${PROJECT_ID}" \ --location="global" \ --workload-identity-pool="github-actions-pool" \ --display-name="GitHub Actions OIDC Provider" \ --attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.aud=assertion.aud,attribute.repository=assertion.repository" \ --attribute-condition="attribute.repository==assertion.repository" \ --issuer-uri="https://token.actions.githubusercontent.com"
Shell
복사
[트러블 슈팅] INVALID_ARGUMENT: The attribute condition must reference one of the provider's claims.

IAM 서비스 계정 생성

깃허브 액션에서 Google Cloud 리소스에 접근할 수 있도록 IAM 서비스 계정을 생성해준다.
서비스 계정은 Google Cloud 리소스를 인증하고 권한을 부여하는 역할을 한다.
IAM 서비스 계정 생성
gcloud iam service-accounts create github-actions-sa \ --project="${PROJECT_ID}" \ --display-name="GitHub Actions Service Account"
Shell
복사
서비스 계정에 역할 할당
Github Actions에서 접근할 리소스에 접근 권한을 부여한다.
GCP UI → IAM 및 관리자 → IAM → 액세스 권한 부여 → Compute 관리자 역할 부여
서비스 계정 권한 부여
gcloud iam service-accounts add-iam-policy-binding "github-actions-sa@${PROJECT_ID}.iam.gserviceaccount.com" \ --project="${PROJECT_ID}" \ --role="roles/iam.workloadIdentityUser" \ --member="principalSet://iam.googleapis.com/${WORKLOAD_IDENTITY_POOL_ID}/attribute.repository/${REPO_AUTHOR_NAME}/${REPO_NAME}"
Shell
복사
gcloud iam service-accounts add-iam-policy-binding \ "my-service-account@developer.gserviceaccount.com" \ --member="serviceAccount:github-actions-sa@${PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/iam.serviceAccountUser"
Shell
복사
IAM 정책에 서비스 계정 역할 추가
gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:my-service-account@developer.gserviceaccount.com" \ --role="roles/iap.tunnelResourceAccessor"
Shell
복사

깃허브 Secrets 설정

WORKLOAD_IDENTITY_PROVIDER_ID
projects/{프로젝트 번호}/locations/global/workloadIdentityPools/github-actions-pool/providers/github-actions-provider
SERVICE_ACCOUNT
github-actions-sa@{프로젝트 번호}.iam.gserviceaccount.com

4. Github Actions CI/CD 파일 작성

name: CI/CD Pipeline # main 브랜치에 대한 Pull request 및 Merge on: pull_request : branches : - main push: branches: - main workflow_dispatch: jobs: build: runs-on: ubuntu-latest permissions : id-token : write contents : read pull-requests : write steps: # 1. 레포지토리 소스 코드 작업 환경으로 가져오기 - name: Checkout Repository uses: actions/checkout@v3 # 2. 환경변수(.env) 파일 생성 - name: Set Environment File run: | echo "${{ secrets.PROD_ENV }}" > .env chmod 644 .env cat .env # 3. 도커허브 로그인 - name: Login to DockerHub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} # 4. 도커 허브에 이미지 푸시 - name: Push Docker Image uses: docker/build-push-action@v6 with: push: true context: . tags: ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_IMAGE_NAME }}:latest # 5. GCP 인증 - name: Authenticate to GCP id: 'auth' uses: 'google-github-actions/auth@v2' with: workload_identity_provider: ${{ secrets.WORKLOAD_IDENTITY_PROVIDER }} # 생성한 워크로드 아이덴티티 풀의 ID service_account: ${{ secrets.SERVICE_ACCOUNT_EMAIL }} # IAM 서비스 계정 # 6. GCP Compute Engine SSH로 배포 - name: Deploy to GCP Compute Engine id: 'compute-ssh' uses: 'google-github-actions/ssh-compute@v1' with: instance_name: ${{ secrets.GCP_INSTANCE_NAME }} zone: ${{ secrets.GCP_INSTANCE_ZONE }} ssh_private_key: ${{ secrets.GCP_SSH_PRIVATE_KEY }} command: 'echo Hello world'
YAML
복사

참고 자료