使用 Spinnaker 和 Google Kubernetes Engine 的持續推送軟體更新管道

本教學課程說明如何使用 Google Kubernetes Engine、Cloud Source Repositories、Cloud Build 和 Spinnaker 來建立持續推送軟體更新管道。建立範例應用程式後,請設定這些服務以自動進行建構、測試和部署。當您修改應用程式的程式碼時,變更會觸發持續推送軟體更新管道,以自動重新建構、重新測試和重新部署新版本。

管道架構

管道架構

如要向使用者持續推送應用程式更新,您需要可穩定建構、測試和更新軟體的自動化程序。程式碼變更應自動流經包含建立成果、單元測試、功能測試和實際工作環境發布的管道。在某些情況下,您會希望只將程式碼更新套用到某個使用者子集,以便在推送到整個使用者數量前先進行實際演練。如果其中一個初期測試版不符合您的期望,則自動化程序必須要能快速復原軟體變更。

透過 GKE 和 Spinnaker,您可以建立完善可靠的持續推送軟體更新流程,協助確保提供的軟體速度與開發及驗證速度一樣快。雖然您的最終目標是快速疊代,但您必須先確保每個應用程式的修訂版本都能通過一連串的自動化驗證作業,這樣才能成為導入實際工作環境的候選程式。當指定變更已通過自動化審核時,您也可以手動驗證應用程式,並進行進一步的發行前版本測試。

當您的團隊認定應用程式已可供實際工作環境使用,其中一位小組成員可以核准應用程式,進行實際工作環境部署。

應用程式推送管道

在本教學課程中,您將建構下圖所示的持續推送軟體更新管道。

應用程式推送管道

目標

  • 設定環境:啟動 Cloud Shell、建立 GKE 叢集,並設定身分和使用者管理方案。
  • 下載範例應用程式、建立 Git 存放區,並將 Git 存放區上傳至 Cloud Source Repository。
  • 使用 Helm 將 Spinnaker 部署至 GKE。
  • 建構 Docker 映像檔。
  • 建立觸發條件,以在應用程式變更時建立 Docker 映像檔。
  • 設定 Spinnaker 管道,穩定持續地將應用程式部署至 GKE。
  • 部署程式碼變更、觸發管道,並觀察程式碼如何發布到實際工作環境。

費用

本教學課程使用的 Google Cloud Platform (GCP) 收費元件包括:

  • GKE
  • Cloud Load Balancing
  • Cloud Build

使用 Pricing Calculator 可根據您的預測使用量來產生預估費用。

初次使用 GCP 的使用者可能符合免費試用的資格。

事前準備

  1. 登入您的 Google 帳戶。

    如果您沒有帳戶,請申請新帳戶

  2. 選取或建立 Google Cloud Platform 專案。

    前往「Manage resources」(管理資源) 頁面

  3. 請確認您已啟用 Google Cloud Platform 專案的計費功能。

    瞭解如何啟用計費功能

  4. 啟用GKE, Cloud Build, and Cloud Source Repositories API。

    啟用 API

設定環境

在本節中,您將設定基礎架構和完成教學課程所需的身分識別。

啟動 Cloud Shell 執行個體並建立 GKE 叢集

您將從 Cloud Shell 執行本教學課程中所有的終端機指令。

  1. 開啟 Cloud Shell:

    開啟 Cloud Shell

  2. 建立一個 GKE 叢集,以使用以下指令來部署 Spinnaker 和範例應用程式:

    gcloud config set compute/zone us-central1-f
    
    gcloud container clusters create spinnaker-tutorial \
        --machine-type=n1-standard-2
    

設定身分與存取權管理

您需要建立 Cloud Identity and Access Management (Cloud IAM) 服務帳戶,以將權限委任給 Spinnaker,讓 Spinnaker 能夠將資料儲存在 Cloud Storage 中。Spinnaker 會將管道資料儲存在 Cloud Storage 中,以確保可靠度與彈性。如果 Spinnaker 部署意外失敗,您可以在幾分鐘內建立相同的部署,且能存取與原始部署相同的管道資料。

  1. 建立服務帳戶:

    gcloud iam service-accounts create  spinnaker-account \
        --display-name spinnaker-account
    
  2. 將服務帳戶電子郵件地址和目前的專案 ID 儲存於環境變數中,以在後續的指令中使用:

    export SA_EMAIL=$(gcloud iam service-accounts list \
        --filter="displayName:spinnaker-account" \
        --format='value(email)')
    export PROJECT=$(gcloud info --format='value(config.project)')
    
  3. storage.admin 角色繫結至您的服務帳戶:

    gcloud projects add-iam-policy-binding \
        $PROJECT --role roles/storage.admin --member serviceAccount:$SA_EMAIL
    
  4. 下載服務帳戶金鑰。稍後安裝 Spinnaker 並將金鑰上傳至 GKE 時,需要用到這個金鑰。

    gcloud iam service-accounts keys create spinnaker-sa.json --iam-account $SA_EMAIL
    

