使用 Spinnaker 在 Kubernetes Engine 中實作持續交付管道

# 概述

在本教程中, 你將會學到如何使用 Google Kubernetes Engine, Google Cloud Source Repositories, Google Cloud Container Builder, 以及 Spinnaker 來建立持續交付管道。 在你建立範例應用之後, 你將設定這些服務, 使他們可以自動建立, 測試, 以及部署。
當你修改了應用的程式碼, 這個變更會觸發持續交付管道, 使用新的版本來重新建立, 測試, 以及部署。




# 目標

  • 藉由啟動 Google Cloud Shell 來設定你的環境, 在裡面建立 Kubernetes Engine 叢集, 設定你的身份以及使用者管理方案
  • 下載範例應用, 建立一個 Git 倉庫, 然後上傳到 Google Cloud Source Repository
  • 使用 Helm 將 Spinnaker 部署到 Kubernetes Engine
  • 建立你的 Docker 鏡像
  • 建立觸發者, 當你的應用變更時, 會建立 Docker 鏡像
  • 設定 Spinnaker 管道來可靠的, 持續地將應用部署到 Kubernetes Engine
  • 部署一個變更過的程式碼, 觸發管道, 然後檢視滾動更新到正式環境的過程



# 管道結構

你需要一個能夠可靠的建立, 測試, 以及更新軟體的自動化的程序來持續地將你的應用更新到使用者手上。 程式碼變更需要全自動化的經由一個管道, 這個管道包含成品建立, 單元測試, 功能測試, 以及正式環境部署。
在某些情況下, 你會想要一個程式碼更新只作用到某部分的用戶, 這樣一來, 這個更新就可以在應用到所有用戶之前實際的先跑過了一次。 如果其中一個 canary 發佈確定不太適合, 你的自動化程序必須要能夠很快的將它回復到更新前的版本。

使用 Kubernetes Engine 以及 Spinnaker, 你可以建立一個可信賴的持續交付流程, 這個流程可以幫你確保你的軟體在開發以及核對之後, 可正確的被交付。 儘管快速部署是我們的最終目標, 但在更新的版次成為正式環境的選項之一之前, 我們必須確保它通過了所有的自動化驗證。 當更新通過了所有的自動化驗證, 你也可以再進行手動驗證, 以及更進一步的實施發布前的測試。

在你的團隊確定這個應用已經可以上正式環境了, 團隊中的其中一個成員可以手動核准這次的正式環境部署。


# 應用交付管道

在本教程中, 你將建立一個如下圖般的持續交付管道




# 前言

本篇主要是利用 Google 的 Qwiklab 平台學習的同時,做的一份學習筆記
為避免翻譯誤解,專業術語在本篇將不會被翻譯,保留原文




# 設定及要求

在你按下 Start Lab 按鈕之前

詳讀所有的教學。 Labs 是有時間限制的, 而且你不可以停止時間倒數。 倒數計時器在你按下 Start Lab 按鈕後開始倒數, 上面顯示的時間為你還能使用 Cloud 資源的時間。

Qwiklabs 的手把手環境, 讓你可以在真實環境中來操作進行 Qwiklabs 上提供的課程, 而不是在一個模擬或是展示的環境。 我們透過提供你一個全新的、暫時的帳號密碼, 在計時器歸零之前, 你可以用來登入並存取 Google Cloud Platform。

你需要什麼?

要完成這個 lab, 你需要:

  • 一個一般的網路瀏覽器(推薦 Chrome)
  • 完成這個 lab 的時間

備註: 如果你已經有你自己的個人 GCP 帳號或專案,請不要使用在這一個 lab

現在你已經開始你的 lab, 你將會登入 Google Cloud Shell 主控台, 然後開啟命令列工具

如何開始你的 lab, 然後登入 Console?

  • 按下 Start Lab 按鈕。 如果你需要付費, 會有一個彈出視窗來讓你選擇付費的方式。 在左方你會看到一個面板, 上面有暫時的帳號密碼, 你必須使用這些帳號密碼在此次 lab

  • 複製 username, 然後點擊 Open Google Console。 Lab 會開啟另外一個視窗, 顯示選擇帳號的頁面

