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

2021. 5. 25. 18:19IT 공부/Qwiklabs

※ 본 카테고리에서는 구글 클라우드 스터디잼을 통해 제공받은 퀵랩에서 퀘스트를 수행하며 공부한 내용을 기록하고 있습니다. 


https://google.qwiklabs.com/focuses/552?parent=catalog

 

 

실습목표 : (1) Kubernetes Engine 클러스터를 생성 및 ID와 사용자 관리 스키마 구성, 환경설정

              (2) 샘플 애플리케이션을 Google Cloud Source Repositories에 업로드

              (3) Helm으로 Spinnaker를 Kubernetes Engine에 배포

              (4) Docker 이미지 빌드

              (5) Spinnaker 파이프라인을 구성하여 애플리케이션을 안정적이고 지속적으로 Kubernetes Engine에 배포

              (6) 코드 변경사항을 배포하여 파이프라인을 트리거한 후 프로덕션에 제대로 적용되는지 확인

 


 

- 카나리아 릴리즈 (Canary Release)

  : 조금씩 사용자의 범위를 늘려가며 피드백을 통해 배포하는 방식이다. 

    처음부터 전체 사용자에게 적용하지 않는다. 

    새 버전에 문제점이 발견될 경우 자동화된 프로세스에서 소프트웨어 변경사항을 롤백한다. 

    단계별 배포(phased rollout) 또는 점진적 배포(incremental rollout)으로도 불린다. 

    기존 버전과 새 버전을 모두 서비스해야 하므로 관리비용이 보다 필요하다는 단점이 존재한다. 

(참고)

https://woongsin94.tistory.com/356

 

- 스피내커 (Spinnaker)

   : Netflix에서 개발하고 Google에서 확장한 지속적 배포 소프트웨어 플랫폼 오픈소스

    AWS, GCP, Azure 등 대부분의 메이저 클라우드를 지원하며,

    k8s나 OpenStack과 같은 오픈소스 기반의 클라우드 또는 컨테이너 플랫폼을 동시에 지원한다. 

    멀티 클라우드 뿐만 아니라 오케스트레이션 파이프라인 구조를 지원하므로,

    배포 단계는 여러 개의 스텝이 복합적으로 수행되므로 복잡한 워크 플로우에 대한 관리가 필요하다. 

    배포시 카나리아 릴리즈가 가능하게끔 도와준다.

 

>> 파이프라인

 

>> 하위 태스크

 

 

>> 파이프라인에서의 샘플 스테이지

  Bake   VM 이미지를 생성
  Deploy   VM 이미지(또는 컨테이너)를 클러스터에 배포
  Check Preconditions   다음 단계로 넘어가기 전에 조건을 체크
  (ex. 얼마나 많은 VM이 생성되서 준비가 됐는지)
  Jenkins   Jenkins Job을 실행
  Manual Judgement   사용자로부터 입력받아 파이프라인 실행 여부를 결정
  Enable / Disable Server Group   이미 생성된 Server Group을 Enable 또는 Disable 시킴
  Pipeline   다른 파이프라인을 수행
  WebHook   HTTP로 다른 시스템을 호출
  (통상적으로 HTTP REST API를 호출)

 

(참고)

https://bcho.tistory.com/1234

 


 환경 설정 

1. cloud shell 열기

 

2. 기본 컴퓨팅 영역 설정

gcloud config set compute/zone us-central1-f

 

3. Spinnaker 가이드 샘플 애플리케이션을 사용하여 Kubernetes Engine을 생성

gcloud container clusters create spinnaker-tutorial --machine-type=n1-standard-2

 

4. 서비스계정 만들기

   : Cloud IAM 서비스 계정을 만들어 Spinnaker에 권한을 위임

    → Spinnaker가 안정성, 복원성을 보장하기 위해 파이프라인 데이터를 Cloud Storage에 데이터를 저장할 수 있다.

   : Spinnaker 배포가 예기치 않게 실패하면,

    → 몇 분 내에 원본과 같은 파이프라인 데이터에 액세스할 수 있는 동일한 배포를 생성 가능