設定 Cloud Pub/Sub 以觸發 Spinnaker 管道

  1. 建立 Cloud Pub/Sub 主題,以取得來自 Container Registry 的通知。這個指令可能會失敗並顯示「Resource already exists in the project」(資源已在專案中) 的錯誤訊息,這表示系統已為您建立主題。

    gcloud beta pubsub topics create projects/$PROJECT/topics/gcr
    
  2. 建立 Spinnaker 可讀取的訂閱,以接收正在推送的映像檔的通知。

    gcloud beta pubsub subscriptions create gcr-triggers \
        --topic projects/${PROJECT}/topics/gcr
    
  3. 將讀取 gcr-triggers 訂閱的權限授予 Spinnaker 服務帳戶。

    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.subscriber --member serviceAccount:$SA_EMAIL
    

使用 Helm 部署 Spinnaker

在本節中,您將使用 Helm圖表存放區部署 Spinnaker。Helm 是可用來設定及部署 Kubernetes 應用程式的套件管理員。

安裝 Helm

  1. 下載並安裝 helm 二進位檔:

    wget https://storage.googleapis.com/kubernetes-helm/helm-v2.10.0-linux-amd64.tar.gz
    
  2. 將檔案解壓縮到本機系統:

    tar zxfv helm-v2.10.0-linux-amd64.tar.gz
    
    cp linux-amd64/helm .
    
  3. 將叢集中的 cluster-admin 角色授予 Helm 伺服器端 Tiller:

    kubectl create clusterrolebinding user-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value account)
    kubectl create serviceaccount tiller --namespace kube-system
    kubectl create clusterrolebinding tiller-admin-binding --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
    
  4. cluster-admin 角色授予 Spinnaker,使其可以在所有命名空間中部署資源︰

    kubectl create clusterrolebinding --clusterrole=cluster-admin --serviceaccount=default:default spinnaker-admin
    
  5. 將 Helm 初始化,以便在叢集中安裝 Tiller︰

    ./helm init --service-account=tiller
    ./helm update
  6. 執行以下指令來確保 Helm 已正確安裝。如果 Helm 已正確安裝,用戶端和伺服器都會顯示 v2.10.0

    ./helm version
    Client: &version.Version{SemVer:"v2.10.0", GitCommit:"9ad53aac42165a5fadc6c87be0dea6b115f93090", GitTreeState:"clean"}
    Server: &version.Version{SemVer:"v2.10.0", GitCommit:"9ad53aac42165a5fadc6c87be0dea6b115f93090", GitTreeState:"clean"}
    

設定 Spinnaker

  1. 為 Spinnaker 建立值區,以儲存管道設定:

    export PROJECT=$(gcloud info \
        --format='value(config.project)')
    export BUCKET=$PROJECT-spinnaker-config
    gsutil mb -c regional -l us-central1 gs://$BUCKET
  2. 建立檔案 (spinnaker-config.yaml),說明如何安裝 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_JSON'
    
    dockerRegistries:
    - name: gcr
      address: https://gcr.io
      username: _json_key
      password: '$SA_JSON'
      email: 1234@5678.com
    
    # Disable minio as the default storage backend
    minio:
      enabled: false
    
    # Configure Spinnaker to enable GCP services
    halyard:
      spinnakerVersion: 1.10.2
      image:
        tag: 1.12.0
      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 圖表

  1. 使用 Helm 指令列介面,透過設定集來部署圖表:這個指令通常需要五到十分鐘才能完成。

    ./helm install -n cd stable/spinnaker -f spinnaker-config.yaml --timeout 600 \
        --version 1.1.6 --wait
  2. 指令完成後,請執行以下指令,以設定從 Cloud Shell 到 Spinnaker UI 的通訊埠轉送:

    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 &
    
  3. 如要開啟 Spinnaker 使用者介面,請按一下 Cloud Shell 中的 [Web Preview] (網頁預覽),然後按一下 [Preview on port 8080] (在通訊埠 8080 上預覽)

    port8080

  4. 您應該會看到歡迎畫面,接著是 Spinnaker UI:

    hello

    spinui