tip: 開啟一個全新的視窗,然後跟原本的頁面並排

  • 選擇帳號頁面, 點擊 Use Another Account

  • 登入頁面開啟, 貼上之前複製的 username 以及 password, 然後貼上

重要:必須使用之前於 Connection Details 面板 取得的帳號密碼,不要使用你自己的 Qwiklabs 帳號密碼。 如果你有自己的 GCP 帳號, 請不要用在這裡(避免產生費用)

  • 點擊並通過接下來的頁面:
    • 接受 terms 以及 conditions
    • 不要增加 recovery optoinstwo factor authentication (因為這只是一個臨時帳號)
    • 不要註冊免費體驗

稍待一些時候, GCP 控制台將會在這個視窗開啟。

**注意:** 按下左上方位於 `Google Cloud Platform` 隔壁的 `Navigation menu`, 你可以瀏覽選單, 裡面有一系列的 GCP 產品以及服務


# 啟動 Google Cloud Shell

Google Cloud Shell 是載有開發工具的虛擬機器。 它提供了5GB的 home 資料夾, 並且運行在 Google Cloud 上。 Google Cloud Shell 讓你可以利用 command-line 存取 GCP 資源

  • GCP 控制台, 右上的工具列,點擊 Open Cloud Shell 按鈕

  • 在打開的對話框裡, 按下 START CLOUD SHELL:

你可以立即按下 START CLOUD SHELL 當對話視窗打開。

連結並提供環境會需要一點時間。 當你連結成功, 這代表你已成功獲得授權, 且此專案已被設為你的專案ID, 例如:

gcloudGoogle Cloud Platform 的 command-line 工具, 他已事先被安裝在 Cloud Shell 並且支援自動補齊

使用這個 command, 你可以列出有效帳戶名稱:

gcloud auth list

輸出:

Credentialed accounts:
- <myaccount>@<mydomain>.com (active)

範例輸出:

Credentialed accounts:
- google1623327_student@qwiklabs.net

你可以使用以下 command 來列出專案 ID

gcloud config list project

輸出:

[core]
project = <project_ID>

範例輸出:

[core]
project = qwiklabs-gcp-44776a13dea667a6

gcloud 的完整文件可以參閱 Google Cloud gcloud Overview




# 設定環境

設定本教程中需要的基礎設施以及身份。 首先, 你將建立 Kubernetes Engine 叢集來部署 Spinnaker 以及範例應用

  • 設定預設 zone

    gcloud config set compute/zone us-central1-f
  • 使用 Spinnaker 教學範例, 建立一個 Kubernetes Engine

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

這個部署將會耗費 5 到 10 分鐘。 你可能會看到一個預設範圍的警告, 你可以忽略他們, 因為對本教程沒有影響。 等待部署完成。

完成之後, 你會看到一些細節資訊, 像是名稱, 地區, 版本, ip-address, 機器類型, node 版本, node 數量, 以及叢集的狀態顯示該叢集已經處於運行中


# 設定身份以及存取管理

建立一個 Cloud Identity Access Management (Cloud IAM) service account 來賦予 Spinnaker 權限, 允許它可以將資料存到 Cloud Storage 。 Spinnaker 將管道資料儲存到 Cloud Storage 以確保可靠度以及復原能力。 如果你的 Spinnaker 部署無預期的失敗了, 你可以利用存取相同管道內的資料, 在幾分鐘內建立一個相同的部署。

經由以下步驟來上傳啟動腳本到 Cloud Storage

  • 建立 service account:
gcloud iam service-accounts create spinnaker-account \
--display-name spinnaker-account
  • 將 service account 的 email 以及目前的專案 ID 存到環境變數, 之後的指令會用到
export SA_EMAIL=$(gcloud iam service-accounts list \
--filter="displayName:spinnaker-account" \
--format='value(email)')
export PROJECT=$(gcloud info --format='value(config.project)')
  • 賦予 service account storage.admin 的角色
gcloud projects add-iam-policy-binding $PROJECT \
--role roles/storage.admin \
--member serviceAccount:$SA_EMAIL
  • 下載 service account 的 key 。 在之後的步驟, 你將會安裝 Spinnaker 以及上傳這個 key 到 Kubernetes Engine:
gcloud iam service-accounts keys create spinnaker-sa.json \
--iam-account $SA_EMAIL

(輸出)

created key [12f224e036437704b91a571792462ca6fc4cd438] of type [json] as [spinnaker-sa.json] for [spinnaker-account@qwiklabs-gcp-gcpd-f5e16da10e5d.iam.gserviceaccount.com]



# 設定 Cloud Pub/Sub 來觸發 Spinnaker 管道

  • 建立 Cloud Pub/Sub 主題來接收 Container Registry 的通知
gcloud pubsub topics create projects/$PROJECT/topics/gcr
  • 建立一個訂閱, 所以 Spinnaker 可以讀取並接收到鏡像已被推送的通知

    gcloud pubsub subscriptions create gcr-triggers \
    --topic projects/${PROJECT}/topics/gcr
  • 給予 Spinnaker 的 service account 權限, 所以它可以讀取 gcr-triggers 的訂閱

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

# 測試進度

點擊 Check my progress 來確認目前的進度。如果你已經完成環境設定,你將獲得一個評價分數。




# 使用 Helm 部署 Spinnaker

在本節中, 你會使用 HelmCharts 倉庫來部署 Spinnaker 。 Helm 是一個套件管理器, 你可以用它來設定以及部署 Kubernetes applications


# 安裝 Helm

  • 下載以及安裝 helm 二進制檔
wget https://storage.googleapis.com/kubernetes-helm/helm-v2.10.0-linux-amd64.tar.gz
  • 解壓縮到本地系統
tar zxfv helm-v2.10.0-linux-amd64.tar.gz
cp linux-amd64/helm .

給予 Tiller 在叢集中 cluster-admin role 的權限, Tiller 是 Helm 的伺服器端

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
  • 賦予 Spinnaker cluster-admin 的權限, 所以 Spinnaker 可以部署資源到所有的命名空間上
kubectl create clusterrolebinding --clusterrole=cluster-admin \
--serviceaccount=default:default spinnaker-admin
  • 安裝 Helm 以及 Tiller 到叢集, Tiller 是 Helm 的 Server 端
./helm init --service-account=tiller
./helm repo update
  • 輸入以下指令, 確定 Helm 已經正確安裝了。 如果 Helm 安裝正確, client 端及 server 端都會輸出 v2.10.0
    ./helm version

(輸出)

