Git 분기 및 Cloud Build로 Cloud Run 카나리아 배포 구현

Last reviewed 2023-05-26 UTC

이 문서에서는 자동화된 카나리아 테스트 및 백분율에 기반한 트래픽 관리로 개발자 분기에서 프로덕션으로의 코드 진행을 구현하는 Cloud Run에 대해 배포 파이프라인을 구현하는 방법을 보여줍니다. 이 문서는 CI/CD 파이프라인을 만들고 관리하는 플랫폼 관리자를 대상으로 합니다. 이 문서에서는 사용자가 Git, Cloud Run, CI/CD 파이프라인 개념을 기본적으로 이해하고 있다고 가정합니다.

Cloud Run을 사용하면 약간의 오버헤드 또는 노력만으로 애플리케이션을 배포하고 실행할 수 있습니다. 많은 조직은 코드를 프로덕션으로 이동하기 위해 강력한 출시 파이프라인을 사용합니다. Cloud Run은 약간의 노력만으로 고급 출시 관리 기법을 구현할 수 있게 해주는 고유한 트래픽 관리 기능을 제공합니다.

목표

  • Cloud Run 서비스 만들기
  • 개발자 분기 사용 설정
  • 카나리아 테스트 구현
  • 프로덕션에 안전하게 출시

비용

이 문서에서는 비용이 청구될 수 있는 다음과 같은 Google Cloud 구성요소를 사용합니다.

프로젝트 사용량을 기준으로 예상 비용을 산출하려면 가격 계산기를 사용하세요. Google Cloud를 처음 사용하는 사용자는 무료 체험판을 사용할 수 있습니다.

시작하기 전에

  1. Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.

    프로젝트 선택기로 이동

  2. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  3. Google Cloud 콘솔에서 Cloud Shell을 활성화합니다.

    Cloud Shell 활성화

    Google Cloud 콘솔 하단에서 Cloud Shell 세션이 시작되고 명령줄 프롬프트가 표시됩니다. Cloud Shell은 Google Cloud CLI가 사전 설치된 셸 환경으로, 현재 프로젝트의 값이 이미 설정되어 있습니다. 세션이 초기화되는 데 몇 초 정도 걸릴 수 있습니다.

환경 준비

  1. Cloud Shell에서 이 튜토리얼 전체에서 사용할 환경 변수를 만듭니다.

    export PROJECT_ID=$(gcloud config get-value project)
    export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
    
  2. 다음 API를 사용 설정합니다.

    • Resource Manager
    • GKE
    • Cloud Build
    • Container Registry
    • Cloud Run
    gcloud services enable \
        cloudresourcemanager.googleapis.com \
        container.googleapis.com \
        secretmanager.googleapis.com \
        cloudbuild.googleapis.com \
        containerregistry.googleapis.com \
        run.googleapis.com
    
  3. Cloud Build 서비스 계정에 Cloud Run 관리자 역할(roles/run.admin)을 부여합니다.

    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member=serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com \
      --role=roles/run.admin
    
  4. Cloud Run 런타임 서비스 계정의 Cloud Build 서비스 계정에 IAM 서비스 계정 사용자 역할(roles/iam.serviceAccountUser)을 부여합니다.

    gcloud iam service-accounts add-iam-policy-binding \
    $PROJECT_NUMBER-compute@developer.gserviceaccount.com \
      --member=serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com \
      --role=roles/iam.serviceAccountUser
    

Git 값 설정

이전에 Cloud Shell에서 Git을 사용하지 않았으면 사용하려는 user.nameuser.email 값을 설정합니다.

    git config --global user.email YOUR_EMAIL_ADDRESS
    git config --global user.name YOUR_USERNAME
    git config --global credential.helper store
  • YOUR_EMAIL_ADDRESS: GitHub 계정에 사용되는 이메일입니다.
  • YOUR_USERNAME: GitHub 사용자 ID입니다.

GitHub에서 MFA를 사용하는 경우 개인 액세스 토큰을 만들고 명령줄을 통해 GitHub와 상호작용할 때 이를 비밀번호로 사용합니다.

더 쉽게 액세스할 수 있도록 GitHub 사용자 ID를 환경 변수에 저장합니다.

export GH_USER=YOUR_GITHUB_ID

프로젝트 저장소 포크

나만의 쓰기 가능한 실습 저장소 버전을 만들려면 GitHub UI를 통해 샘플 저장소를 GitHub 계정으로 포크합니다.

