Cloud Build로 Google Kubernetes Engine (GKE)에 지속적 배포

1. 개요

이 실습에서는 Cloud Build로 GKE를 위한 지속적 배포 파이프라인을 설정하는 방법을 알아봅니다. 이 실습에서는 다양한 git 이벤트에 대한 Cloud Build 작업을 트리거하는 방법과 GKE에서 자동화된 카나리아 릴리스를 위한 간단한 패턴을 알아봅니다.

다음 단계를 완료합니다.

  • GKE 애플리케이션 만들기
  • git 브랜치 배포 자동화
  • git 기본 브랜치 배포 자동화
  • Git 태그 배포 자동화

2. 시작하기 전에

이 참조 가이드에는 Google Cloud 프로젝트가 필요합니다. 새 프로젝트를 만들거나 이미 만든 프로젝트를 선택할 수 있습니다.

  1. Google Cloud 프로젝트를 선택하거나 만듭니다.

프로젝트 선택기 페이지로 이동

  1. 프로젝트에 결제를 사용 설정합니다.

결제 사용 설정

3. 환경 준비

  1. 이 튜토리얼 전체에서 사용할 환경 변수를 만듭니다.
    export PROJECT_ID=$(gcloud config get-value project)
    export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
    
    export ZONE=us-central1-b
    export CLUSTER=gke-progression-cluster
    export APP_NAME=myapp
    
  2. 다음 API를 사용 설정합니다.
    • Resource Manager
    • GKE
    • Cloud Source Repositories
    • Cloud Build
    • Container Registry
    gcloud services enable \
        cloudresourcemanager.googleapis.com \
        container.googleapis.com \
        sourcerepo.googleapis.com \
        cloudbuild.googleapis.com \
        containerregistry.googleapis.com \
        --async
    
  3. 샘플 소스를 클론하고 실습 디렉터리로 전환합니다.
    git clone https://github.com/GoogleCloudPlatform/software-delivery-workshop.git gke-progression
    
    cd gke-progression/labs/gke-progression
    rm -rf ../../.git
    
  4. 샘플 저장소의 자리표시자 값을 PROJECT_ID로 바꿉니다. 이 단계에서는 현재 환경에 고유한 다양한 구성 파일의 인스턴스를 만듭니다. 업데이트되는 템플릿의 예를 검토하려면 다음 명령어를 실행합니다.
    cat k8s/deployments/dev/frontend-dev.yaml.tmpl
    
    다음 명령어를 실행하여 변수 대체를 실행합니다.
    for template in $(find . -name '*.tmpl'); do envsubst '${PROJECT_ID} ${ZONE} ${CLUSTER} ${APP_NAME}' < ${template} > ${template%.*}; done
    
    대체 후 파일 예시를 검토하려면 다음 명령어를 실행합니다.
    cat k8s/deployments/dev/frontend-dev.yaml
    
  5. 이전에 Cloud Shell에서 Git을 사용한 적이 없는 경우 사용할 user.nameuser.email 값을 설정합니다.
    git config --global user.email "YOUR_EMAIL_ADDRESS"
    git config --global user.name "YOUR_USERNAME"
    
  6. 샘플 저장소의 코드를 Cloud Source Repositories에 저장합니다.
    gcloud source repos create gke-progression
    git init
    git config credential.helper gcloud.sh
    git remote add gcp https://source.developers.google.com/p/$PROJECT_ID/r/gke-progression
    git branch -m main
    git add . && git commit -m "initial commit"
    git push gcp main
    
  7. GKE 클러스터를 만듭니다.
    gcloud container clusters create ${CLUSTER} \
        --project=${PROJECT_ID} \
        --zone=${ZONE}
    
  8. Cloud Build에 클러스터에 대한 권한을 부여합니다.Cloud Build에서 애플리케이션을 GKE 클러스터에 배포하며, 이 작업을 수행하려면 권한이 필요합니다.
    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member=serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
        --role=roles/container.developer
    

환경이 준비되었습니다.