建構 Docker 映像檔

在本節中,您將設定 Cloud Build 以偵測應用程式原始碼變更、建構 Docker 映像檔,然後將映像檔推送到 Container Registry。

建立原始碼存放區

  1. 在 Cloud Shell 中,下載原始碼範例:

    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. 檢查是否可以在主控台中看到原始碼:

    前往「Source Code」(原始碼) 頁面

設定建構觸發條件

在本節中,您將設定 Cloud Build,以在每次將 Git 標記推送到原始存放區時,建構並推送 Docker 映像檔。Cloud Build 會自動檢查原始碼、從存放區中的 Dockerfile 建構 Docker 映像檔,並將該映像檔推送到 Container Registry。

Spinnaker 工作流程

  1. 在 GCP 主控台的「Cloud Build」區段中,按一下 [Build Triggers] (版本觸發條件)

    前往「BUILD TRIGGERS」(版本觸發條件) 頁面

  2. 選取 [Cloud Source Repository] (Cloud 原始碼存放區),然後按一下 [Continue] (繼續)

  3. 從清單中選取新建立的 sample-app 存放區,然後按一下 [Continue] (繼續)

  4. 設定下列觸發條件設定:

    • 「Name」(名稱)sample-app-tags
    • 「Trigger type」(觸發條件類型):標記
    • 「Tag (regex)」(標記 (規則運算式))v.*
    • 「Build configuration」(版本設定)cloudbuild.yaml
    • 「cloudbuild.yaml location」(cloudbuild.yaml 位置)cloudbuild.yaml
  5. 按一下 [Create trigger] (建立觸發條件)

    建立觸發條件

從現在開始,每當您將前置字串為 "v" 字母的 Git 標記推送到原始碼存放區時,Cloud Build 就會自動建構應用程式,並以 Docker 映像檔的形式將應用程式推送到 Container Registry。

準備可供 Spinnaker 使用的 Kubernetes 資訊清單