샘플 저장소 복제

샘플 저장소를 클론하고 준비합니다.

git clone https://github.com/$GH_USER/software-delivery-workshop.git cloudrun-progression

cd cloudrun-progression/labs/cloudrun-progression

Git 저장소 연결

Cloud Build를 사용하면 Google Cloud 콘솔을 사용하여 소스 코드 저장소에 대한 연결을 만들고 관리할 수 있습니다. 1세대 또는 2세대 Cloud Build 저장소를 사용하여 연결을 만들고 관리할 수 있습니다. 이 튜토리얼에서는 2세대 Cloud Build 저장소를 사용합니다.

필요한 권한 부여

GitHub 호스트를 연결하려면 사용자 계정에 Cloud Build 연결 관리자(roles/cloudbuild.connectionAdmin) 역할을 부여합니다.

PN=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)")
CLOUD_BUILD_SERVICE_AGENT="service-${PN}@gcp-sa-cloudbuild.iam.gserviceaccount.com"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
 --member="serviceAccount:${CLOUD_BUILD_SERVICE_AGENT}" \
 --role="roles/secretmanager.admin"

호스트 연결 만들기

  1. Cloud Build 저장소 연결을 구성합니다.

    gcloud alpha builds connections create github $GH_USER --region=us-central1
    
  2. 출력에 제공된 링크를 클릭하고 화면 안내에 따라 연결을 완료합니다.

  3. GitHub 연결 설치를 확인합니다.

    gcloud alpha builds connections describe $GH_USER --region=us-central1
    

방금 구성한 호스트 연결을 사용하여 포크한 샘플 저장소에 연결합니다.

 gcloud alpha builds repositories create cloudrun-progression \
     --remote-uri=https://github.com/$GH_USER/software-delivery-workshop.git \
     --connection=$GH_USER \
     --region=us-central1

저장소 이름 변수 설정

나중에 사용할 수 있도록 저장소 이름을 저장합니다.

export REPO_NAME=projects/$PROJECT_ID/locations/us-central1/connections/$GH_USER/repositories/cloudrun-progression

Cloud Run 서비스 배포

이 섹션에서는 이 튜토리얼 전체에서 사용되는 초기 프로덕션 애플리케이션을 빌드하고 배포합니다.

서비스 배포

  • Cloud Shell에서 인증이 필요한 서비스를 포함하여 애플리케이션을 빌드하고 배포합니다. 공개 서비스를 만들려면 --allow-unauthenticated 플래그를 사용합니다.

        gcloud builds submit --tag gcr.io/$PROJECT_ID/hello-cloudrun
    
        gcloud run deploy hello-cloudrun \
          --image gcr.io/$PROJECT_ID/hello-cloudrun \
          --platform managed \
          --region us-central1 \
          --tag=prod -q
    

    출력은 다음과 같이 표시됩니다.

    Deploying container to Cloud Run service [hello-cloudrun] in project [sdw-mvp6] region [us-central1]
    ✓ Deploying new service... Done.
      ✓ Creating Revision...
      ✓ Routing traffic...
    Done.
    Service [hello-cloudrun] revision [hello-cloudrun-00001-tar] has been deployed and is serving 100 percent of traffic.
    Service URL: https://hello-cloudrun-apwaaxltma-uc.a.run.app
    The revision can be reached directly at https://prod---hello-cloudrun-apwaaxltma-uc.a.run.app
    

출력에는 서비스 URL과 버전의 고유 URL이 포함됩니다. 사용자의 실제 값은 여기에 표시된 것과 약간 다를 것입니다.

배포 검증

  1. 배포가 완료되면 Cloud 콘솔에서 버전 페이지에서 새로 배포된 서비스를 확인합니다.

  2. Cloud Shell에서 인증된 서비스 응답을 확인합니다.

    PROD_URL=$(gcloud run services describe hello-cloudrun --platform managed --region us-central1 --format=json | jq --raw-output ".status.url")
    
    echo $PROD_URL
    
    curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" $PROD_URL
    

브랜치 배포 사용 설정

이 섹션에서는 Git에서 개발 분기에 대해 고유 URL을 사용 설정합니다.

브랜치 트리거 설정

