Spinnaker 및 Google Kubernetes Engine을 사용한 지속적 배포 파이프라인

이 가이드는 Google Cloud용 Google Kubernetes Engine(GKE), Cloud Source Repositories, Cloud Build, Spinnaker를 사용하여 지속적 배포 파이프라인을 만드는 방법을 보여줍니다. 샘플 앱을 만든 후 이러한 서비스를 구성하여 앱을 자동으로 빌드, 테스트, 배포합니다. 앱 코드를 수정하면 변경사항으로 인해 지속적 배포 파이프라인이 트리거되어 새 버전이 자동으로 다시 빌드, 테스트, 배포됩니다.

파이프라인 아키텍처

다음 다이어그램은 지속적 배포 파이프라인의 아키텍처를 나타낸 것입니다.

개발자와 사용자를 위한 파이프라인 아키텍처

사용자에게 앱 업데이트를 지속적으로 배포하려면 소프트웨어를 안정적으로 빌드, 테스트, 업데이트하는 자동화된 프로세스가 필요합니다. 코드 변경사항이 아티팩트 생성, 단위 테스트, 기능 테스트, 프로덕션 출시를 포함하는 파이프라인을 자동으로 통과하도록 해야 합니다. 경우에 따라서는 코드 업데이트를 전체 사용자층에 푸시하기 전에 실사용 시험을 거치기 위해 사용자 중 일부에만 적용할 수도 있어야 합니다. 이러한 카나리아 릴리스 중 하나에서 문제점이 드러날 경우 자동화된 절차를 통해 소프트웨어 변경사항을 빠르게 롤백할 수 있어야 합니다.

GKE와 Spinnaker를 사용하면 개발 및 검증을 거친 소프트웨어를 최대한 빠르게 출시하는 데 도움이 되는 견고한 지속적 배포 흐름을 만들 수 있습니다. 최종 목표는 개발 주기를 더 빠르게 하는 것이지만, 앱에 수정사항이 있을 때마다 프로덕션 출시를 고려하기 전에 먼저 일련의 자동화된 검증 절차를 통과하도록 해야 합니다. 변경사항이 자동화된 테스트를 통과하면 앱을 수동으로 검증하고 추가적인 출시 전 테스트를 수행하면 됩니다.

팀에서 앱이 프로덕션 적용 준비가 된 것으로 판정되면 팀원 중 한 명이 앱을 프로덕션에 배포하도록 승인할 수 있습니다.

앱 배포 파이프라인

본 가이드에서는 아래 다이어그램에 표시된 지속적 배포 파이프라인을 구축합니다.

앱 전송 파이프라인 아키텍처

위 파이프라인에서 설명하는 간략한 단계는 다음과 같습니다.

  1. 개발자가 코드를 변경하여 저장소에 푸시합니다.

  2. Cloud Build가 변경을 감지하고 Docker 이미지를 빌드하여 이미지를 테스트한 후 테스트한 이미지를 Spinnaker에 푸시합니다.

  3. Spinnaker가 이미지를 감지하여 Canary에게 배포한 후 Canary 배포를 테스트합니다. 수동 승인을 받으면 Spinnaker가 이미지를 프로덕션 환경에 배포합니다.

목표

  • Cloud Shell을 실행하고 Google Cloud용 Spinnaker를 배포하여 환경을 설정합니다.
  • 샘플 애플리케이션을 배포할 GKE 클러스터를 만듭니다.
  • 샘플 앱을 다운로드하고, Git 저장소를 만들고, Cloud Source Repositories에 업로드합니다.
  • Docker 이미지를 빌드합니다.
  • 앱이 변경될 때 Docker 이미지를 생성하는 트리거를 만듭니다.
  • Spinnaker 파이프라인을 구성하여 GKE에 앱을 안정적, 지속적으로 배포합니다.
  • 코드 변경사항을 배포하여 파이프라인을 트리거하고 프로덕션에 제대로 적용되는지 확인합니다.

비용

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

  • GKE
  • Cloud Load Balancing
  • Cloud Build
  • Cloud Source Repositories
  • Container Registry

가격 계산기를 사용하면 예상 사용량을 토대로 예상 비용을 산출할 수 있습니다.

새 Google Cloud 사용자는 무료 체험판을 사용할 수 있습니다.