gcloud iam service-accounts create spinnaker-account --display-name spinnaker-account

 

5. 서비스 계정 이메일 주소 및 현재 프로젝트 ID를 환경변수에 저장

   : 이후 명령어에서 사용할 수 있게 됨

export SA_EMAIL=$(gcloud iam service-accounts list --filter="displayName:spinnaker-account" --format='value(email)')
export PROJECT=$(gcloud info --format='value(config.project)')

 

6. 서비스 계정에 storage.admin 역할 부여하기

gcloud projects add-iam-policy-binding $PROJECT --role roles/storage.admin --member serviceAccount:$SA_EMAIL

 

7. 서비스 계정 키 다운로드

   → Spinnaker 설치 후 Kubernetes Engine에 키를 업로드할 예정

gcloud iam service-accounts keys create spinnaker-sa.json --iam-acount $SA_EMAIL
// create key [12f224e036437704b91a571792462ca6fc4cd438] of type [json] as [spinnaker-sa.json] for [spinnaker-account@qwiklabs-gcp-gcpd-f5e16da10e5d.iam.gserviceaccount.com]

 


 

 Spinnaker 파이프라인을 트리거하는 Cloud Pub/Sub 설정하기 

 

1. Container Registry에서 알림을 위한 Cloud Pub/Sub 주제 생성

gcloud pubsub topics create projects/$PROJECT/topics/gcr

 

2. 이미지가 푸시되고 있다는 알림을 받기 위해 Spinnaker에서 읽을 수 있는 구독 생성

gcloud pubsub subscriptions create gcr-triggers --topic projects/${PROJECT}/topics/gcr

 

3. Spinnaker의 서비스 계정에 gcr-trigger 구독에서 읽을 수 있는 권한을 부여

export SA_EMAIL=$(gcloud iam service-accounts list --filter="displayNAme:spinnaker-account" --format='value(email)')
gcloud beta pubsub subscriptions add-iam-policy-binding gcr-triggers --role roles/pubsub.subscrier --member serviceAccount:$SA_EMAIL

 


 

 Helm을 사용하여 Spinnaker 배포 

 

※ Helm 이란?

- k8s package managing tool

- npm과 비슷한 형태

- chart 라고 부르는 package format을 사용하며, chart는 k8s 리소스를 describe하는 파일들의 집합

(참고)

https://reoim.tistory.com/entry/Kubernetes-Helm-%EC%82%AC%EC%9A%A9%EB%B2%95

 

<Helm 설치>

1. helm 바이너리를 다운로드 후 설치

wget https://get.helm.sh/helm-v3.1.0-linux-amd64.tar.gz

 

2. 로컬 시스템에 파일의 압축 해제

tar zxfv helm-v3.1.0-linux-amd64.tar.gz
cp linux-amd64/helm .

 

3. Helm에 클러스터의 cluster-admin 역할 부여

kubectl create clusterrolebinding user-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value account)

 

4. Spinnaker가 모든 네임스페이스에 리소스를 배포할 수 있도록 cluster-admin 역할 부여

kubectl create clusterrolebinding --clusterrole=cluster-admin --serviceaccount=default:default spinnaker-admin

 

5. Helm의 사용 가능한 저장소에 안정화 차트 배포를 추가 (Spinnaker 포함)

./helm repo add stable https://charts.helm.sh/stable
./helm repo update

// ./helm repo add stable https://kubernetes-charts.storage.googleapis.com 는 링크 폐쇄됨

 

<Spinnaker 구성>

6. Spinnaker 파이프라인 구성을 저장할 버킷 생성

export PROJECT=$(gcloud info --format='value(config.project)')
export BUCKET=$PROJECT-spinnaker-config
gsutil mb -c regional -l us-central1 gs://$BUCKET

※ gsutil mb gs://버킷이름      # 버킷 생성

※ -c 스토리지클래스             # 버킷의 기본 스토리지 클래스 지정

※ -l 위치                            # 버킷의 위치 지정

 

7. spinnaker-config.yaml 파일 생성 

   → Helm 에서 Spinnaker를 어떻게 설치할지 정의해줌