각 브랜치는 브랜치 이름으로 식별된 URL로 표시됩니다. 브랜치를 커밋하면 배포가 트리거되고 동일한 URL에서 업데이트에 액세스할 수 있습니다.

  1. Cloud Shell에서 트리거를 설정합니다.

    gcloud alpha builds triggers create github \
    --name=branchtrigger \
    --repository=$REPO_NAME \
    --branch-pattern='[^(?!.*main)].*' \
    --build-config=labs/cloudrun-progression/branch-cloudbuild.yaml \
    --region=us-central1
    
  2. 트리거를 검토하려면 Cloud 콘솔에서 Cloud Build 트리거 페이지로 이동합니다.

브랜치에서 변경사항 만들기

  1. Cloud Shell에서 새 분기를 만듭니다.

    git checkout -b new-feature-1
    
  2. 원하는 편집기 또는 Cloud Shell IDE를 사용하여 샘플 애플리케이션을 엽니다.

    edit app.py
    
  3. 샘플 애플리케이션에서 v1.0 대신 v1.1을 나타내도록 24행을 수정합니다.

    @app.route('/')
    
    def hello_world():
        return 'Hello World v1.1'
    
    
  4. 터미널로 돌아가려면 터미널 열기를 클릭합니다.

브랜치 트리거 실행

  1. Cloud Shell에서 변경사항을 커밋하고 원격 저장소로 푸시합니다.

    git add . && git commit -m "updated" && git push origin new-feature-1
    
  2. 진행 중인 빌드를 검토하려면 Cloud Build 빌드 기록 화면으로 이동합니다.

  3. 새 버전을 검토하려면 빌드가 완료된 후 Cloud 콘솔에서 Cloud Run 버전 페이지로 이동합니다.

  4. Cloud Shell에서 이 분기의 고유 URL을 가져옵니다.

    BRANCH_URL=$(gcloud run services describe hello-cloudrun --platform managed --region us-central1 --format=json | jq --raw-output ".status.traffic[] | select (.tag==\"new-feature-1\")|.url")
    
    echo $BRANCH_URL
    
  5. 인증된 URL에 액세스합니다.

    curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" $BRANCH_URL
    

    업데이트된 응답 출력이 다음과 같이 표시됩니다.

    Hello World v1.1
    

카나리아 테스트 자동화

코드가 프로덕션에 출시되면 모든 트래픽을 새로운 코드베이스로 마이그레이션하기 전에 라이브 트래픽 중 일부에 코드를 출시하는 것이 일반적입니다.

이 섹션에서는 코드가 기본 브랜치에 커밋되었을 때 활성화되는 트리거를 구현합니다. 이 트리거는 코드를 고유한 카나리아 URL에 배포하고 모든 라이브 트래픽 중 10%를 새 버전에 라우팅합니다.

  1. Cloud Shell에서 분기 트리거를 설정합니다.

    gcloud alpha builds triggers create github \
      --name=maintrigger \
      --repository=$REPO_NAME \
      --branch-pattern=main \
      --build-config=labs/cloudrun-progression/main-cloudbuild.yaml \
      --region=us-central1
    
  2. 새 트리거를 검토하려면 Cloud 콘솔에서 Cloud Build 트리거 페이지로 이동합니다.

  3. Cloud Shell에서 브랜치를 기본 줄에 병합하고 원격 저장소에 푸시합니다.

    git checkout main
    git merge new-feature-1
    git push origin main
    
  4. 진행 중인 빌드를 검토하려면 Cloud Build 빌드 페이지로 이동합니다.

  5. 빌드가 완료된 후 새 버전을 검토하려면 Cloud 콘솔에서 Cloud Run 버전 페이지로 이동합니다. 트래픽의 90%가 프로덕션으로 라우팅되고, 10%가 카나리아로 라우팅되고, 0%가 브랜치 버전으로 라우팅됩니다.

카나리아 배포에 대해 논리를 구현하는 main-cloudbuild.yaml의 핵심 행을 검토합니다.

39~45행은 새 버전을 배포하고 태그 플래그를 사용하여 고유 카나리아 URL의 트래픽을 라우팅합니다.

gcloud run deploy ${_SERVICE_NAME} \
--platform managed \
--region ${_REGION} \
--image gcr.io/${PROJECT_ID}/${_SERVICE_NAME} \
--tag=canary \
--no-traffic

61행은 배포의 Git 단축 SHA를 확인하는 정적 태그를 버전에 추가합니다.

gcloud beta run services update-traffic ${_SERVICE_NAME} --update-tags=sha-$SHORT_SHA=$${CANARY} --platform managed --region ${_REGION}