시작하기 전에

  1. Google 계정에 로그인합니다.

    아직 계정이 없으면 새 계정을 등록하세요.

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

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

  3. Google Cloud Platform 프로젝트에 결제가 사용 설정되어 있는지 확인합니다. 프로젝트에 결제가 사용 설정되어 있는지 확인하는 방법을 알아보세요.

  4. GKE, Cloud Build, Cloud Source Repositories필요한 API를 사용 설정합니다.

    API를 사용 설정합니다.

환경 설정

이 섹션에서는 가이드를 완료하는 데 필요한 인프라를 구성합니다.

Cloud Shell을 사용하여 Google Cloud용 Spinnaker 배포

Cloud Shell에서 이 가이드의 모든 터미널 명령어를 실행합니다.

Google Cloud용 Spinnaker를 사용하면 Google Cloud에 최적화된 프로덕션 환경에서 Spinnaker를 설정하고 관리할 수 있습니다. Google Cloud용 Spinnaker는 리소스(GKE, Memorystore, Cloud Storage 버킷 및 서비스 계정)를 설정하고 Spinnaker를 Cloud Build와 같은 관련 서비스와 통합하며 Spinnaker 설치에 Cloud Shell 기반 관리 환경은 물론 spinhal과 같은 도우미와 일반 도구를 제공합니다.

  1. Cloud Shell에서 Google Cloud용 Spinnaker를 엽니다. 그러면 Google Cloud용 Spinnaker 저장소가 Cloud Shell 환경으로 클론되고 자세한 설치 안내가 시작됩니다.

    Cloud Shell로 이동

  2. Google Cloud용 Spinnaker를 설치합니다.

    PROJECT_ID=${DEVSHELL_PROJECT_ID} ~/spinnaker-for-gcp/scripts/install/setup_properties.sh
    ~/spinnaker-for-gcp/scripts/install/setup.sh
    
  1. Cloud Shell을 다시 시작하여 새 환경 설정을 로드합니다.

    Cloud Shell 다시 시작 메뉴 옵션

  2. Spinnaker에 연결합니다.

    ~/spinnaker-for-gcp/scripts/manage/connect_unsecured.sh
    
  3. Cloud Shell에서 웹 미리보기 아이콘을 클릭하고 포트 8080에서 미리보기를 선택합니다.

    메뉴의 Cloud Shell 다시 시작 옵션

애플리케이션 배포를 위한 GKE 만들기

일반적인 패턴은 빌드, 배포 등에 GKE 클러스터를 사용하고 애플리케이션 실행에 다른 GKE 클러스터를 사용하는 것입니다. 이 섹션에서는 다른 GKE 클러스터인 app-cluster를 만들고 샘플 애플리케이션을 배포합니다.

  1. Cloud Shell에서 새 GKE 클러스터를 만듭니다.

    REGION=us-west1-b
    gcloud config set compute/zone $REGION
    gcloud container clusters create app-cluster \
    --machine-type=n1-standard-2
    
  2. 새 GKE 클러스터를 Spinnaker에 추가합니다. 기본값은 올바른 값이어야 합니다.

    ~/spinnaker-for-gcp/scripts/manage/add_gke_account.sh
    

    출력 및 값 예시:

    Please enter the context you wish to use to manage your GKE resources: gke_spinnaker-246920_us-west1-b_app-cluster
    Please enter the id of the project within which the referenced cluster lives: spinnaker-246920
    Please enter a name for the new Spinnaker account: app-cluster-acct
    

  3. kubernetes 컨텍스트를 다시 Spinnaker 클러스터로 변경합니다.

    kubectl config use-context gke_${DEVSHELL_PROJECT_ID}_${REGION}_spinnaker-1
    
  4. 구성 변경사항을 푸시하여 Spinnaker에 적용합니다.

    ~/spinnaker-for-gcp/scripts/manage/push_and_apply.sh
    

Docker 이미지 빌드

이 섹션에서는 앱 소스 코드의 변경사항을 감지하고 Docker 이미지를 빌드하여 Container Registry에 푸시하도록 Cloud Build를 구성합니다.