export SA_JSON=$(cat spinnaker-sa.json)
export PROJECT=$(gcloud info --format='value(config.project)')
export BUCKET=$PROJECT-spinnaker-config
cat > spinnaker-config.yaml <<EOF
gcs:
  enabled: true
  bucket: $BUCKET
  project: $PROJECT
  jsonKey: '$SA_SJON'

dockerRegistries:
- name: gcr
  address: https://gcr.io
  username: _json_key
  password: '$SA_JSON'
  email: 1234@5678.com
  
# Disable minio as the default storae backend minio:
  enabled: false
  
# Configure Spinnaker to enable GCP services halyard:
  spinnakerVersion: 1.19.4
  image:
    repository: us-docker.pkg.dev/spinnaker-community/docker/halyard
    tag: 1.32.0
    pullSecrets: []
  additionalScripts:
    create: true
    data:
      enable_gcs_artifacts.sh: |-
        \$HAL_COMMAND config artifact gcs account add gcs-$PROJECT --json-path /opt/gcs/key.json
        \$HAL_COMMAND config artifact gcs enable
      enable_pubsub_triggers.sh: |-
        \$HAL_COMMAND config pubsub google enable
        \$HAL_COMMAND config pubsub google subscription add gcr-triggers \
          --subscription-name gcr-triggers \
          --json-path /opt/gcs/key.json \
          --project $PROJECT \
          --message-format GCR
EOF

 

<Spinnaker 차트 배포>

8. Helm 명령줄 인터페이스를 사용하여 설정된 구성으로 차트 배포

./helm install -n default cd stable/spinnaker -f spinnaker-config.yaml --version 2.0.0-rc9 --timeout 10m0s --wait

 

9. Cloud Shell에서 Spinnaker로 포트 전달 설정

export DECK_POD=$(kubectl get pods --namespace default -l "cluster=spin-deck" -o jsonpath="{.items[0].metadata.name}")

 

kubectl port-forward --namespace default $DECK_POD 8080:9000 >> /dev/null &

 

10. Cloud Shell 창 상단에서 "Preview on port 8080"을 클릭하여 Spinnaker 사용자 인터페이스 열기

 

 

 

 


 

 Docker 이미지 빌드 

 

 

<소스 코드 저장소 만들기>

1. Cloud Shell 에서 샘플 애플리케이션 소스 코드 다운로드

gsutil -m cp -r gs://spls/gsp114/sample-app.tar .

※ -m            # parallel 하게 처리되어 성능이 향상됨

 

2. 소스 코드의 압축 해제

mkdir sample-app
tar xvf sample-app.tar -C ./sample-app

 

3. 디렉터리를 소스 코드로 변경

cd sample-app

 

4. 이 저장소의 Git 커밋에 대한 사용자 이름과 이메일 주소를 설정

git config --global user-email "$(gcloud config get-value core/account)"
git config --gloval user.name "나의 사용자 이름"

 

5. 소스 코드 저장소에 대한 최초 커밋 수행

git init
git add .
git commit -m "Initial commit"

 

6. 코드를 호스팅할 저장소 생성

gcloud source repos create sample-app

 

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. 콘솔의 메뉴에서 Source Repositories 클릭 - 소스 코드가 보이는지 확인

 

10. "모든 저장소 보기" 클릭 - 'sample-app' 선택

 

<빌드 트리거 구성>

11. 콘솔의 메뉴에서 Cloud Build 클릭 - Trigger 클릭

 

12. Create Trigger 클릭

 

13. 트리거 설정 지정

  이름 (Name)   sample-app-tags
  이벤트 (Event)   새 태그 푸시 (Push new tag)
  저장소 (Source)   sample-app (Cloud Source Repositories)
  태그 (Tag)   v.*
  빌드 구성 (Build configuration)   Cloud Build configuration file (yaml or json)
  Cloud Build configuration file location   /cloudbuild.yaml

 

14. Create 클릭

    → 이후, v 프리픽스가 있는 Git 태그를 소스 코드 저장소에 푸시할 때마다

        Container Builder에서 자동으로 애플리케이션을 빌드하여

        Docker 이미지로 Container Registry에 푸시한다. 

 

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