62행은 90%를 프로덕션으로 라우팅하고 10%를 카나리아로 라우팅하도록 트래픽을 업데이트합니다.

gcloud run services update-traffic ${_SERVICE_NAME} --to-revisions=$${PROD}=90,$${CANARY}=10 --platform managed --region ${_REGION}
  1. Cloud Shell에서 카나리아 버전에 대해 고유 URL을 가져옵니다.

    CANARY_URL=$(gcloud run services describe hello-cloudrun --platform managed --region us-central1 --format=json | jq --raw-output ".status.traffic[] | select (.tag==\"canary\")|.url")
    
    echo $CANARY_URL
    
  2. 카나리아 엔드포인트를 직접 검토합니다.

    curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" $CANARY_URL
    
  3. 백분율 기반 응답을 보려면 다음 일련의 요청을 수행합니다.

    LIVE_URL=$(gcloud run services describe hello-cloudrun --platform managed --region us-central1 --format=json | jq --raw-output ".status.url")
    for i in {0..20};do
      curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" $LIVE_URL; echo \n
    done
    

프로덕션으로 출시

트래픽 일부를 사용해서 카나리아 배포가 검증된 다음에는 나머지 라이프 트래픽에 배포를 출시합니다.

이 섹션에서는 저장소에서 태그를 만들 때 활성화되는 트리거를 설정합니다. 이 트리거는 태그의 커밋 SHA를 기준으로 이미 배포된 버전으로 트래픽 100%를 마이그레이션합니다. 커밋 SHA를 사용하면 카나리아 트래픽으로 검증된 버전이 나머지 프로덕션 트래픽에 사용되도록 보장합니다.

  1. Cloud Shell에서 태그 트리거를 설정합니다.

    gcloud alpha builds triggers create github \
      --name=tagtrigger \
      --repository=$REPO_NAME \
      --tag-pattern=. \
      --build-config=labs/cloudrun-progression/tag-cloudbuild.yaml \
      --region=us-central1
    
  2. 새 트리거를 검토하려면 Cloud 콘솔에서 Cloud Build 트리거 페이지로 이동합니다.

  3. Cloud Shell에서 새 태그를 만들고 원격 저장소에 푸시합니다.

    git tag 1.1
    git push origin 1.1
    
  4. 진행 중인 빌드를 검토하려면 Cloud 콘솔에서 Cloud Build 빌드 기록 화면으로 이동합니다.

  5. 빌드가 완료된 후 새 버전을 검토하려면 Cloud 콘솔에서 Cloud Run 버전 페이지로 이동합니다. 버전은 프로덕션 태그를 나타내도록 업데이트되고 실시간 트래픽을 100% 제공합니다.

  6. Cloud Shell에서 백분율 기반 응답을 보려면 다음 일련의 요청을 수행합니다.

    LIVE_URL=$(gCloud Run services describe hello-cloudrun --platform managed --region us-central1 --format=json | jq --raw-output ".status.url")
    
    for i in {0..20};do
      curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" $LIVE_URL; echo \n
    done
    
  7. 프로덕션 배포 논리를 구현하는 tag-cloudbuild.yaml의 핵심 행을 검토합니다.

    37행은 프로덕션 태그를 추가하는 카나리아 버전을 업데이트합니다. 배포된 버전은 이제 프로덕션 및 카나리아에 대해 모두 태그가 지정됩니다.

    gcloud beta run services update-traffic ${_SERVICE_NAME} --update-tags=prod=$${CANARY} --platform managed --region ${_REGION}
    

    39행은 프로덕션으로 태그가 지정된 버전으로 트래픽 100%를 라우팅하도록 기본 서비스 URL의 트래픽을 업데이트합니다.

    gcloud run services update-traffic ${_SERVICE_NAME} --to-revisions=$${NEW_PROD}=100 --platform managed --region ${_REGION}
    

삭제

이 튜토리얼에서 사용된 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 리소스가 포함된 프로젝트를 삭제하거나 프로젝트를 유지하고 개별 리소스를 삭제하세요.

  1. Google Cloud 콘솔에서 리소스 관리 페이지로 이동합니다.

    리소스 관리로 이동

  2. 프로젝트 목록에서 삭제할 프로젝트를 선택하고 삭제를 클릭합니다.
  3. 대화상자에서 프로젝트 ID를 입력한 후 종료를 클릭하여 프로젝트를 삭제합니다.

다음 단계