1. 簡介
Cloud Spanner 是全代管且遍及全球的關聯資料庫服務,提供 ACID 交易和 SQL 語意,但不會犧牲效能及高可用性。
GKE Autopilot 是 GKE 的作業模式,Google 會管理您的叢集設定,包括節點、資源調度、安全性,以及遵循最佳做法的其他預設設定。舉例來說,GKE Autopilot 會啟用 Workload Identity 來管理服務權限。
本研究室的目標是逐步引導您將多項在 GKE Autopilot 上執行的後端服務連結至 Cloud Spanner 資料庫。
在本研究室中,您將先設定專案並啟動 Cloud Shell。接著,您會透過 Terraform 部署基礎架構。
完成後,您需要與 Cloud Build 和 Cloud Deploy 互動,為遊戲資料庫執行初始結構定義遷移作業、部署後端服務,然後部署工作負載。
本程式碼研究室中的服務與「Cloud Spanner 開始使用遊戲開發」程式碼研究室中的服務相同。即使沒有參加該程式碼研究室,也能在 GKE 中執行服務並連線至 Spanner。不過,如果您有意進一步瞭解能在 Spanner 中運作的服務,歡迎多加參考。
工作負載和後端服務開始運作之後,您就可以開始產生負載,並觀察這些服務如何搭配運作。
最後,您將清除在這個研究室中建立的資源。
建構項目
在這個研究室中,您將完成以下工作:
- 使用 Terraform 佈建基礎架構
- 在 Cloud Build 中使用結構定義遷移程序建立資料庫結構定義
- 部署四個使用 Workload Identity 來連線至 Cloud Spanner 的 Golang 後端服務
- 部署四個工作負載服務,用來模擬後端服務的負載。
課程內容
- 如何使用 Terraform 佈建 GKE Autopilot、Cloud Spanner 和 Cloud Deploy 管道
- Workload Identity 如何讓 GKE 上的服務以服務帳戶的身分存取 IAM 權限,以便與 Cloud Spanner 搭配使用
- 如何使用 Locust.io 在 GKE 和 Cloud Spanner 中產生類似實際工作環境的負載
軟硬體需求
2. 設定和需求
建立專案
如果您還沒有 Google 帳戶 (Gmail 或 Google Apps),請先建立帳戶。登入 Google Cloud Platform 控制台 ( console.cloud.google.com),並建立新專案。
如果您已有專案,請按一下控制台左上方的專案選取下拉式選單:
並按一下 [新增專案]按鈕,用於建立新專案:
如果您還沒有專案,系統會顯示如下的對話方塊,讓您建立第一個專案:
後續的專案建立對話方塊可讓您輸入新專案的詳細資料:
請記住,專案 ID 在所有的 Google Cloud 專案中是不重複的名稱 (已經有人使用上述名稱,目前無法為您解決問題!)。稍後在本程式碼研究室中會稱為 PROJECT_ID
。
接下來,如果您尚未在 Developers Console 中啟用計費功能,必須完成此步驟,才能使用 Google Cloud 資源並啟用 Cloud Spanner API。
執行本程式碼研究室所需的費用不應超過數美元,但如果您決定使用更多資源,或讓這些資源繼續運作,費用會增加 (請參閱本文件結尾的「清理」一節)。Google Cloud Spanner 的定價請參閱這裡;GKE Autopilot 請參閱這裡。
Google Cloud Platform 的新使用者符合 $300 美元的免費試用資格,應該可以免費使用本程式碼研究室。
Cloud Shell 設定
雖然 Google Cloud 和 Spanner 可以在筆記型電腦上遠端運作,但在本程式碼研究室中,我們會使用 Google Cloud Shell,這是一種在 Cloud 中執行的指令列環境。
這種以 Debian 為基礎的虛擬機器,搭載各種您需要的開發工具。提供永久的 5 GB 主目錄,而且在 Google Cloud 中運作,大幅提高網路效能和驗證能力。換言之,本程式碼研究室只需要在 Chromebook 上運作即可。
- 如要透過 Cloud 控制台啟用 Cloud Shell,只要點選「啟用 Cloud Shell」圖示 ,即可佈建並連線至環境,操作只需幾分鐘的時間。
連線至 Cloud Shell 後,您應會發現自己通過驗證,且專案已設為 PROJECT_ID
。
gcloud auth list
指令輸出
Credentialed accounts:
- <myaccount>@<mydomain>.com (active)
gcloud config list project
指令輸出
[core]
project = <PROJECT_ID>
如因故未設定專案,請直接發出以下指令:
gcloud config set project <PROJECT_ID>
正在尋找 PROJECT_ID
嗎?查看您在設定步驟中使用的 ID,或在 Cloud 控制台資訊主頁查詢:
根據預設,Cloud Shell 也會設定一些環境變數,方便您之後執行指令。
echo $GOOGLE_CLOUD_PROJECT
指令輸出
<PROJECT_ID>
下載程式碼
在 Cloud Shell 中,您可以下載本研究室的程式碼:
git clone https://github.com/cloudspannerecosystem/spanner-gaming-sample.git
指令輸出
Cloning into 'spanner-gaming-sample'...
*snip*
本程式碼研究室是以 v0.1.3 版本為基礎,因此請查看該標記:
cd spanner-gaming-sample
git fetch --all --tags
# Check out v0.1.3 release
git checkout tags/v0.1.3 -b v0.1.3-branch
指令輸出
Switched to a new branch 'v0.1.3-branch'
現在,將目前的工作目錄設為 DEMO_HOME 環境變數。這可讓您在使用程式碼研究室的不同部分時輕鬆瀏覽。
export DEMO_HOME=$(pwd)
摘要
在這個步驟中,您設定了新專案、已啟用 Cloud Shell,並下載這個研究室的程式碼。
下一步
接下來,您將透過 Terraform 佈建基礎架構。
3. 佈建基礎架構
總覽
專案準備就緒後,就可以開始執行基礎架構了。這類元件包括虛擬私有雲網路、Cloud Spanner、GKE Autopilot 和 Artifact Registry,可用於儲存要在 GKE 上執行的映像檔、後端服務和工作負載的 Cloud Deploy 管道,以及使用這些服務的服務帳戶和 IAM 權限。
它有很多種。幸好,Terraform 可以簡化這項設定程序。Terraform 是「基礎架構即程式碼」方便我們在一系列「.tf」中為這項專案指定所需項目檔案。這麼一來,您就能輕鬆佈建基礎架構。
熟悉 Terraform 並非完成本程式碼研究室的必要條件。不過,如果您想查看接下來的幾個步驟,可以前往 infrastructure 目錄查看這些檔案建立的所有內容:
- vpc.tf
- backend_gke.tf
- spanner.tf
- artifact_registry.tf
- pipelines.tf
- iam.tf
設定 Terraform
在 Cloud Shell 中,您要變更為 infrastructure
目錄並初始化 Terraform:
cd $DEMO_HOME/infrastructure
terraform init
指令輸出
Initializing the backend...
Initializing provider plugins...
*snip*
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
接著,複製 terraform.tfvars.sample
並修改專案值來設定 Terraform。您也可以變更其他變數,但專案是唯一要變更的專案,才能與您的環境搭配運作。
cp terraform.tfvars.sample terraform.tfvars
# edit gcp_project using the project environment variable
sed -i "s/PROJECT/$GOOGLE_CLOUD_PROJECT/" terraform.tfvars
佈建基礎架構
現在要佈建基礎架構了!
terraform apply
# review the list of things to be created
# type 'yes' when asked
指令輸出
Plan: 46 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
google_project_service.project["container.googleapis.com"]: Creating...
*snip*
Apply complete! Resources: 46 added, 0 changed, 0 destroyed.
查看建立的內容
如要確認建立的內容,請查看 Cloud 控制台中的產品。
Cloud Spanner
首先,前往漢堡選單並點選 Spanner
,查看 Cloud Spanner。您可能需要點選「查看更多產品」以便從清單中找出該代碼
系統會將您導向 Spanner 執行個體清單。點進執行個體,即可查看資料庫。如下所示:
GKE Autopilot
接著,前往漢堡選單並點選「Kubernetes Engine => Clusters
」,查看 GKE。這裡會顯示 sample-games-gke
叢集在 Autopilot 模式下執行。
Artifact Registry
接著,您需要查看圖片的儲存位置。因此,請按一下漢堡選單,然後找出「Artifact Registry=>Repositories
」。Artifact Registry 位於選單的「CI/CD」專區中。
在這裡,您會看到名為 spanner-game-images
的 Docker Registry。目前沒有任何內容。
Cloud Deploy
Cloud Deploy 是建立管道的位置,可讓 Cloud Build 提供建構映像檔的步驟,然後將映像檔部署至 GKE 叢集。
前往漢堡選單並找出 Cloud Deploy
,它也位於選單的「CI/CD」部分中。
您會在這裡看到兩個管道,一個用於後端服務,另一個用於工作負載。兩者都會將映像檔部署至同一個 GKE 叢集,但這麼做可以將部署作業區隔開來。
IAM
最後,請前往 Cloud 控制台的「IAM」頁面,驗證建立的服務帳戶。前往漢堡選單並找到 IAM and Admin=>Service accounts
。如下所示:
Terraform 建立的服務帳戶總共有六個:
- 預設電腦服務帳戶。未在本程式碼研究室中用到。
- cloudbuild-cicd 帳戶會用於 Cloud Build 和 Cloud Deploy 步驟。
- 四個「應用程式」,透過這個帳戶與 Cloud Spanner 互動。
接下來,您要設定 kubectl
來與 GKE 叢集互動。
設定 kubectl
# Name of GKE cluster from terraform.tfvars file
export GKE_CLUSTER=sample-game-gke
# get GKE credentials
gcloud container clusters get-credentials $GKE_CLUSTER --region us-central1
# Check that no errors occur
kubectl get serviceaccounts
指令輸出
#export GKE_CLUSTER=sample-game-gke
# gcloud container clusters get-credentials $GKE_CLUSTER --region us-central1
Fetching cluster endpoint and auth data.
kubeconfig entry generated for sample-game-gke.
# kubectl get serviceaccounts
NAME SECRETS AGE
default 0 37m
item-app 0 35m
matchmaking-app 0 35m
profile-app 0 35m
tradepost-app 0 35m
摘要
太好了!您已成功佈建 Cloud Spanner 執行個體,也就是 GKE Autopilot 叢集,所有作業都在虛擬私有雲中,以建立私人網路。
此外,您也為後端服務和工作負載建立了兩個 Cloud Deploy 管道,以及一個用於儲存建構映像檔的 Artifact Registry 存放區。
最後,已建立並設定服務帳戶,藉此與 Workload Identity 搭配使用,好讓後端服務能使用 Cloud Spanner。
在部署後端服務和工作負載後,您也將 kubectl
設為在 Cloud Shell 中與 GKE 叢集互動。
下一步
您必須先定義資料庫結構定義,才能使用服務。接下來,您會完成設定。
4. 建立資料庫結構定義
總覽
執行後端服務前,您必須確保資料庫結構定義已設置妥當。
如果您在示範存放區中查看「$DEMO_HOME/schema/migrations
」目錄中的檔案,就會看到一系列定義結構定義的 .sql
檔案。這種作法是模仿的開發週期,存放區本身會追蹤結構定義變更,並且可與應用程式的特定功能連結。
在此範例環境中,扳手是可使用 Cloud Build 套用結構定義遷移的工具。
Cloud Build
$DEMO_HOME/schema/cloudbuild.yaml
檔案說明將執行的步驟:
serviceAccount: projects/${PROJECT_ID}/serviceAccounts/cloudbuild-cicd@${PROJECT_ID}.iam.gserviceaccount.com
steps:
- name: gcr.io/cloud-builders/curl
id: fetch-wrench
args: ['-Lo', '/workspace/wrench.tar.gz', 'https://github.com/cloudspannerecosystem/wrench/releases/download/v1.4.1/wrench-1.4.1-linux-amd64.tar.gz' ]
- name: gcr.io/cloud-builders/gcloud
id: migrate-spanner-schema
entrypoint: sh
args:
- '-xe'
- '-c'
- |
tar -xzvf wrench.tar.gz
chmod +x /workspace/wrench
# Assumes only a single spanner instance and database. Fine for this demo in a dedicated project
export SPANNER_PROJECT_ID=${PROJECT_ID}
export SPANNER_INSTANCE_ID=$(gcloud spanner instances list | tail -n1 | awk '{print $1}')
export SPANNER_DATABASE_ID=$(gcloud spanner databases list --instance=$$SPANNER_INSTANCE_ID | tail -n1 | awk '{print $1}')
if [ -d ./migrations ]; then
/workspace/wrench migrate up --directory .
else
echo "[Error] Missing migrations directory"
fi
timeout: 600s
基本上包含兩個步驟
- 將扳手下載至 Cloud Build 工作區
- 執行扳手遷移
必須要有 Spanner 專案、執行個體和資料庫環境變數,扳手才能連線至寫入端點。
Cloud Build 會以 cloudbuild-cicd@${PROJECT_ID}.iam.gserviceaccount.com
服務帳戶的身分執行,因此可以進行這些變更:
serviceAccount: projects/${PROJECT_ID}/serviceAccounts/cloudbuild-cicd@${PROJECT_ID}.iam.gserviceaccount.com
這個服務帳戶由 Terraform 新增 spanner.databaseUser
角色,可讓服務帳戶 updateDDL。
結構定義遷移作業
系統會根據 $DEMO_HOME/schema/migrations
目錄中的檔案執行五個遷移步驟。以下是建立 players
資料表和索引的 000001.sql
檔案範例:
CREATE TABLE players (
playerUUID STRING(36) NOT NULL,
player_name STRING(64) NOT NULL,
email STRING(MAX) NOT NULL,
password_hash BYTES(60) NOT NULL,
created TIMESTAMP,
updated TIMESTAMP,
stats JSON,
account_balance NUMERIC NOT NULL DEFAULT (0.00),
is_logged_in BOOL,
last_login TIMESTAMP,
valid_email BOOL,
current_game STRING(36)
) PRIMARY KEY (playerUUID);
CREATE UNIQUE INDEX PlayerAuthentication ON players(email) STORING(password_hash);
CREATE UNIQUE INDEX PlayerName ON players(player_name);
CREATE INDEX PlayerGame ON players(current_game);
提交結構定義遷移作業
如要提交版本來執行結構定義遷移,請切換至 schema
目錄並執行下列 gcloud 指令:
cd $DEMO_HOME/schema gcloud builds submit --config=cloudbuild.yaml
指令輸出
Creating temporary tarball archive of 8 file(s) totalling 11.2 KiB before compression.
Uploading tarball of [.] to [gs://(project)_cloudbuild/source/(snip).tgz]
Created [https://cloudbuild.googleapis.com/v1/projects/(project)/locations/global/builds/7defe982-(snip)].
Logs are available at [ https://console.cloud.google.com/cloud-build/builds/7defe982-(snip)?project=(snip) ].
gcloud builds submit only displays logs from Cloud Storage. To view logs from Cloud Logging, run:
gcloud beta builds submit
ID: 7defe982-(snip)
CREATE_TIME: (created time)
DURATION: 3M11S
SOURCE: gs://(project)_cloudbuild/source/(snip).tgz
IMAGES: -
STATUS: SUCCESS
在上方的輸出內容中,您會看到 Created
雲端建構程序的連結。點選該名稱後,系統會將您導向 Cloud 控制台中的建構作業,方便您監控建構作業的進度及瞭解建構內容。
摘要
在這個步驟中,您使用了 Cloud Build 來提交套用 5 項不同 DDL 作業的初始結構定義遷移作業。這類作業代表了何時新增的特徵,需要變更資料庫結構定義。
在正常的開發情境中,您可能會想要進行與目前應用程式回溯相容的結構定義變更,以免服務中斷。
如果變更無法回溯相容,建議您分階段部署應用程式和結構定義的變更,以免服務中斷。
下一步
備妥結構定義後,下一步就是部署後端服務!
5. 部署後端服務
總覽
本程式碼研究室的後端服務是代表四種不同服務的 golang REST API:
- 設定檔:讓玩家註冊並驗證我們的「遊戲」範例。
- 配對:與玩家資料互動,協助配對功能、追蹤已建立遊戲的相關資訊,並在遊戲結束後更新玩家統計資料。
- 項目:讓玩家在玩遊戲的過程中取得遊戲道具和金錢。
- Tradepost:讓玩家可以在貿易站上買賣商品
如要進一步瞭解這些服務,請參閱 Cloud Spanner 開始使用遊戲開發程式碼研究室。基於我們的目的,我們希望這些服務在 GKE Autopilot 叢集中執行。
這些服務必須能夠修改 Spanner 資料。為此,每項服務都具備已建立的服務帳戶,藉此授予「databaseUser」角色。
Workload Identity 可讓 Kubernetes 服務帳戶冒用服務,按照以下步驟操作 Terraform:
- 建立服務的 Google Cloud 服務帳戶 (
GSA
) 資源 - 將 databaseUser 角色指派給該服務帳戶
- 將 workloadIdentityUser 角色指派給該服務帳戶
- 建立參照 GSA 的 Kubernetes 服務帳戶 (
KSA
)
粗略的圖表如下所示:
Terraform 已為您建立服務帳戶和 Kubernetes 服務帳戶。您也可以使用 kubectl
查看 Kubernetes 服務帳戶:
# kubectl get serviceaccounts
NAME SECRETS AGE
default 0 37m
item-app 0 35m
matchmaking-app 0 35m
profile-app 0 35m
tradepost-app 0 35m
建構的運作方式如下:
- Terraform 產生的
$DEMO_HOME/backend_services/cloudbuild.yaml
檔案會如下所示:
serviceAccount: projects/${PROJECT_ID}/serviceAccounts/cloudbuild-cicd@${PROJECT_ID}.iam.gserviceaccount.com
steps:
#
# Building of images
#
- name: gcr.io/cloud-builders/docker
id: profile
args: ["build", ".", "-t", "${_PROFILE_IMAGE}"]
dir: profile
waitFor: ['-']
- name: gcr.io/cloud-builders/docker
id: matchmaking
args: ["build", ".", "-t", "${_MATCHMAKING_IMAGE}"]
dir: matchmaking
waitFor: ['-']
- name: gcr.io/cloud-builders/docker
id: item
args: ["build", ".", "-t", "${_ITEM_IMAGE}"]
dir: item
waitFor: ['-']
- name: gcr.io/cloud-builders/docker
id: tradepost
args: ["build", ".", "-t", "${_TRADEPOST_IMAGE}"]
dir: tradepost
waitFor: ['-']
#
# Deployment
#
- name: gcr.io/google.com/cloudsdktool/cloud-sdk
id: cloud-deploy-release
entrypoint: gcloud
args:
[
"deploy", "releases", "create", "${_REL_NAME}",
"--delivery-pipeline", "sample-game-services",
"--skaffold-file", "skaffold.yaml",
"--skaffold-version", "1.39",
"--images", "profile=${_PROFILE_IMAGE},matchmaking=${_MATCHMAKING_IMAGE},item=${_ITEM_IMAGE},tradepost=${_TRADEPOST_IMAGE}",
"--region", "us-central1"
]
artifacts:
images:
- ${_REGISTRY}/profile
- ${_REGISTRY}/matchmaking
- ${_REGISTRY}/item
- ${_REGISTRY}/tradepost
substitutions:
_PROFILE_IMAGE: ${_REGISTRY}/profile:${BUILD_ID}
_MATCHMAKING_IMAGE: ${_REGISTRY}/matchmaking:${BUILD_ID}
_ITEM_IMAGE: ${_REGISTRY}/item:${BUILD_ID}
_TRADEPOST_IMAGE: ${_REGISTRY}/tradepost:${BUILD_ID}
_REGISTRY: us-docker.pkg.dev/${PROJECT_ID}/spanner-game-images
_REL_NAME: rel-${BUILD_ID:0:8}
options:
dynamic_substitutions: true
machineType: E2_HIGHCPU_8
logging: CLOUD_LOGGING_ONLY
- Cloud Build 指令會讀取這個檔案,並按照畫面上列出的步驟操作。首先建構服務映像檔然後執行
gcloud deploy create
指令。這會讀取$DEMO_HOME/backend_services/skaffold.yaml
檔案,該檔案定義了每個部署檔案的所在位置:
apiVersion: skaffold/v2beta29
kind: Config
deploy:
kubectl:
manifests:
- spanner_config.yaml
- profile/deployment.yaml
- matchmaking/deployment.yaml
- item/deployment.yaml
- tradepost/deployment.yaml
- Cloud Deploy 會遵循每項服務
deployment.yaml
檔案的定義。服務的部署檔案包含建立服務的相關資訊,在本例中為在通訊埠 80 上執行的 clusterIP。
"ClusterIP" 類型可避免後端服務 Pod 擁有外部 IP,因此只有可以連線至內部 GKE 網路的實體才能存取後端服務。因此,玩家不應直接存取這些服務,因為這些服務會存取及修改 Spanner 資料。
apiVersion: v1
kind: Service
metadata:
name: profile
spec:
type: ClusterIP
selector:
app: profile
ports:
- port: 80
targetPort: 80
除了建立 Kubernetes 服務外,Cloud Deploy 也會建立 Kubernetes Deployment。一起來看看 profile
服務的部署部分:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: profile
spec:
replicas: 2 # EDIT: Number of instances of deployment
selector:
matchLabels:
app: profile
template:
metadata:
labels:
app: profile
spec:
serviceAccountName: profile-app
containers:
- name: profile-service
image: profile
ports:
- containerPort: 80
envFrom:
- configMapRef:
name: spanner-config
env:
- name: SERVICE_HOST
value: "0.0.0.0"
- name: SERVICE_PORT
value: "80"
resources:
requests:
cpu: "1"
memory: "1Gi"
ephemeral-storage: "100Mi"
limits:
cpu: "1"
memory: "1Gi"
ephemeral-storage: "100Mi"
頂部提供了一些服務的相關中繼資料,最重要的是,定義這個部署作業將建立多少備用資源。
replicas: 2 # EDIT: Number of instances of deployment
接著,我們會看到應執行應用程式的服務帳戶,以及應使用哪一個映像檔。這些執行個體與透過 Terraform 建立的 Kubernetes 服務帳戶和 Cloud Build 步驟中建立的映像檔相符。
spec:
serviceAccountName: profile-app
containers:
- name: profile-service
image: profile
之後,我們會指定網路與環境變數的一些資訊。
spanner_config
是 Kubernetes ConfigMap,指定應用程式連線至 Spanner 所需的專案、執行個體和資料庫資訊。
apiVersion: v1
kind: ConfigMap
metadata:
name: spanner-config
data:
SPANNER_PROJECT_ID: ${project_id}
SPANNER_INSTANCE_ID: ${instance_id}
SPANNER_DATABASE_ID: ${database_id}
ports:
- containerPort: 80
envFrom:
- configMapRef:
name: spanner-config
env:
- name: SERVICE_HOST
value: "0.0.0.0"
- name: SERVICE_PORT
value: "80"
SERVICE_HOST
和 SERVICE_PORT
是服務取得繫結位置所需的其他環境變數。
最後一個部分會向 GKE 說明這個部署作業中各項備用資源允許多少資源。GKE Autopilot 也會使用這個指標視需要調度叢集資源。
resources:
requests:
cpu: "1"
memory: "1Gi"
ephemeral-storage: "100Mi"
limits:
cpu: "1"
memory: "1Gi"
ephemeral-storage: "100Mi"
掌握以上資訊後,即可部署後端服務。
部署後端服務
如上所述,部署後端服務會使用 Cloud Build。和遷移結構定義一樣,您可以使用 gcloud 指令列提交建構要求:
cd $DEMO_HOME/backend_services gcloud builds submit --config=cloudbuild.yaml
指令輸出
Creating temporary tarball archive of 66 file(s) totalling 864.6 KiB before compression.
Uploading tarball of [.] to [gs://(project)_cloudbuild/source/(snip).tgz]
Created [https://cloudbuild.googleapis.com/v1/projects/(project)/locations/global/builds/30207dd1-(snip)].
Logs are available at [ https://console.cloud.google.com/cloud-build/builds/30207dd1-(snip)?project=(snip) ].
gcloud builds submit only displays logs from Cloud Storage. To view logs from Cloud Logging, run:
gcloud beta builds submit
ID: 30207dd1-(snip)
CREATE_TIME: (created time)
DURATION: 3M17S
SOURCE: gs://(project)_cloudbuild/source/(snip).tgz
IMAGES: us-docker.pkg.dev/(project)/spanner-game-images/profile:30207dd1-(snip) (+3 more)
STATUS: SUCCESS
與 schema migration
步驟的輸出內容不同,此建構作業的輸出內容會指出已建立一些圖片。這些內容會儲存在 Artifact Registry 存放區中。
gcloud build
步驟的輸出內容會包含 Cloud 控制台連結。快來看看這些指標。
收到 Cloud Build 的成功通知後,依序前往 Cloud Deploy,然後前往 sample-game-services
管道,即可監控部署作業的進度。
部署服務後,您可以透過 kubectl
查看 Pod 的狀態:
kubectl get pods
指令輸出
NAME READY STATUS RESTARTS AGE
item-6b9d5f678c-4tbk2 1/1 Running 0 83m
matchmaking-5bcf799b76-lg8zf 1/1 Running 0 80m
profile-565bbf4c65-kphdl 1/1 Running 0 83m
profile-565bbf4c65-xw74j 1/1 Running 0 83m
tradepost-68b87ccd44-gw55r 1/1 Running 0 79m
接著,查看服務以瞭解 ClusterIP
的實際運作情形:
kubectl get services
指令輸出
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
item ClusterIP 10.172.XXX.XXX <none> 80/TCP 84m
kubernetes ClusterIP 10.172.XXX.XXX <none> 443/TCP 137m
matchmaking ClusterIP 10.172.XXX.XXX <none> 80/TCP 84m
profile ClusterIP 10.172.XXX.XXX <none> 80/TCP 84m
tradepost ClusterIP 10.172.XXX.XXX <none> 80/TCP 84m
您也可以前往 Cloud 控制台中的 GKE UI,查看 Workloads
、Services
和 ConfigMaps
。
工作負載
服務
ConfigMap
摘要
在這個步驟中,您已將四項後端服務部署至 GKE Autopilot。您已成功執行 Cloud Build 步驟,並在 Cloud 控制台中檢查 Cloud Deploy 和 Kubernetes 的進度。
您也瞭解這些服務如何利用 Workload Identity 來模擬具有適當權限的服務帳戶,以便讀取 Spanner 資料庫中的資料,以及將資料寫入 Spanner。
後續步驟
在下一節中,您將部署工作負載。
6. 部署工作負載
總覽
現在後端服務在叢集內運作,接下來請部署工作負載。
這些工作負載可從外部存取,每個後端服務都有各自的工作負載,可用於本程式碼研究室。
這些工作負載是以 Locust 為基礎的負載產生指令碼,模擬了這些範例服務預期的實際存取模式。
以下是 Cloud Build 程序的檔案:
$DEMO_HOME/workloads/cloudbuild.yaml
(由 Terraform 產生)$DEMO_HOME/workloads/skaffold.yaml
- 每項工作負載都有一個
deployment.yaml
檔案
工作負載 deployment.yaml
檔案與後端服務部署檔案看起來略有不同。
以下是 matchmaking-workload
的範例:
apiVersion: v1
kind: Service
metadata:
name: matchmaking-workload
spec:
type: LoadBalancer
selector:
app: matchmaking-workload
ports:
- port: 8089
targetPort: 8089
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: matchmaking-workload
spec:
replicas: 1 # EDIT: Number of instances of deployment
selector:
matchLabels:
app: matchmaking-workload
template:
metadata:
labels:
app: matchmaking-workload
spec:
serviceAccountName: default
containers:
- name: matchmaking-workload
image: matchmaking-workload
ports:
- containerPort: 8089
resources:
requests:
cpu: "500m"
memory: "512Mi"
ephemeral-storage: "100Mi"
limits:
cpu: "500m"
memory: "512Mi"
ephemeral-storage: "100Mi"
檔案的最上層會定義服務。在此情況下,系統會建立 LoadBalancer
,而工作負載會在通訊埠 8089
上執行。
LoadBalancer 會提供外部 IP,可用來連線至工作負載。
apiVersion: v1
kind: Service
metadata:
name: matchmaking-workload
spec:
type: LoadBalancer
selector:
app: matchmaking-workload
ports:
- port: 8089
targetPort: 8089
「Deployment」(部署) 區段的頂端是工作負載的相關中繼資料。本例中只會部署一個備用資源:
replicas: 1
但容器規格不同。舉例來說,我們要使用 default
Kubernetes 服務帳戶,這個帳戶沒有任何特殊權限,因為工作負載不需要連線至任何 Google Cloud 資源 (在 GKE 叢集中執行的後端服務除外)。
另一個差別在於這些工作負載不需要任何環境變數。這會產生較短的部署作業規格。
spec:
serviceAccountName: default
containers:
- name: matchmaking-workload
image: matchmaking-workload
ports:
- containerPort: 8089
資源設定與後端服務類似。提醒您,GKE Autopilot 會知道需要多少資源,才能滿足叢集中所有 Pod 的要求。
請開始部署工作負載!
部署工作負載
和先前一樣,您可以使用 gcloud 指令列提交建構要求:
cd $DEMO_HOME/workloads gcloud builds submit --config=cloudbuild.yaml
指令輸出
Creating temporary tarball archive of 18 file(s) totalling 26.2 KiB before compression.
Some files were not included in the source upload.
Check the gcloud log [/tmp/tmp.4Z9EqdPo6d/logs/(snip).log] to see which files and the contents of the
default gcloudignore file used (see `$ gcloud topic gcloudignore` to learn
more).
Uploading tarball of [.] to [gs://(project)_cloudbuild/source/(snip).tgz]
Created [https://cloudbuild.googleapis.com/v1/projects/(project)/locations/global/builds/(snip)].
Logs are available at [ https://console.cloud.google.com/cloud-build/builds/0daf20f6-(snip)?project=(snip) ].
gcloud builds submit only displays logs from Cloud Storage. To view logs from Cloud Logging, run:
gcloud beta builds submit
ID: 0daf20f6-(snip)
CREATE_TIME: (created_time)
DURATION: 1M41S
SOURCE: gs://(project)_cloudbuild/source/(snip).tgz
IMAGES: us-docker.pkg.dev/(project)/spanner-game-images/profile-workload:0daf20f6-(snip) (+4 more)
STATUS: SUCCESS
請務必檢查 Cloud 控制台中的 Cloud Build 記錄檔和 Cloud Deploy 管道,確認狀態。針對工作負載,Cloud Deploy 管道為 sample-game-workloads
:
部署完成後,請在 Cloud Shell 中透過 kubectl
檢查狀態:
kubectl get pods
指令輸出
NAME READY STATUS RESTARTS AGE
game-workload-7ff44cb657-pxxq2 1/1 Running 0 12m
item-6b9d5f678c-cr29w 1/1 Running 0 9m6s
item-generator-7bb4f57cf8-5r85b 1/1 Running 0 12m
matchmaking-5bcf799b76-lg8zf 1/1 Running 0 117m
matchmaking-workload-76df69dbdf-jds9z 1/1 Running 0 12m
profile-565bbf4c65-kphdl 1/1 Running 0 121m
profile-565bbf4c65-xw74j 1/1 Running 0 121m
profile-workload-76d6db675b-kzwng 1/1 Running 0 12m
tradepost-68b87ccd44-gw55r 1/1 Running 0 116m
tradepost-workload-56c55445b5-b5822 1/1 Running 0 12m
接著,請檢查工作負載服務,瞭解 LoadBalancer
的實際運作情形:
kubectl get services
指令輸出
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
game-workload LoadBalancer *snip* 35.XX.XX.XX 8089:32483/TCP 12m
item ClusterIP *snip* <none> 80/TCP 121m
item-generator LoadBalancer *snip* 34.XX.XX.XX 8089:32581/TCP 12m
kubernetes ClusterIP *snip* <none> 443/TCP 174m
matchmaking ClusterIP *snip* <none> 80/TCP 121m
matchmaking-workload LoadBalancer *snip* 34.XX.XX.XX 8089:31735/TCP 12m
profile ClusterIP *snip* <none> 80/TCP 121m
profile-workload LoadBalancer *snip* 34.XX.XX.XX 8089:32532/TCP 12m
tradepost ClusterIP *snip* <none> 80/TCP 121m
tradepost-workload LoadBalancer *snip* 34.XX.XX.XX 8089:30002/TCP 12m
摘要
現在已將工作負載部署至 GKE 叢集。這些工作負載不需要額外的 IAM 權限,且可透過 LoadBalancer 服務從通訊埠 8089 外部存取。
後續步驟
只要是正在執行後端服務和工作負載,就可以玩遊戲!
7. 開始玩遊戲
總覽
「遊戲」範例的後端服務而且還能產生「播放器」透過工作負載與這些服務互動
每個工作負載都會使用 Locust 來模擬服務 API 的實際負載。在這個步驟中,您將執行數項工作負載,在 GKE 叢集和 Spanner 上產生負載,並將資料儲存在 Spanner 中。
以下是各個工作負載的說明:
item-generator
工作負載是快速的工作負載,會產生 game_items 清單。玩家可以透過「玩遊戲」的過程中取得該清單遊戲。profile-workload
會模擬玩家註冊和登入的情況。matchmaking-workload
會模擬排入佇列至遊戲的玩家。game-workload
會在遊戲過程中模擬玩家已取得 game_items 和金錢。tradepost-workload
會模擬玩家在交易郵局上銷售及購買商品的玩家。
本程式碼研究室會特別執行 item-generator
和 profile-workload
。
執行項目產生器
item-generator
會使用 item
後端服務端點,將 game_items
新增至 Spanner。您必須完成這些項目,game-workload
和 tradepost-workload
才能正常運作。
第一步是取得 item-generator
服務的外部 IP。在 Cloud Shell 中執行下列指令:
# The external IP is the 4th column of the output
kubectl get services | grep item-generator | awk '{print $4}'
指令輸出
{ITEMGENERATOR_EXTERNAL_IP}
接著開啟新的瀏覽器分頁,並指向 http://{ITEMGENERATOR_EXTERNAL_IP}:8089
。您應該會找到類似下方的頁面:
您將讓 users
和 spawn
保留預設值 1。在 host
, 欄位中輸入 http://item
。按一下進階選項,然後輸入執行時間:10s
。
設定應如下所示:
按一下「開始群戰」!
針對在 POST /items
端點發出的要求,系統會開始顯示統計資料。10 秒後將停止載入。
按一下 Charts
,即可查看這些要求的成效圖表。
現在,您要檢查資料是否已輸入 Spanner 資料庫。
方法很簡單,只要按一下漢堡選單,然後瀏覽至「Spanner」即可。在這個頁面上,前往 sample-instance
和 sample-database
。然後按一下「Query
」。
我們要選取 game_items
的數量:
SELECT COUNT(*) FROM game_items;
結果底部會顯示結果。
我們不需要大量的game_items
種子。但現在玩家可以獲得這些獎勵了!
執行設定檔工作負載
完成 game_items
種子後,下一步是將玩家註冊加入遊戲行列。
profile-workload
會使用 Locust 模擬玩家建立帳戶、登入、擷取設定檔資訊及登出的動作。在類似實際工作環境的一般工作負載中,所有這些測試都會測試 profile
後端服務的端點。
如要執行這個指令,請取得 profile-workload
外部 IP:
# The external IP is the 4th column of the output
kubectl get services | grep profile-workload | awk '{print $4}'
指令輸出
{PROFILEWORKLOAD_EXTERNAL_IP}
接著開啟新的瀏覽器分頁,並指向 http://{PROFILEWORKLOAD_EXTERNAL_IP}:8089
。您應該會找到與前一頁相似的 Locust 頁面。
在這種情況下,您將使用 http://profile
做為主機。您也不會在進階選項中指定執行階段。此外,請將 users
指定為 4,這樣就能一次模擬 4 個使用者要求。
profile-workload
測試應如下所示:
按一下「開始群戰」!
和之前一樣,畫面會顯示多個 profile
REST 端點的統計資料。按一下滑鼠,即可檢視圖表來掌握整體成效。
摘要
在這個步驟中,您已產生一些 game_items
,接著使用 Cloud 控制台中的 Spanner Query UI 查詢 game_items
資料表。
此外,您也讓玩家註冊您的遊戲,並瞭解 Locust 如何針對後端服務建立類似實際工作環境的工作負載。
後續步驟
執行工作負載後,您可能會想確認 GKE 叢集和 Spanner 執行個體的運作情形。
8. 查看 GKE 和 Spanner 的用量
設定檔服務執行期間,您將有機會瞭解 GKE Autopilot 叢集和 Cloud Spanner 的運作情形。
檢查 GKE 叢集
前往 Kubernetes 叢集。請注意,您已部署工作負載和服務,因此叢集現在多了關於 vCPU 和記憶體總數的詳細資料。如果叢集中沒有任何工作負載,就無法取得這項資訊。
接著,點選進入 sample-game-gke
叢集,並切換至「觀測能力」分頁:
我們的工作負載和後端服務是在 default
上執行,因此 default
Kubernetes 命名空間應已超出 CPU 使用率的 kube-system
命名空間。如果未顯示,請確認 profile workload
仍在執行,然後等待幾分鐘,讓圖表更新。
如要查看哪些工作負載佔用最多資源,請前往 Workloads
資訊主頁。
直接前往資訊主頁的「觀測能力」分頁,而非個別查看各項工作負載。您應該會看到 profile
和 profile-workload
CPU 已增加。
接著來看看 Cloud Spanner
查看 Cloud Spanner 執行個體
如要查看 Cloud Spanner 的效能,請前往 Spanner 並點選進入 sample-instance
執行個體和 sample-game
資料庫。
登入後,左選單會顯示「System Insights」分頁:
這裡有許多圖表可協助您瞭解 Spanner 執行個體的一般效能,包括 CPU utilization
、transaction latency and locking
和 query throughput
。
除了系統深入分析外,您也可以瀏覽「觀測能力」部分中的其他連結,取得查詢工作負載的詳細資訊:
- 查詢深入分析結果有助於找出使用 Spanner 資源中的前 N 項查詢。
- 交易與鎖定深入分析有助於找出高延遲的交易。
- Key Visualizer 能以視覺化方式呈現存取模式,有助於追蹤資料中的熱點。
摘要
在這個步驟中,您學到瞭如何檢查 GKE Autopilot 和 Spanner 的一些基本成效指標。
舉例來說,在執行設定檔工作負載時,請查詢 players 資料表,取得更多有關該資料表儲存資料的資訊。
後續步驟
接著就可以開始清理儲存空間了!
9. 清除所用資源
在清理之前,您可以探索未涵蓋的其他工作負載。特別是 matchmaking-workload
、 game-workload
和 tradepost-workload
。
當你結束播放時就能清理遊樂場幸好這很簡單。
首先,如果您的 profile-workload
仍在瀏覽器中執行,請重新進行操作並停止執行:
針對您可能測試的每個工作負載執行同樣的步驟。
接著在 Cloud Shell 中前往「基礎架構」資料夾您將使用 terraform 來destroy
基礎架構:
cd $DEMO_HOME/infrastructure
terraform destroy
# type 'yes' when asked
指令輸出
Plan: 0 to add, 0 to change, 46 to destroy.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
*snip*
Destroy complete! Resources: 46 destroyed.
在 Cloud 控制台中前往 Spanner
、Kubernetes Cluster
、Artifact Registry
、Cloud Deploy
和 IAM
,確認所有資源已移除。
10. 恭喜!
恭喜!您已成功在 GKE Autopilot 上部署範例 golang 應用程式,並透過 Workload Identity 將這類應用程式連線至 Cloud Spanner!
還有一項好處,那就是您可以使用 Terraform 以重複方式輕鬆設定及移除這個基礎架構。
您可以進一步瞭解自己在本程式碼研究室中互動過的 Google Cloud 服務:
後續步驟
現在,您已大致瞭解 GKE Autopilot 和 Cloud Spanner 搭配運作的方式,不妨接著採取行動,開始建構能與這些服務搭配使用的應用程式。