15. 버킷 생성

export PROJECT=$(gcloud info --format='value(config.project)')
gsutil mb -l us-central1 gs://$PROJECT-kubernetes-manifests

 

16. 버킷에 버전관리를 사용 설정

    → 매니페스트의 기록을 볼 수 있게 함

gsutil versioning set on gs://$PROJECT-kubernetes-manifests

 

17. kubernetes 배포 매니페스트에 올바른 프로젝트 ID를 설정

sed -i s/PROJECT/$PROJECT/g k8s/deployments/*

 

18. 저장소에 대한 변경사항을 커밋

git commit -a -m "Set project ID"

 

<이미지 빌드>

19. sample-app 디렉터리에 Git 태그를 생성 

git tag v1.0.0

 

20. 태그를 푸시

git push --tags
// To https://source.developers.google.com/p/qwiklabs-gcp-ddf2925f84de0b16/r/sample-app
// * [new tag]      v1.0.0 -> v1.0.0

 

21. Cloud Build의 History를 클릭(10분 가까이 소요) - 빌드가 트리거 되었는지 확인

 

 


 

 배포 파이프라인 구성 

 

 

<Spinnaker 관리를 위한 spin CLI 설치하기>

※ spin 이란?

Spinnaker의 애플리케이션 및 파이프라인을 관리하기 위한 명령줄 유틸리티

 

 

1. spin의 1.14.0 버전 다운로드

curl -L0 https://storage.googleapis.com/spinnaker-artifacts/spin/1.14.0/linux/amd64/spin

 

2. spin 실행 파일 생성

chmod +x spin

 

<배포 파이프라인 만들기>

3. spin을 사용하여 Spinnaker에서 sample 앱 생성 후 Spinnaker에서 앱의 소유자 이메일 주소를 설정

./spin application save --application-name sample 
                        --owner-email "$(gcloud config get-value core/account)" 
                        --cloud-providers kubernetes
                        --gate-endpoint http://localhost:8080/gate
                        
// Application save succeeded                         

 

4. sample-app 소스 코드 디렉터리로 이동 후 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

// Pipeline save succeeded

 

 

<파이프라인 실행을 수동으로 트리거하여 확인>

5. spinnaker UI 화면 상단 - Application 클릭

   → sample 이 애플리케이션임

 

6. sample 을 클릭 - 애플리케이션 배포를 확인

 

7. 파이프라인(PIPELINES) 클릭 - 애플리케이션 파이프라인 상태를 확인

 

8. 수동 실행 시작(Start Manual Execution) 클릭 - 파이프라인을 처음으로 트리거 하기

 

9. 실행(Run) 클릭

 

10. 실행 세부정보 클릭 - 파이프라인 진행 상황에 대한 자세한 정보 확인

     → 파란색 : 현재 실행중인 단계 / 녹색 : 정상적으로 완료된 단계 / 빨간색 : 실패한 단계

 

11. 단계를 클릭하면 세부정보를 확인할 수 있음.

     ※ 3~5분이 지나면 통합 테스트 단계가 완료됨

        → 파이프라인을 수동으로 승인해야 배포가 계속 진행됨

 

12. 노란색 '사람' 아이콘에 마우스를 가져간 뒤 "계속(Continue)" 클릭

   → 프로덕션 프런트엔드 및 백엔드에 배포됨 ( 몇 분 후 완료 됨 )

 

13. Spinnaker UI 상단의 '인프라(INFRASTRUCTURE) > 부하분산기(LOAD BALANCERS)' 클릭하여 앱을 확인

 

14. service sample-frontend-production 아래에서 기본값(DEFAULT) 클릭

     → 오르쪽에 로드 밸런서에 대한 세부 정보가 표시됨

 

15. 인그레스ip의 클립보드 버튼을 클릭하여 앱의 IP 주소를 복사

     → Spinnaker UI의 인그레스 IP 링크는 기본적으로 HTTPS를 사용하지만,

         이번 실습에서는 HTTP를 사용하도록 구성되어 있음

 

16. 새로운 브라우터 탭에 주소를 붙여 넣어 애플리케이션을 확인

     → 카나리아 버전이 표시될 수 있지만, 새로 고치면 프롣거션 버전도 표시됨

     → 수동으로 파이프라인 트리거 후 애플리케이션 빌드, 테스트, 배포가 완료된 상태

 

 


 

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

 

1. sample-app 디렉터리에서 앱 색상을 주황->파랑색으로 변경

sed -i 's/orange/blue/g' cmd/gke-info/common-service.go

 

2. 변경사항을 태그에 지정하고 소스 코드 저장소에 푸시

git commit -a -m "Change color to blue"
// [master 99f3afe] Change color to blue
// 2 files changed, 39 insertions(+), 39 deletions(-)

git tag v1.0.1

git push --tags
// Enumerating objects: 11, done.
// Counting objects: 100% (11/11), done.
// Delta compression using up to 2 threads
// Compressing objects: 100% (5/5), done.
// Writing objects: 100% (6/6), 779 bytes | 389.00 KiB/s, done.
// Total 6 (delta 4), reused 0 (delta 0)
// remote: Resolving deltas: 100% (4/4)
// To https://source.developers.google.com/p/qwiklabs-gcp-04-7659719cadaa/r/sample-app
//  * [new tag]         v1.0.1 -> v1.0.1

 

3. 콘솔에서 'Cloud Build > History' 클릭 - 새 빌드가 표시될 때까지 대기 (몇 분 소요됨)

 

4. Spinnaker UI 에서 파이프라인 클릭 - 파이프라인이 이미지 배포를 시작하는지 확인

   → 자동으로 트리거된 파이프라인이 표시되는데 몇 분 소요됨 (페이지를 새로고침해야 할 수도 있음)

 


 

 카나리아 배포 확인 

 

1. 배포가 일시중지되어 프로덕션 적용을위해 대기중이면

   → 실행중인 애플리케이션을 표시하는 웹 페이지로 돌아가서 앱이 포함된 탭을 새로고침을 5번 수행

   →백엔드 중 4개는 이전 버전의 앱을 실행 >>>> 주황색

   → 1개의 백엔드는 카나리아를 실행 >>>> 파란색

 

2. 버전 필드가 canary로 표시되어 있음을 확인

   → 앱이 전체 프로덕션 환경에 정상적으로 출시됨

 

 

3. 이전 커밋으로 되돌리면 이 변경 사항을 롤백 가능

   → 롤백 수행시 새 태그 (v1.0.2)가 추가되고 v1.0.1을 배포하는데 사용한 파이프라인을 통해 다시 푸시됨

git revert v1.0.1
// [master 22d7db9] Revert "Change color to blue"
// 2 files changed, 39 insertions(+), 39 deletions(-)

git tag v1.0.2

git push --tags
// Enumerating objects: 11, done.
// Counting objects: 100% (11/11), done.
// Delta compression using up to 2 threads
// Compressing objects: 100% (5/5), done.
// Writing objects: 100% (6/6), 805 bytes | 805.00 KiB/s, done.
// Total 6 (delta 4), reused 0 (delta 0)
// remote: Resolving deltas: 100% (4/4)
// To https://source.developers.google.com/p/qwiklabs-gcp-04-7659719cadaa/r/sample-app
//  * [new tag]         v1.0.2 -> v1.0.2

 

4. 빌드 후 파이프라인이 완료되면 '인프라 > 부하 분산기'를 클릭

   → 롤백을 확인

   → service sample-frontend-production 의 DEFAULT를 클릭

   → 인그레스 IP 주소를 새 탭에 복사

   → 앱이 주황색으로 돌아오고 production 버전 번호 확인 가능

 

 

- 끝 -

 

 

반응형

'IT 공부 > Qwiklabs' 카테고리의 다른 글

Cloud Architecture (finished)  (0) 2021.10.18
Kubernetes in Google Cloud (finished)  (0) 2021.09.25
Cloud Engineering (finished)  (0) 2021.09.22
GCP Essentials (finished)  (0) 2021.09.17
퀵랩 - Kubernetes를 통한 클라우드 조정  (0) 2021.05.11