Spinnaker 需要 Kubernetes 資訊清單的存取權,才能將資訊清單部署到您的叢集。本節會建立 Cloud Storage 值區,並在值區中於 Cloud Build 中的 CI 程序期間填入您的資訊清單。在您的資訊清單位於 Cloud Storage 後,Spinnaker 就能在管道的執行作業期間下載並套用資訊清單。

  1. 建立值區。

    export PROJECT=$(gcloud info --format='value(config.project)')
    gsutil mb -l us-central1 gs://$PROJECT-kubernetes-manifests
    
  2. 啟用值區上的版本管理,以擁有資訊清單記錄。

    gsutil versioning set on gs://$PROJECT-kubernetes-manifests
    
  3. 在 Kubernetes 部署資訊清單中,設定正確的專案 ID。

    sed -i s/PROJECT/$PROJECT/g k8s/deployments/*
    
  4. 修訂存放區的變更:

    git commit -a -m "Set project ID"
    

建構映像檔

透過下列步驟推送第一個映像檔:

  1. 前往 Cloud Shell 中的原始碼資料夾。
  2. 建立 Git 標記:

    git tag v1.0.0
  3. 推送標記:

    git push --tags
  4. 在「Cloud Build」中,按一下 [Build History] (版本記錄),檢查是否已觸發版本。如果未觸發,請確認您在上一節中是否已正確設定觸發條件。

    前往「Build History」(版本記錄)。

    版本記錄

設定部署管道

現在系統正在自動建構映像檔,您必須將映像檔部署到 Kubernetes 叢集。

您可以部署到調降的環境,以進行整合測試。通過整合測試後,您必須手動核准變更,才能將程式碼部署到實際工作環境服務。

設定部署管道

安裝 spin CLI 以管理 Spinnaker

spin 是可以管理 Spinnaker 應用程式和管道的指令列公用程式。

  1. 下載最新版 spin

    curl -LO https://storage.googleapis.com/spinnaker-artifacts/spin/1.5.2/linux/amd64/spin
    
  2. spin 設為可執行。

    chmod +x spin
    

建立部署管道

  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
    

查看管道執行情況

您剛建立的設定會使用新標記映像檔的通知,系統會推送這些映像檔以觸發 Spinnaker 管道。在上一個步驟中,您已將標記推送到 Cloud Source Repositories,此動作已觸發 Cloud Build 建構映像檔,並將映像檔推送到 Container Registry。現在,您可以查看已觸發的管道。

  1. 按一下 [Pipelines] (管道) 以返回「Pipelines」(管道) 頁面。

  2. 按一下 [Details] (詳細資料) 以查看有關管道進度的詳細資訊。本區段會顯示部署管道的狀態及其步驟:藍色是目前正在執行的步驟;綠色是已成功完成的步驟;紅色是失敗的步驟。按一下任意階段即可查看其詳細資料。

    3 到 5 分鐘後,整合測試階段就會完成。管道需要手動核准,才能繼續進行部署。

  3. 將滑鼠游標懸停在黃色「人形」圖示上,然後按一下 [Continue] (繼續)

    推送到實際工作環境

    發布內容就會繼續傳送到實際工作環境前端和後端部署。這項作業會在幾分鐘後完成。

  4. 如要查看應用程式,請選取 Spinnaker UI 頂端的 [Infrastructure] (基礎架構) > [Load Balancers] (負載平衡器)

    負載平衡器

  5. 向下捲動負載平衡器清單,然後按一下「sample-frontend-production」底下的 [Default] (預設)

    預設負載平衡器

  6. 向下捲動右側的詳細資料窗格,然後按一下「Ingress」(輸入) IP 上的剪貼簿按鈕,以複製應用程式的 IP 位址。根據預設,Spinnaker UI 中的輸入 IP 連結會使用 HTTPS,但應用程式設定為使用 HTTP。

    複製應用程式的 IP 位址

  7. 將該位址貼到瀏覽器中,以查看應用程式的正式版。

    後端

    現在,您已手動觸發管道來建構、測試和部署應用程式。

從程式碼變更觸發管道

在本節中,您將進行程式碼變更、推送 Git 標記,並觀察管道如何執行回應,藉此測試管道端對端。推送開頭為 "v" 的 Git 標記後,就會觸發 Cloud Build 來建構新的 Docker 映像檔,並將映像檔推送到 Container Registry。Spinnaker 會偵測開頭為 "v" 的新映像檔標記並觸發管道,以將映像檔部署到初期測試環境、執行測試,並將同一個映像檔發布到部署中的所有 Pod。

  1. 將應用程式的顏色從橘色變更為藍色:

    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 Build History」(Cloud Build 版本記錄) 中顯示的新版本。

  4. 按一下 [Pipelines] (管道),以觀察管道如何開始部署映像檔。

  5. 觀察初期測試部署。當部署暫停並等待發布到實際工作環境時,請開始重新整理包含應用程式的分頁。您的後端中有四個正在執行舊版的應用程式,只有一個後端正在執行初期測試版本。每當您重新整理到約第十次時,就會看到藍色的應用程式新版本。

  6. 測試完成後,請返回「Spinnaker」分頁,並核准部署。

  7. 管道完成後,應用程式看起來會像下方螢幕擷取畫面。請注意,由於程式碼變更,顏色已變為藍色,且「Version」(版本) 欄位現在顯示為 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. 刪除 Spinnaker 安裝:

    ../helm delete --purge cd
    
  2. 刪除應用程式服務範例:

    kubectl delete -f k8s/services
    
  3. 移除服務帳戶 IAM 繫結:

    export SA_EMAIL=$(gcloud iam service-accounts list \
        --filter="displayName:spinnaker-account" --format='value(email)')
    export PROJECT=$(gcloud info --format='value(config.project)')
    gcloud projects remove-iam-policy-binding $PROJECT --role roles/storage.admin --member serviceAccount:$SA_EMAIL
    
  4. 刪除服務帳戶:

    export SA_EMAIL=$(gcloud iam service-accounts list \
        --filter="displayName:spinnaker-account" --format='value(email)')
    gcloud iam service-accounts delete $SA_EMAIL
    
  5. 刪除 GKE 叢集:

    gcloud container clusters delete spinnaker-tutorial --zone=us-central1-f
    
  6. 刪除存放區:

    gcloud source repos delete sample-app
    
  7. 刪除值區:

    export PROJECT=$(gcloud info --format='value(config.project)')
    export BUCKET=$PROJECT-spinnaker-config
    gsutil -m rm -r gs://$BUCKET
    
  8. 刪除容器映像檔:

    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
    
  9. 如果您已在上方的選用復原步驟中建立 v1.0.2,請刪除該容器映像檔:

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

後續步驟

本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁
解決方案