소스 코드 저장소 만들기

  1. Cloud Shell에서 샘플 소스 코드를 다운로드합니다.

    cd ~
    wget https://gke-spinnaker.storage.googleapis.com/sample-app-v2.tgz
    
  2. 소스 코드의 압축을 풉니다.

    tar xzfv sample-app-v2.tgz
    
  3. 디렉터리를 소스 코드로 변경합니다.

    cd sample-app
    
  4. 이 저장소의 Git 커밋에 대한 사용자 이름과 이메일 주소를 설정합니다. [EMAIL_ADDRESS]를 Git 이메일 주소로, [USERNAME]을 Git 사용자 이름으로 바꿉니다.

    git config --global user.email "[EMAIL_ADDRESS]"
    git config --global user.name "[USERNAME]"
    
  5. 소스 코드 저장소에 대한 최초 커밋을 수행합니다.

    git init
    git add .
    git commit -m "Initial commit"
    
  6. 코드를 호스팅할 저장소를 만듭니다.

    gcloud source repos create sample-app
    git config credential.helper gcloud.sh
    
  7. 새로 만든 저장소를 원격으로 추가합니다.

    export PROJECT=$(gcloud info --format='value(config.project)')
    git remote add origin https://source.developers.google.com/p/$PROJECT/r/sample-app
    
  8. 새 저장소의 마스터 브랜치에 코드를 푸시합니다.

    git push origin master
  9. 콘솔에서 소스 코드를 볼 수 있는지 확인합니다.

    소스 코드 페이지로 이동

빌드 트리거 구성

다음 다이어그램은 이 섹션에서 빌드한 트리거를 나타낸 것입니다.

Spinnaker 워크플로

소스 저장소에 Git 태그를 푸시할 때마다 Docker 이미지를 빌드하여 푸시하도록 Cloud Build를 구성합니다. Cloud Build는 자동으로 소스 코드를 체크아웃하고, 저장소의 Dockerfile로 Docker 이미지를 빌드하고, Container Registry에 해당 이미지를 푸시합니다.

  1. Cloud Console의 Cloud Build 섹션에서 빌드 트리거를 클릭합니다.

    빌드 트리거 페이지로 이동

  2. Cloud Source Repository를 선택하고 계속을 클릭합니다.

  3. 목록에서 새로 만든 sample-app 저장소를 선택하고 계속을 클릭합니다.

  4. 다음 트리거 설정을 지정합니다.

    • 이름: sample-app-tags
    • 트리거 유형: 태그
    • 태그(정규식): v.*
    • 빌드 구성: cloudbuild.yaml
    • cloudbuild.yaml 위치: cloudbuild.yaml
  5. 트리거 만들기를 클릭합니다.

    트리거를 만들 때 트리거 설정

이제부터는 'v' 프리픽스가 있는 Git 태그를 소스 코드 저장소에 푸시할 때마다 Cloud Build에서 자동으로 앱을 빌드하여 Docker 이미지로 Container Registry에 푸시합니다.

Spinnaker에서 사용할 Kubernetes 매니페스트 준비

