# Google Kubernetes Engine에 배포

CD(지속적인 배포) 워크플로의 일부로 GKE(Google Kubernetes Engine)에 프로젝트를 배포하는 방법을 알아보세요.

## 필수 조건

워크플로 만들기를 계속 진행하기 전에 Kubernetes 프로젝트에 대해 다음 단계를 완료해야 합니다. 이 가이드에서는 프로젝트의 루트에 `Dockerfile` 및 Kubernetes 배포 구성 파일이 이미 있다고 가정합니다.

### GKE 클러스터 만들기

GKE 클러스터를 만들려면 먼저 `gcloud` CLI를 사용하여 인증해야 합니다. 이 단계에 대한 자세한 내용은 다음 문서를 참조하세요.

* [`gcloud auth login`](https://cloud.google.com/sdk/gcloud/reference/auth/login)
* [
  `gcloud` Cli](https://cloud.google.com/sdk/gcloud/reference)
* [
  `gcloud` CLI 및 클라우드 SDK](https://cloud.google.com/sdk/gcloud#the_gcloud_cli_and_cloud_sdk)

예시:

```shell copy
$ gcloud container clusters create $GKE_CLUSTER \
    --project=$GKE_PROJECT \
    --zone=$GKE_ZONE
```

### API 활성화

Kubernetes Engine 및 Container Registry API를 사용하도록 설정합니다. 예시:

```shell copy
$ gcloud services enable \
    containerregistry.googleapis.com \
    container.googleapis.com
```

### 서비스 계정 구성 및 자격 증명 저장

이 절차에서는 GKE 통합의 서비스 계정을 만드는 방법을 보여줍니다. 계정을 만들고, 역할을 추가하고, 해당 키를 검색하고, base64로 인코딩된 암호화된 리포지토리 비밀로 `GKE_SA_KEY`저장하는 방법을 설명합니다.

1. 새 서비스 계정을 만듭니다.

   ```shell copy
   gcloud iam service-accounts create $SA_NAME
   ```

2. 방금 만든 서비스 계정의 메일 주소를 검색합니다.

   ```shell copy
   gcloud iam service-accounts list
   ```

3. 서비스 계정에 역할을 추가합니다.

   > \[!NOTE]
   > 요구 사항에 맞게 더 제한적인 역할을 적용합니다.

   ```shell copy
   gcloud projects add-iam-policy-binding $GKE_PROJECT \
     --member=serviceAccount:$SA_EMAIL \
     --role=roles/container.admin
   gcloud projects add-iam-policy-binding $GKE_PROJECT \
     --member=serviceAccount:$SA_EMAIL \
     --role=roles/storage.admin
   gcloud projects add-iam-policy-binding $GKE_PROJECT \
     --member=serviceAccount:$SA_EMAIL \
     --role=roles/container.clusterViewer
   ```

4. 서비스 계정에 대한 JSON 키 파일을 다운로드합니다.

   ```shell copy
   gcloud iam service-accounts keys create key.json --iam-account=$SA_EMAIL
   ```

5. 서비스 계정 키를 `GKE_SA_KEY`라는 비밀로 저장합니다.

   ```shell copy
   export GKE_SA_KEY=$(cat key.json | base64)
   ```

   비밀을 저장하는 방법에 대한 자세한 내용은 [GitHub Actions에서 비밀 사용](/ko/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets)을(를) 참조하세요.

### 프로젝트 이름 저장

프로젝트 이름을 `GKE_PROJECT`라는 비밀로 저장합니다. 비밀을 저장하는 방법에 대한 자세한 내용은 [GitHub Actions에서 비밀 사용](/ko/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets)을(를) 참조하세요.

### (선택 사항) kustomize 구성

kustomize는 YAML 사양을 관리하는 데 사용되는 선택적 도구입니다.
`kustomization` 파일을 만든 후 아래 워크플로를 사용하여 이미지의 필드를 동적으로 설정하고 결과를 `kubectl`로 파이프할 수 있습니다. 자세한 내용은 [kustomize 사용법](https://github.com/kubernetes-sigs/kustomize#usage)을 참조하세요.

### (선택 사항) 배포 환경 구성

환경은 일반적인 배포 대상(예: `production`, `staging` 또는 `development`)을 설명하는 데 사용됩니다. 워크플로가 GitHub Actions 환경에 배포되면 환경이 리포지토리의 기본 페이지에 표시됩니다. 환경을 사용하여 작업이 진행되기 전에 승인을 요구하거나, 워크플로를 트리거할 수 있는 분기를 제한하거나, 사용자 지정 배포 보호 규칙으로 배포를 제어하거나, 비밀 정보에 대한 액세스를 제한할 수 있습니다. 환경을 만드는 방법에 대한 자세한 내용은 [배포 환경 관리](/ko/actions/how-tos/deploy/configure-and-manage-deployments/manage-environments)을(를) 참조하세요.

## 워크플로 만들기

필수 구성 요소를 완료한 후에는 워크플로 만들기를 진행할 수 있습니다.

다음 예시 워크플로에서는 컨테이너 이미지를 빌드하고 GCR에 푸시하는 방법을 보여줍니다. 그런 다음, Kubernetes 도구(예시: `kubectl` 및 `kustomize`)를 사용하여 이미지를 클러스터 배포로 풀합니다.

`env` 키에서 `GKE_CLUSTER` 값을 클러스터 이름으로, `GKE_ZONE`을 클러스터 영역으로, `DEPLOYMENT_NAME`을 배포 이름으로, `IMAGE`를 이미지 이름으로 변경합니다.

배포 환경을 구성한 경우 환경의 이름으로 `environment` 값을 변경합니다. 환경을 구성하지 않은 경우 또는 워크플로가 프라이빗 리포지토리에 있고 GitHub Enterprise Cloud를 사용하지 않는 경우 `environment` 키를 삭제합니다.

```yaml copy
# 이 워크플로는 GitHub에서 인증되지 않은 작업을 사용합니다.
# 작업은 타사에서 제공하며
# 별도의 서비스 약관, 개인정보처리방침, 지원 설명서에서 규정됩니다.
# 참조하세요.

# 커밋 SHA에 작업을 고정하는 것이 좋습니다.
# 최신 버전을 얻으려면 SHA를 업데이트해야 합니다.
# 태그 또는 분기를 참조할 수도 있지만 경고 없이 작업이 변경될 수 있습니다.

name: Build and Deploy to GKE

on:
  push:
    branches:
      - main

env:
  PROJECT_ID: ${{ secrets.GKE_PROJECT }}
  GKE_CLUSTER: cluster-1    # Add your cluster name here.
  GKE_ZONE: us-central1-c   # Add your cluster zone here.
  DEPLOYMENT_NAME: gke-test # Add your deployment name here.
  IMAGE: static-site

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

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

    # Setup gcloud CLI
    - uses: google-github-actions/setup-gcloud@1bee7de035d65ec5da40a31f8589e240eba8fde5
      with:
        service_account_key: ${{ secrets.GKE_SA_KEY }}
        project_id: ${{ secrets.GKE_PROJECT }}

    # Configure Docker to use the gcloud command-line tool as a credential
    # helper for authentication
    - run: |-
        gcloud --quiet auth configure-docker

    # Get the GKE credentials so we can deploy to the cluster
    - uses: google-github-actions/get-gke-credentials@db150f2cc60d1716e61922b832eae71d2a45938f
      with:
        cluster_name: ${{ env.GKE_CLUSTER }}
        location: ${{ env.GKE_ZONE }}
        credentials: ${{ secrets.GKE_SA_KEY }}

    # Build the Docker image
    - name: Build
      run: |-
        docker build \
          --tag "gcr.io/$PROJECT_ID/$IMAGE:$GITHUB_SHA" \
          --build-arg GITHUB_SHA="$GITHUB_SHA" \
          --build-arg GITHUB_REF="$GITHUB_REF" \
          .

    # Push the Docker image to Google Container Registry
    - name: Publish
      run: |-
        docker push "gcr.io/$PROJECT_ID/$IMAGE:$GITHUB_SHA"

    # Set up kustomize
    - name: Set up Kustomize
      run: |-
        curl -sfLo kustomize https://github.com/kubernetes-sigs/kustomize/releases/download/v3.1.0/kustomize_3.1.0_linux_amd64
        chmod u+x ./kustomize

    # Deploy the Docker image to the GKE cluster
    - name: Deploy
      run: |-
        ./kustomize edit set image gcr.io/PROJECT_ID/IMAGE:TAG=gcr.io/$PROJECT_ID/$IMAGE:$GITHUB_SHA
        ./kustomize build . | kubectl apply -f -
        kubectl rollout status deployment/$DEPLOYMENT_NAME
        kubectl get services -o wide
```

## 추가 참고 자료

예시에서 사용된 도구에 대한 자세한 내용은 다음 설명서를 참조하세요.

* 전체 워크플로 템플릿은 ["빌드 및 GKE에 배포" 워크플로](https://github.com/actions/starter-workflows/blob/main/deployments/google.yml)를 참조하세요.
* Kubernetes YAML 사용자 지정 엔진: [Kustomize](https://kustomize.io/)
* Google Kubernetes Engine 설명서의 [컨테이너화된 웹 애플리케이션 배포](https://cloud.google.com/kubernetes-engine/docs/tutorials/hello-app)