Client: &version.Version{SemVer:"v2.10.0", GitCommit:"618447cbf203d147601b4b9bd7f8c37a5d39fbb4", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.10.0", GitCommit:"618447cbf203d147601b4b9bd7f8c37a5d39fbb4", GitTreeState:"clean"}

# 設定 Spinnaker

  • 還是在 Cloud Shell, 建立一個儲存區讓 Spinnaker 可以儲存管道設定資料
export PROJECT=$(gcloud info \
--format='value(config.project)')
export BUCKET=$PROJECT-spinnaker-config
gsutil mb -c regional -l us-central1 gs://$BUCKET
  • 輸入以下指令來建立 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_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 chart

  • 使用 Helm 命令列介面, 用設定檔來部署 chart
./helm install -n cd stable/spinnaker -f spinnaker-config.yaml \
--timeout 600 --version 1.1.6 --wait

這個指令大概會需要 5~6 分鐘 完成

  • 在指令完成後, 輸入以下指令來設定從 Cloud Shell 到 Spinnaker 的 port 轉發規則
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 &

這個指令會花好幾分鐘完成。 再繼續之前, 確認他已經完成了。

  • 點擊 Cloud shell 視窗上方的 Web Preview 圖案, 並選擇 Preview on port 8080 來打開 Spinnaker 使用者介面

會先看到歡迎畫面, 然後是 Spinnaker 使用者介面

保持這個視窗開啟, 這是我們存取 Spinnaker UI 的地方


# 測試進度

點擊 Check my progress 來確認目前的進度。如果你已經正確的使用 Kubernetes Helm 部署 Spinnaker chart,你將獲得一個評價分數。




# 建立 Docker 鏡像

在本節中, 你將設定 Cloud Build 來偵測程式碼變更, 建立 Docker 鏡像, 然後推送到 Container Registry


# 建立源碼倉庫

  • 在 Cloud Shell, 下載範例應用源碼
wget https://gke-spinnaker.storage.googleapis.com/sample-app-v2.tgz
  • 解壓縮
tar xzfv sample-app-v2.tgz
  • 進到源碼目錄
cd sample-app
  • 設定在 Git 當中的 username 以及 email, 將 [USERNAME] 替換成你自己的
git config --global user.email "$(gcloud config get-value core/account)"
git config --global user.name "[USERNAME]"
  • 做第一個 commit
git init
git add .
git commit -m "Initial commit"
  • 建立源碼倉庫
gcloud source repos create sample-app

如果看到你可能會被收費的訊息, 請無視

git config credential.helper gcloud.sh
  • 將剛剛建立的源碼倉庫設為遠端
export PROJECT=$(gcloud info --format='value(config.project)')
git remote add origin https://source.developers.google.com/p/$PROJECT/r/sample-app
  • 推送程式碼到新的倉庫的 master 分支
git push origin master
  • 在主控台點擊 Navigation Menu > Source Repositories, 確認你可以看到你的源碼

  • 點擊 sample-app


# 設定建立觸發者

設定 Container Builder, 所以每次你推送 Git tags 到你的源碼倉庫時, 會自動建立以及推送 Docker 鏡像。 Container Builder 會自動切換到你的程式碼, 依照你倉庫中的 Dockerfile 來建立 Docker 鏡像, 然後推送鏡像到 Google Cloud Container Registry

  • 在 Cloud Platform 主控台, 點擊 Navigation menu > Cloud Build > Triggers
  • 點擊 Create trigger

  • 選擇 Cloud Source Repository, 然後點擊 Continue
  • 選擇你新建立的 sample-app 倉庫, 然後點擊 Continue
  • 設定以下的觸發設定
    • Name: sample-app-tags
    • Trigger type: Tag
    • Tag (regex): v.*
    • Build configuration: Cloud Build configuration file (yaml or json)
    • cloudbuild.yaml location: /cloudbuild.yaml
  • 點擊 Create trigger

從現在開始, 只要你推送一個帶有前綴為 “v” 的 Git tag 到你的源碼倉庫, Container Builder 會自動的建立並推送應用的 Docker 鏡像到 Container Registry


# 準備將使用在 Spinnaker 的 Kubernetes Manifests (Kubernetes 的部署文件)

要部署到你的集群, Spinnaker 需要存取你的 Kubernetes manifests 。 本節中會建立一個 Cloud Storage 儲存區, 這個儲存區會在 Cloud Build 的 CI 過程中載入 manifest 。 當你的 manifest 被存在 Cloud Storage 之後, Spinnaker 可以在整個管道執行過程中, 下載以及應用它

  • 建立儲存區

    export PROJECT=$(gcloud info --format='value(config.project)')
    gsutil mb -l us-central1 gs://$PROJECT-kubernetes-manifests
  • 啟用儲存區的 versioning (物件版本管理), 所以我們將有整個 manifests 的歷史

    gsutil versioning set on gs://$PROJECT-kubernetes-manifests
  • 在 Kubernetes deployment manifests 中設定正確的 project ID

    sed -i s/PROJECT/$PROJECT/g k8s/deployments/*
  • 提交 commit 到倉庫

    git commit -a -m "Set project ID"

# 建立鏡像

按照以下步驟, 推送你的第一個鏡像

  • 在 Cloud Shell, sample-app 資料夾, 建立一個 Git tag:

    git tag v1.0.0
  • 推送 tag

    git push --tags

(輸出)

To https://source.developers.google.com/p/qwiklabs-gcp-ddf2925f84de0b16/r/sample-app
* [new tag] v1.0.0 -> v1.0.0
  • 到 GCP 主控台。 在 Cloud Build, 點擊左方面板的 History, 確認 build 是否已經被觸發。 若否, 確認在之前的章節中, trigger 有正確的被設定

先在此頁面等待, 待 build 完成, 再到下一個章節


# 測試進度

點擊 Check my progress 來確認目前的進度。如果你已經成功建立 Docker 鏡像,你將獲得一個評價分數。




# 設定部署管道

現在你的鏡像已經自動地被建立, 你需要將他們部署到 Kubernetes 叢集
部署到規模縮減的環境來實施整合測試。 整合測試通過後, 手動核准這次的變更來將代碼部署到正式生產服務。


# 安裝 spin CLI 來管理 Spinnaker

spin 是用來管理 Spinnaker 的應用以及管道的命令列工具

  • 下載 1.6 版本的 spin

    curl -LO https://storage.googleapis.com/spinnaker-artifacts/spin/1.6.0/linux/amd64/spin
  • 使 spin 可執行

    chmod +x spin

# 建立部署管道

  • 使用 spin, 在 Spinnaker 建立一個叫做 sample 的應用。 設定使用者 email
    ./spin application save --application-name sample \
    --owner-email "$(gcloud config get-value core/account)" \
    --cloud-providers kubernetes \
    --gate-endpoint http://localhost:8080/gate

請忽略 Cloud not read configuration file... 輸出訊息

接下來, 建立一個持續交付管道。 在本教程中, 管道被設定偵測, 當一個前綴為 “v” 的 tag 被推送到我們的 Container Registry

  • sample-app 程式碼資料夾, 執行以下命令來更新範例管道到 Spinnaker instance
    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

請忽略 Cloud not read configuration file... 輸出訊息


# 手動觸發以及檢視你的管道執行狀況

當有鏡像被推送且有符合規則的新標籤時, 我們剛剛建立的設定會觸發 Spinnaker 管道。 在之前的步驟中, 我們推送一個標籤到 Cloud Source Repositories, 然後觸發 Cloud Build 來建立以及推送我們的鏡像到 Container Registry 。 要核准這個管道, 手動觸發

  • 在 Spinnaker UI 介面, 在螢幕最上方點擊 Application 來檢視被管理應用的清單。 sample 是我們的應用。 如果你沒看到 sample, 嘗試重刷新 Spinnaker Application 頁面

  • 點擊 sample 來檢視你的應用部署

  • 在上方點擊 Pipelines 來檢視你的應用管道狀態

  • 點擊 Start Manual Execution 來首次觸發管道

  • 點擊 Run

  • 點擊 Details 來檢視管道進度的更多資訊

進度條顯示部署管道的狀態以及階段

藍色部分為目前正在運行中, 綠色為已經成功完成, 紅色為已經失敗的

  • 點擊一個階段來看細節資訊
    3 ~ 5 分鐘 後, 整合測試階段完成, 且管道需要手動核准來持續部署

  • 在游標停在黃色的”人形”圖案上, 並且點擊 Continue

你的推送持續的到正式環境的前端以及後端部署。 它在幾分鐘後完成。

  • 在 Spinnaker UI 的上方選擇 **Infrastructure > Load Balancers 來檢視 app

  • 下捲 load balancers 清單並且在 service sample-frontend-production 下點擊 Default

  • 在右方 details 面板下捲並且在 Ingress IP 點擊 clipboard 按鈕來複製你的 app IP 位址。 Spinnaker UI 頁面的 ingress IP 預設為 HTTPS, 儘管應用是被設定使用 HTTP

  • 將位址貼到一個新的視窗來檢視應用的正式版本

現在你已經手動的觸發管道建立, 測試, 以及部署你的應用


# 測試進度

點擊 Check my progress 來確認目前的進度。如果你已經成功建立服務平衡負載,你將獲得一個評價分數。


# 測試進度

點擊 Check my progress 來確認目前的進度。如果你已經成功部署鏡像到正式環境,你將獲得一個評價分數。




# 從程式碼變更來觸發你的管道

現在讓我們改變程式碼, 推送一個 Git 標籤, 以及檢視管道執行的回應來從端對端的測試管道。 藉由推送前綴為 “v” 的 Git 標籤來觸發 Container Builder 建立一個新的 Docker 鏡像, 然後將它推送到 Container Registry 。 Spinnaker 將偵測是否有新的有著 Git 標籤為 “v” 的鏡像被推送, 然後觸發管道來部署鏡像到 canaries, 運行 tests, 然後推送一樣的鏡像到所有 deployment 中的所有 pods

  • 在 sample-app 資料夾, 將 app 的顏色從 orange 改成 blue

    sed -i 's/orange/blue/g' cmd/gke-info/common-service.go
  • 將變更的 commit 貼上標籤並且推送到程式碼倉庫

    git commit -a -m "Change color to blue"
    git tag v1.0.1
    git push --tags
  • 在主控台, Cloud Build > History, 等待幾分鐘待新的 build 完成。 到下一個步驟之前, 你可能需要重整你的頁面, 等待新的 build 完成

  • 回到 Spinnaker UI 並點擊 Pipelines 來檢視管道正開始部署。 自動被觸發的管道將需要幾分鐘才會顯示在頁面上, 你可能需要重刷新頁面。


# 測試進度

點擊 Check my progress 來確認目前的進度。如果你已經成功從程式碼變更觸發管道,你將獲得一個評價分數。




# 觀察 canary 部署

  • 當部署停下, 等待推送到正式環境時, 我們回到網頁顯示運行中的應用並且重整頁面。 後端中有 四個正運行之前版本的應用, 而只有一個後端運行 canary 。 你可以看到那個藍色新版本的應用大概每重整五次會出現一次

  • 在測試完成後, 回到 Spinnaker 頁面, 點擊 Continue 來核准部署

當管道完成後, 你的 app 看起來會像以下的截圖一樣。 注意到顏色都已經變成藍色因為你的程式碼變了, 而且 Version 欄位目前顯示 production

你已經成功地將你的 app 推送到整個正式環境

  • 你也可以藉由取消當前版本來取消變更。 取消當前版本並且新增一個標籤, 然後經由同一個管道部署

    git revert v1.0.1
    git tag v1.0.2
    git push --tags
  • 當 build 以及管道完成, 點擊 Infrastructure > Load Balancers 來核准這次的回滾, 然後點擊 service sample-frontend-canary Default, 然後複製 Ingress IP 位址到新的視窗

現在你的應用已經回到橘色, 且你可以看到 canary 的版本號




# 恭喜

你已經完成本教程




# Q&A

以下的 gcloud command 的意思是?
  • Example:
    gcloud iam service-accounts create spinnaker-account \
    --display-name spinnaker-account
  • Answer:
    建立一個名為 spinnaker-account 的 service account
    --display-name: 好記的名稱為 spinnaker-account
以下 gcloud 指令的意思?
export SA_EMAIL=$(gcloud iam service-account list \
--filter="displayName:spinnaker-account" \
--format='value(email)')
- `export`: 將 SA_EMAIL 的值變成環境變數
- `--filter`: 取得 displayName 為 spinnaker-account 的那一行
- `--format`: 取得上面那行 email 的值
以下 gcloud 指令的意思?
export PROJECT=$(gcloud info --format='value(config.project)')
- `--format`: 取得 info 輸出中的 config property 下的 project 
- 可使用 --format=json 來檢視, 會比較清楚
以下 gcloud 指令的意思?
gcloud projects add-iam-policy-binding $PROJECT \
--role roles/storage.admin \
--member serviceAccount:$SA_EMAIL
- 在指定專案中, 新增 add-iam-policy-binding
- policy 是 binding 的集合
- binding 綁定了一個或多個 member 到一個單獨的 role
- `--role`: 賦予 roles/storage.admin 的角色
- `--member`: 透過 service account 綁定這個 member 到這個專案
以下的 gcloud command 的意思是?
  • Example:
    gcloud iam service-accounts keys create spinnaker-sa.json \
    --iam-account $SA_EMAIL
  • Answer:
    建立一把 service account 的 private key
    spinnaker-sa.json 為輸出的 key name
    --iam-account 為指定 service account 的 email
以下 gcloud 指令的意思?
gcloud pubsub topics create projects/$PROJECT/topics/gcr
- 建立一個 topic, 名為 project/$PROJECT/topics/gcr
以下 gcloud 指令的意思?
gcloud pubsub subscriptions create gcr-triggers \
--topic projects/${PROJECT}/topics/gcr
- 建立一個 subscriptions, 名為 gcr-triggers
- 接收的 topic 為 project/${PROJECT}/topics/gcr
以下 gcloud 指令的意思?
gcloud beta pubsub subscriptions add-iam-policy-binding gcr-triggers \
--role roles/pubsub.subscriber --member serviceAccount:$SA_EMAIL
- 在 gcr-triggers 這個 subscriptions 建立一個政策繫結
- role 為 pubsub 的 subscriber
- member 為 spinnaker 的 service account
以下 kubectl 指令的意思?
kubectl create clusterrolebinding user-admin-binding \
--clusterrole=cluster-admin --user=$(gcloud config get-value account)
- 建立一個叢集角色綁定, 名為 user-admin-binding
- 叢集角色為 cluster-admin, 為系統內建角色
- user 為預設帳號的擁有者
tiller 跟 helm 的關係?

如下圖, Helm 為 client 端, Tiller 為 server 端

以下 kubectl 指令的意思?
kubectl create clusterrolebinding --clusterrole=cluster-admin \
--serviceaccount=default:default spinnaker-admin
- 建立一個叢集角色綁定
- 綁定的角色的叢集預設的 cluster-admin
- serviceaccount 為 default 命名空間下的 default service account
- 該綁定的名稱為, spinnaker-admin
以下 helm 指令的意思?
./helm init --service-account=tiller
- 安裝 tiller 到 server 端
- 使用 service-account 名為 tiller
以下 gsutil 指令的意思?
gsutil mb -c regional -l us-central1 gs://$BUCKET
- `gsutil`: google storage utility
- `mb`: make a bucket
- `-c`: class, 儲存空間等級
- `-l`: location, 位置
- `gs://$BUCKET`: 儲存區的名稱
以下的 spinnaker 的 yaml 檔中, gcs 的區塊部分代表什麼意思?

設定預設儲存後端為 gcs, 可參考官方文件

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'
以下的 spinnaker 的 yaml 檔中, dockerRegistries 的區塊部分代表什麼意思?

設定 docker registry 為 Google Container Registry, 可參考官方文件

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

dockerRegistries:
- name: gcr
address: https://gcr.io
username: _json_key
password: '$SA_JSON'
email: 1234@5678.com
Spinnaker 的預設儲存服務為?

minio, 可參考文件

Spinnaker 的 artifact 是什麼?

代表一個參考外部資源的物件, 可參考文件

以下的 Spinnaker 指令是什麼意思?
- 啟用 GCP pubsub 服務
- 增加一個名為 gcr-trigger 的 subscription 到 pubsub
- subscription 的 name 為 gcr-trigger
- 可參考[文件](https://www.spinnaker.io/reference/halyard/commands/#hal-config-pubsub-google-subscription-add)
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

halyard:
spinnakerVersion: 1.10.2
image:
tag: 1.12.0
additionalScripts:
create: true
data:
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 指令是什麼意思?
- 啟用 GCS 服務
- 增加一個 artifact account 到 GCS provider
- 可參考[文件](https://www.spinnaker.io/reference/halyard/commands/#hal-config-artifact-gcs-account-add)
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

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
EOF
以下的指令中, |- 代表什麼意思?
- `|` 為 Block Style Indicator, literal style, 如果 string 當中有空行, 會被保留下來
- `-` 為 Block Chomping Indicator, strip style, 在 string 結尾不保留任何空行
- 可參考[文件](https://yaml.org/spec/1.2/spec.html#id2794534)
- 可參考 [Stackoverflow](https://stackoverflow.com/questions/3790454/how-do-i-break-a-string-over-multiple-lines)
- 可參考[範例](https://yaml-multiline.info/)
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

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
以下的 helm 指令是什麼意思?
./helm install -n cd stable/spinnaker -f spinnaker-config.yaml \
--timeout 600 --version 1.1.6 --wait
- **-n**: namespace 為 cd
- **-f**: file 為 spannaker-config.yaml
- **--timeout**: timeout 600 秒
- **--version**: 版本 1.1.6
- **--wait**: helm 會等待所有的 Pods 都 ready, PVCs 掛載, 部署有達到最小數量, 狀態為 ready 的 Pods, server 有 IP 位址, 可參考[文件](https://helm.sh/docs/intro/using_helm/#helpful-options-for-install-upgrade-rollback)
以下指令的意思是?
export DECK_POD=$(kubectl get pods --namespace default -l "cluster=spin-deck" \
-o jsonpath="{.items[0].metadata.name}")
- **export**: 將輸出設為環境變數
- **--namespace**: 取得該 namespace 中的資源
- **-l**: selector(label)
- **-o**: 指定輸出格式
以下指令的意思是?
kubectl port-forward --namespace default $DECK_POD 8080:9000 >> /dev/null &
- **port-forward**: 轉發 port 指令
- **--namespace**: 指定命名空間
- **$DECK_POD**: port 的名稱
- **8080:9000**: 指定外面的 8080 port 到 pod 的 9000 port, 再將輸出隱藏。
以下指令的用途是?
git config credential.helper gcloud.sh

正常來說, 新增一個遠端 git 倉庫會需要設定 ssh 金鑰, 上面指令可以省略這個步驟, 讓我們可以使用我們在 gcloud 的 key 來做到這件事

以下指令的意思是?
sed -i s/PROJECT/$PROJECT/g k8s/deployments/*

找到 PROJECT, 並把他替換成 $PROJECT, $PROJECT 為事先設好的變數, 尋找對象為 k8s/deployments/ 下面所有的檔案

Spinnaker 中, spin 是什麼?

spinnaker 的 CLI 管理工具

以下的程式碼代表什麼意思?
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
- 利用 gcloud 指令取得 project, 在帶入變數 PROJECT 並將之變成環境變數
- sed 指令將 pipeline-deploy.json 檔案中的 PROJECT 替換為上一部取得的 $PROJECT 變數的值, 在複製一份到新檔案 pipeline.json
- 使用 spin 建立一個 pipeline, 參數為上一部建立的檔案 pipeline.json, gate-endpoint 會通往遠端部署 spinnaker 的機器
以下的 cloud build 設定黨的意思是?
steps:
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '--tag=gcr.io/$PROJECT_ID/sample-app:$TAG_NAME', '.']
- name: 'gcr.io/cloud-builders/docker'
args: ['run', 'gcr.io/$PROJECT_ID/sample-app:$TAG_NAME', 'go', 'test']
- name: 'gcr.io/cloud-builders/gsutil'
args: ['cp', '-r', 'k8s/*', 'gs://$PROJECT_ID-kubernetes-manifests']
images: ['gcr.io/$PROJECT_ID/sample-app:$TAG_NAME']
- steps: 建構執行步驟
- name: 雲端建構工具, 可參考[文件](https://cloud.google.com/cloud-build/docs/build-config?hl=zh-tw#build_steps), 以及[文件](https://cloud.google.com/cloud-build/docs/cloud-builders?hl=zh-tw)
- args: 會被傳送至 `name` 欄位參照的建構工具。 若建構工具擁有進入點, 則 args 為 args, 若否, 則第一個 args 為進入點。
- images: 要傳送到 Container Registry 的鏡像, 可參考[文件](https://cloud.google.com/cloud-build/docs/build-config?hl=zh-tw#images) 以及 [文件](https://cloud.google.com/cloud-build/docs/configuring-builds/store-images-artifacts?hl=zh-tw)
以下的 gsutil 指令是什麼意思?
gsutil versioning set on gs://$PROJECT-kubernetes-manifests
- 啟用物件版本管理功能, 啟用後, 每當物件的使用中版本遭到複寫或刪除, Cloud Storage 會為該物件建立一個[封存版本](https://cloud.google.com/storage/docs/object-versioning?hl=zh-tw), 可參考[文件](https://cloud.google.com/storage/docs/using-object-versioning?hl=zh-tw)
Laravel - EloquentORM - Relationships <未完成> 使用 Stackdriver 在 Kubernetes Engine 上實施監控

留言

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×