Spinnaker는 Kubernetes 매니페스트를 클러스터에 배포하기 위하여 해당 매니페스트에 대한 액세스 권한을 필요로 합니다. 이 섹션에서는 지속적 통합(CI) 프로세스 도중에 Cloud Build에서 매니페스트로 채워지는 Cloud Storage 버킷을 만듭니다. 매니페스트가 Cloud Storage에 저장되면 Spinnaker는 파이프라인 실행 중에 이를 다운로드하고 적용할 수 있습니다.

  1. 버킷을 만듭니다.

    export PROJECT=$(gcloud info --format='value(config.project)')
    gsutil mb gs://$PROJECT-kubernetes-manifests
    
  2. 버킷에 버전 관리를 사용 설정하여 매니페스트의 기록을 볼 수 있도록 합니다.

    gsutil versioning set on gs://$PROJECT-kubernetes-manifests
    
  3. Kubernetes 배포 매니페스트에 올바른 Google Cloud 프로젝트 ID를 설정합니다.

    sed -i s/PROJECT/$PROJECT/g k8s/deployments/*
    
  4. 저장소에 대한 변경사항을 커밋합니다.

    git commit -a -m "Set project ID"
    

배포 파이프라인 구성

이제 이미지가 자동으로 빌드되므로, 이미지를 Kubernetes 클러스터에 배포할 차례입니다.

다음 다이어그램은 배포 파이프라인 단계를 나타낸 것입니다.

배포 파이프라인 구성

통합 테스트를 위해 규모를 축소한 환경에 배포합니다. 통합 테스트에 성공한 후에는 변경사항을 직접 승인하여 프로덕션 서비스에 코드를 배포해야 합니다.

배포 파이프라인 만들기

  1. spin을 사용하여 Spinnaker에서 앱을 만듭니다.

    spin application save --application-name sample \
                          --owner-email example@example.com \
                          --cloud-providers kubernetes \
                          --gate-endpoint http://localhost:8080/gate
    

이제 지속적 배포 파이프라인을 만들 차례입니다. 이 가이드에서는 'v' 프리픽스가 있는 태그를 가진 Docker 이미지가 Container Registry에 도착하는 시점을 감지하도록 파이프라인을 구성합니다.

  1. Cloud Shell 내 새 탭의 소스 코드 디렉터리에서 다음 명령어를 실행하여 예시 파이프라인을 Spinnaker 인스턴스에 업로드합니다.

    export PROJECT=$(gcloud info --format='value(config.project)')
    sed s/PROJECT/$PROJECT/g spinnaker/pipeline-deploy.json > pipeline.json
    spin pipeline save --gate-endpoint http://localhost:8080/gate -f pipeline.json
    

이미지 빌드

다음 단계에 따라 첫 번째 이미지를 푸시합니다.

  1. Cloud Shell에서 소스 코드 폴더로 이동합니다.
  2. Git 태그를 만듭니다.

    git tag v1.0.0
  3. 태그를 푸시합니다.

    git push --tags
  4. Cloud Build에서 빌드 기록을 클릭하여 빌드가 트리거되었는지 확인합니다. 그렇지 않은 경우 이전 섹션에서 트리거를 올바르게 구성했는지 확인합니다.

    빌드 기록으로 이동

    빌드 기록

파이프라인 실행 보기

방금 만든 구성에서는 새로 태그된 이미지가 푸시되고 있다는 알림을 사용하여 Spinnaker 파이프라인을 트리거합니다. 이전 단계에서는 Cloud Source Repositories에 태그를 푸시하면 여기서 Cloud Build를 트리거하여 이미지를 빌드하고 Container Registry로 이미지를 푸시했습니다. 이제 트리거된 파이프라인을 확인할 수 있습니다.

  1. 파이프라인을 클릭하여 파이프라인 페이지로 돌아갑니다.

  2. 세부정보를 클릭하면 파이프라인의 진행 상황에 대한 자세한 정보를 확인할 수 있습니다. 이 섹션에서는 배포 파이프라인의 상태와 단계를 보여줍니다. 파란색은 현재 실행 중인 단계, 녹색은 정상적으로 완료된 단계, 빨간색은 실패한 단계입니다. 단계를 클릭하면 세부정보를 볼 수 있습니다.

    3~5분이 지나면 통합 테스트 단계가 완료되고, 파이프라인을 수동으로 승인해야 배포가 계속 진행됩니다.

  3. 마우스 포인터를 프로덕션 환경으로 푸시 위로 가져와서 계속을 클릭합니다.

    출시가 프로덕션 프런트엔드 및 백엔드 배포에 들어갑니다. 이 작업은 몇 분 후에 완료됩니다.

  4. 앱을 확인하려면 Spinnaker UI의 상단에서 인프라 > 부하 분산기를 선택합니다.

    부하 분산기가 선택된 인프라 드롭다운 목록

  5. 부하 분산기 목록을 아래로 스크롤하고 sample-frontend-prod 아래의 기본값을 클릭합니다.

    기본 부하 분산기

  6. 오른쪽의 세부정보 창을 아래로 스크롤하고 인그레스 IP의 클립보드 버튼을 클릭하여 앱의 IP 주소를 복사합니다. Spinnaker UI의 인그레스 IP 링크는 기본적으로 HTTPS를 사용하지만 이 애플리케이션은 HTTP를 사용하도록 구성되어 있습니다.

    앱의 IP 주소가 표시된 세부정보 창

  7. 브라우저에 주소를 붙여넣어 앱의 프로덕션 버전을 확인합니다.

    앱의 프로덕션 버전

    이제 수동으로 파이프라인을 트리거하여 앱을 빌드, 테스트, 배포했습니다.

코드 변경으로 파이프라인 트리거하기

이 섹션에서는 코드를 변경하고, Git 태그를 푸시하고, 여기에 따른 응답으로 파이프라인이 실행되는지 확인하는 방법으로 파이프라인에 대한 엔드 투 엔드 테스트를 실행합니다. 'v'로 시작되는 Git 태그를 푸시하면 Cloud Build가 트리거되어 새 Docker 이미지를 빌드하고 Container Registry에 푸시합니다. Spinnaker는 'v'로 시작되는 새 이미지 태그를 감지하여 카나리아 환경에 이미지를 배포하고, 테스트를 실행하고, 배포의 모든 pod에 동일한 이미지를 적용하는 파이프라인을 트리거합니다.

  1. 앱의 색상을 주황색에서 파란색으로 변경합니다.

    cd ~/sample-app
    sed -i 's/orange/blue/g' cmd/gke-info/common-service.go
    
  2. 변경사항에 태그를 지정하고 소스 코드 저장소에 푸시합니다.

    git commit -a -m "Change color to blue"
    git tag v1.0.1
    git push --tags
    
  3. Cloud Build 빌드 기록에 새 빌드가 표시되는지 확인합니다.

  4. 파이프라인을 클릭하여 파이프라인이 이미지 배포를 시작하는지 확인합니다.

  5. 카나리아 배포를 관찰합니다. 배포가 일시 중지되어 프로덕션 적용을 위해 대기 중이면 앱이 포함된 탭을 새로고침합니다. 백엔드 중 4개는 이전 버전의 앱을 실행하며 하나의 백엔드만 카나리아를 실행합니다. 새로고침을 10번 수행할 때마다 앱의 새로운 파란색 버전이 표시됩니다.

  6. 테스트가 완료되면 Spinnaker 탭으로 돌아가서 배포를 승인합니다.

  7. 파이프라인이 완료되면 앱이 다음 스크린샷처럼 표시됩니다. 이제 버전 필드에 v1.0.1이 표시됩니다.

    업데이트된 앱의 프로덕션 버전

    이제 앱이 전체 프로덕션 환경에 정상적으로 출시되었습니다.

  8. 필요한 경우 이전 커밋을 되돌리면 이 변경사항을 롤백할 수 있습니다. 롤백을 수행하면 새 태그((v1.0.2)가 추가되고 v1.0.1을 배포하는 데 사용한 파이프라인을 통해 다시 푸시됩니다.

    git revert v1.0.1
    git tag v1.0.2
    git push --tags

삭제

이 가이드에서 사용한 리소스 비용이 Google Cloud Platform 계정에 청구되지 않도록 하려면 다음 안내를 따르세요.

1. Google Cloud용 Spinnaker 삭제:

<pre class="lang-sh devsite-click-to-copy">
cd ~
~/spinnaker-for-gcp/scripts/manage/generate_deletion_script.sh
~/spinnaker-for-gcp/scripts/manage/delete-all_${DEVSHELL_PROJECT_ID}_spinnaker-1_spinnaker-1.sh
</pre>
  1. GKE 클러스터를 삭제합니다.

    gcloud container clusters delete app-cluster --zone=us-west1-b
    
  2. 저장소를 삭제합니다.

    gcloud source repos delete sample-app
    
  3. 버킷을 삭제합니다.

    export PROJECT=$(gcloud info --format='value(config.project)')
    export BUCKET=$PROJECT-spinnaker-config
    gsutil -m rm -r gs://$BUCKET
    
  4. 컨테이너 이미지를 삭제합니다.

    export PROJECT=$(gcloud info --format='value(config.project)')
    gcloud container images delete gcr.io/$PROJECT/sample-app:v1.0.0
    gcloud container images delete gcr.io/$PROJECT/sample-app:v1.0.1
    
  5. 위의 선택적 롤백 단계에서 v1.0.2를 만든 경우 해당 컨테이너 이미지를 삭제합니다.

    gcloud container images delete gcr.io/$PROJECT/sample-app:v1.0.2
    

다음 단계