4. GKE 애플리케이션 만들기

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

  1. Cloud Build로 애플리케이션을 빌드합니다.
    gcloud builds submit --tag gcr.io/$PROJECT_ID/$APP_NAME:1.0.0 src/
    
  2. 카나리아 및 프로덕션 환경에 수동으로 배포:kubectl apply 명령어를 사용하여 프로덕션 및 카나리아 배포와 서비스를 만듭니다.
    kubectl create ns production
    kubectl apply -f k8s/deployments/prod -n production
    kubectl apply -f k8s/deployments/canary -n production
    kubectl apply -f k8s/services -n production
    
    여기에 배포된 서비스는 트래픽을 카나리아 및 프로덕션 배포로 모두 라우팅합니다.
  3. 실행 중인 포드 수를 검토합니다. 프로덕션 트래픽용 포드 3개와 카나리아 릴리스용 포드 1개를 포함하여 프런트엔드에서 실행 중인 포드가 4개 있는지 확인합니다. 즉, 카나리아 릴리스에 대한 변경사항은 사용자 4명 중 1명 (25%)에게만 영향을 미칩니다.
    kubectl get pods -n production -l app=$APP_NAME -l role=frontend
    
  4. 프로덕션 서비스의 외부 IP 주소를 검색합니다.를 통해 개인정보처리방침을 정의할 수 있습니다.
    kubectl get service $APP_NAME -n production
    
    부하 분산기가 IP 주소를 반환하면 다음 단계로 진행합니다.
  5. 나중에 사용할 수 있도록 외부 IP를 저장합니다.
    export PRODUCTION_IP=$(kubectl get -o jsonpath="{.status.loadBalancer.ingress[0].ip}"  --namespace=production services $APP_NAME)
    
  6. 애플리케이션을 검토합니다. 서비스의 버전 출력을 확인합니다. Hello World v1.0이 표시됩니다.
    curl http://$PRODUCTION_IP
    

축하합니다. 샘플 앱을 배포했습니다. 이제 변경사항을 지속적으로 배포하기 위한 트리거를 설정합니다.

5. git 브랜치에 대한 배포 자동화

이 섹션에서는 main 이외의 브랜치가 커밋될 때 Cloudbuild 작업을 실행하는 트리거를 설정합니다. 여기에 사용된 Cloud Build 파일은 기존 또는 새 브랜치의 네임스페이스와 배포를 자동으로 생성하므로 개발자는 기본 브랜치와 통합하기 전에 코드를 미리 볼 수 있습니다.

  1. 트리거 설정:이 트리거의 핵심 구성요소는 branchName 매개변수를 사용하여 main와 일치하고 invertRegex 매개변수를 사용하여 true로 설정되고 main가 아닌 모든 항목과 일치하도록 branchName 패턴을 변경하는 것입니다. build/branch-trigger.json에서 다음 행을 참고하세요.
      "branchName": "main",
      "invertRegex": true
    
    또한 이 트리거와 함께 사용되는 Cloud Build 파일의 마지막 몇 줄은 작업을 트리거한 브랜치의 이름을 딴 네임스페이스를 만든 다음 새 네임스페이스 내에 애플리케이션과 서비스를 배포합니다. build/branch-cloudbuild.yaml
      kubectl get ns ${BRANCH_NAME} || kubectl create ns ${BRANCH_NAME}
      kubectl apply --namespace ${BRANCH_NAME} --recursive -f k8s/deployments/dev
      kubectl apply --namespace ${BRANCH_NAME} --recursive -f k8s/services
    
    에서 다음 행을 참고하시기 바랍니다. 이제 사용 메커니즘을 이해했으니 아래의 gcloud 명령어를 사용해 트리거를 만듭니다.
    gcloud beta builds triggers create cloud-source-repositories \
      --trigger-config build/branch-trigger.json
    
  2. 트리거를 검토하려면 Console의 Cloud Build 트리거 페이지로 이동합니다.트리거로 이동
  3. 새 브랜치를 만듭니다.
    git checkout -b new-feature-1
    
  4. v1.1을 나타내도록 코드를 수정하고 src/app.py를 수정하고 응답을 1.0에서 1.1로 변경합니다.
    @app.route('/')
    def hello_world():
        return 'Hello World v1.1'
    
  5. 변경사항을 커밋하고 원격 저장소로 푸시합니다.
    git add . && git commit -m "updated" && git push gcp new-feature-1
    
  6. 진행 중인 빌드를 검토하려면 콘솔의 Cloud Build 기록 페이지로 이동합니다.빌드로 이동빌드가 완료되면 다음 단계로 진행합니다.
  7. 새로 배포된 브랜치 서비스의 외부 IP 주소를 검색합니다.를 통해 개인정보처리방침을 정의할 수 있습니다.
    kubectl get service $APP_NAME -n new-feature-1
    
    부하 분산기가 IP 주소를 반환하면 다음 단계로 진행합니다.
  8. 나중에 사용할 수 있도록 외부 IP를 저장합니다.
    export BRANCH_IP=$(kubectl get -o jsonpath="{.status.loadBalancer.ingress[0].ip}"  --namespace=new-feature-1 services $APP_NAME)
    
  9. 애플리케이션을 검토합니다.서비스의 버전 출력을 확인합니다. Hello World v1.0이 표시됩니다.
    curl http://$BRANCH_IP
    

6. git 기본 브랜치에 대한 배포 자동화

코드가 프로덕션으로 출시되기 전에 모든 트래픽을 새 코드베이스로 이전하기 전에 실시간 트래픽의 일부에 코드를 출시하는 것이 일반적입니다.

이 섹션에서는 코드가 기본 브랜치에 커밋되었을 때 활성화되는 트리거를 구현합니다. 트리거가 모든 실시간 트래픽의 25% 를 새 버전으로 수신하는 카나리아 배포를 배포합니다.

  1. 기본 브랜치의 트리거를 설정합니다.
    gcloud beta builds triggers create cloud-source-repositories \
      --trigger-config build/main-trigger.json
    
  2. 새 트리거를 검토하려면 Console의 Cloud Build 트리거 페이지로 이동하세요.트리거로 이동
  3. 브랜치를 메인 줄에 병합하고 원격 저장소로 푸시합니다.
    git checkout main
    git merge new-feature-1
    git push gcp main
    
  4. 진행 중인 빌드를 검토하려면 콘솔의 Cloud Build 기록 페이지로 이동합니다.빌드로 이동빌드가 완료되면 다음 단계로 진행합니다.
  5. serverRun에서 다음 명령어를 여러 개 검토하고 응답 중 약 25% 가 Hello World v1.1의 새 응답을 표시합니다.
    while true; do curl -w "\n" http://$PRODUCTION_IP; sleep 1;  done
    
    계속할 준비가 되면 Ctrl+c를 눌러 루프를 종료합니다.

7. git 태그에 대한 배포 자동화

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

이 섹션에서는 저장소에서 태그를 만들 때 활성화되는 트리거를 설정합니다. 트리거는 적절한 태그로 이미지에 라벨을 지정한 다음 업데이트를 프로덕션에 배포하여 트래픽의 100% 가 태그된 이미지에 액세스할 수 있도록 합니다.

  1. 태그 트리거를 설정합니다.
    gcloud beta builds triggers create cloud-source-repositories \
      --trigger-config build/tag-trigger.json
    
  2. 새 트리거를 검토하려면 Console의 Cloud Build 트리거 페이지로 이동하세요.트리거로 이동
  3. 새 태그를 만들고 원격 저장소로 푸시합니다.
    git tag 1.1
    git push gcp 1.1
    
  4. 진행 중인 빌드를 검토하려면 Console의 Cloud Build 기록 페이지로 이동합니다.빌드로 이동
  5. serverRun의 여러 응답을 검토하고 다음 명령어를 실행하고 응답에 100% 가 Hello World v1.1의 새 응답을 표시하는 것을 확인합니다. 새 포드가 배포되고 GKE 내에서 상태를 확인하는 동안 잠시 시간이 걸릴 수 있습니다.
    while true; do curl -w "\n" http://$PRODUCTION_IP; sleep 1;  done
    
    계속할 준비가 되면 Ctrl+c를 눌러 루프를 종료하세요.축하합니다! Cloud Build에서 앱을 GKE에 배포하기 위한 브랜치 및 태그에 대해 CI/CD 트리거를 만들었습니다.

8. 삭제

프로젝트 삭제

  1. Cloud 콘솔에서 리소스 관리 페이지로 이동합니다.
  2. 프로젝트 목록에서 삭제할 프로젝트를 선택하고 삭제를 클릭합니다.
  3. 대화상자에서 프로젝트 ID를 입력하고 종료를 클릭하여 프로젝트를 삭제합니다.