使用 GKE Autopilot 和 Spanner 部署應用程式

本教學課程說明如何將容器化網頁應用程式部署至 Google Kubernetes Engine (GKE) Autopilot 叢集,並在後端使用 Google Spanner 資料庫儲存資料。這個範例應用程式會管理遊戲玩家表格。你可以透過應用程式的圖形使用者介面 (GUI) 新增及刪除播放器。

Spanner 是全代管的關聯式資料庫服務,可水平擴充、遍及全球,提供 ACID 交易和 SQL 語意,同時兼顧效能和高可用性。

閱讀本頁面之前,請先熟悉 Kubernetes

為何選擇 GKE 和 Spanner

開發人員可能不想花時間瞭解應用程式所需的儲存空間和運算資源量,也不想預測需求波動期間的 RAM 和 CPU 消耗量,或擔心應用程式在尖峰負載時發生故障。

使用 GKE Autopilot 做為全代管 Kubernetes 服務,並使用 Spanner 做為全代管資料庫服務,您就能在穩定的基礎架構上更快開發及部署應用程式,簡化資源設定和管理作業。GKE Autopilot 會根據執行階段的需求,在叢集中新增或移除節點,藉此設定及調度資源,以代管應用程式。同樣地,Spanner 也能在儲存空間或運算需求變更時,動態擴充及縮減資源,且幾乎不需要手動介入。

舉例來說,假設您即將推出下一款熱門遊戲,預期會爆紅,因此在推出當週會吸引大量網路流量。Spanner 可讓您立即增加、減少或重新分配運算資源,同時透過 GKE Autopilot 維持應用程式的最高可用性,因應這類暴增的輸送量。

設定 Spanner

如要設定 Spanner,您需要建立 Spanner 執行個體和 Spanner 資料庫。

可建立 Spanner 執行個體

Spanner 執行個體是一種資源分配單位,在執行個體內建立的 Spanner 資料庫會使用個體內的資源。

建立名為 hello-instance 的 Spanner 執行個體,並採用區域設定和 100 個處理單元的運算容量。

gcloud spanner instances create hello-instance \
    --config=regional-COMPUTE_REGION \
    --description="Spanner sample instance" \
    --processing-units=100

在本教學課程中,請將 COMPUTE_REGION 替換為 us-west1

可建立 Spanner 資料庫

Spanner 資料庫包含資料表、檢視區塊和索引。資料庫會從父項執行個體繼承屬性,例如設定 (單一地區或多地區)、可用運算容量和儲存空間。

使用 GoogleSQL 方言建立名為 hello-database 的 Spanner 資料庫,其中有個名為 Players 的資料表。在 Cloud Shell 中執行下列查詢:

gcloud spanner databases create hello-database \
    --instance=hello-instance \
    --database-dialect=GOOGLE_STANDARD_SQL \
    --ddl="CREATE TABLE Players (
        PlayerUuid STRING(36) NOT NULL,
        FirstName STRING(1024),
        LastName STRING(1024),
        BirthDate DATE) PRIMARY KEY(PlayerUuid)"

建立 GKE Autopilot 叢集

設定 Spanner 後,請建立 Autopilot 叢集,並使用 Workload Identity Federation for GKE,以安全且易於管理的方式存取資料庫。

建立名為 hello-cluster 的 Autopilot 叢集。Autopilot 叢集預設會啟用 Workload Identity Federation for GKE。

gcloud container clusters create-auto CLUSTER_NAME \
  --location=CONTROL_PLANE_LOCATION

更改下列內容:

  • CLUSTER_NAMEhello-cluster
  • CONTROL_PLANE_LOCATION:叢集控制層的 Compute Engine區域。在本教學課程中,請使用您建立 Spanner 執行個體的相同區域 us-west1。建議您在同一區域內建立 Spanner 執行個體和 GKE Autopilot 叢集,以縮短延遲時間。

建立叢集最多可能需要 8 到 10 分鐘。

輸出結果會與下列內容相似:

NAME: hello-cluster
LOCATION: us-west1
MASTER_VERSION: 1.26.5-gke.1200
MASTER_IP: 192.0.2.1
MACHINE_TYPE: e2-medium
NODE_VERSION: 1.26.5-gke.1200
NUM_NODES: 3
STATUS: RUNNING

設定叢集以使用 GKE 適用的工作負載身分聯盟

部署應用程式前,請先設定叢集,透過 GKE 適用的工作負載身分聯盟向 Google Cloud 進行驗證。

  1. 取得憑證,存取叢集:

    gcloud container clusters get-credentials CLUSTER_NAME \
      --location=CONTROL_PLANE_LOCATION
    

    更改下列內容:

    • CLUSTER_NAMEhello-cluster
    • CONTROL_PLANE_LOCATIONus-west1

    這會更新 kubeconfig 檔案,加入適當的憑證和端點資訊,將 kubectl 指向叢集。

  2. 建立要用於 Kubernetes 服務帳戶的命名空間。您也可以使用預設命名空間或任何現有命名空間。

    kubectl create namespace NAMESPACE
    

    NAMESPACE 替換為 hello-namespace,也就是您要建立的新命名空間名稱。

  3. 為應用程式建立要使用的 Kubernetes 服務帳戶:

    kubectl create serviceaccount KSA_NAME \
      --namespace NAMESPACE
    

    更改下列內容:

    • KSA_NAMEksa-helloapp,您要建立的新 Kubernetes 服務帳戶名稱。
    • NAMESPACEhello-namespace
  4. 為應用程式建立 IAM 服務帳戶:

    gcloud iam service-accounts create GSA_NAME \
      --project=GSA_PROJECT
    

    更改下列內容:

    • GSA_NAMEgsa-helloapp,您要建立的新 IAM 服務帳戶名稱。
    • GSA_PROJECT:您的 Google Cloud專案 ID。在本教學課程中,您會在部署範例應用程式的 Google Cloud 專案中建立 IAM 服務帳戶。因此,GSA_PROJECT 和Google Cloud PROJECT_ID 相同。
  5. 為 IAM 服務帳戶新增 IAM 政策繫結,以便讀取及寫入 Spanner:

    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member "serviceAccount:GSA_NAME@PROJECT_ID.iam.gserviceaccount.com" \
      --role "roles/spanner.admin"
    

    更改下列內容:

    • PROJECT_ID:您的 Google Cloud 專案 ID
    • GSA_NAMEgsa-helloapp

    範例:

    gcloud projects add-iam-policy-binding my-gcp-project \
      --member "serviceAccount:gsa-helloapp@my-gcp-project.iam.gserviceaccount.com" \
      --role "roles/spanner.admin"
  6. 在兩個服務帳戶之間新增 IAM 政策繫結,允許 Kubernetes 服務帳戶模擬 IAM 服務帳戶。這個繫結可讓 Kubernetes 服務帳戶做為 IAM 服務帳戶,以便讀取及寫入 Spanner。

    gcloud iam service-accounts add-iam-policy-binding GSA_NAME@GSA_PROJECT.iam.gserviceaccount.com \
      --role roles/iam.workloadIdentityUser \
      --member "serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME]"
    

    更改下列內容:

    • GSA_NAMEgsa-helloapp
    • GSA_PROJECT:您的 Google Cloud 專案 ID
    • PROJECT_ID:您的 Google Cloud 專案 ID
    • NAMESPACEhello-namespace
    • KSA_NAMEksa-helloapp

    範例:

    gcloud iam service-accounts add-iam-policy-binding gsa-helloapp@my-gcp-project.iam.gserviceaccount.com \
      --role roles/iam.workloadIdentityUser \
      --member "serviceAccount:my-gcp-project.svc.id.goog[hello-namespace/ksa-helloapp]"
  7. 註解 Kubernetes 服務帳戶,並提供 IAM 服務帳戶的電子郵件地址。這樣範例應用程式就能知道要使用哪個服務帳戶存取服務 Google Cloud 。因此,當應用程式使用任何標準 Google API 用戶端程式庫存取 Google Cloud 服務時,會使用該 IAM 服務帳戶。

    kubectl annotate serviceaccount KSA_NAME \
      --namespace NAMESPACE \
      iam.gke.io/gcp-service-account=GSA_NAME@GSA_PROJECT.iam.gserviceaccount.com
    

    更改下列內容:

    • KSA_NAMEksa-helloapp
    • NAMESPACEhello-namespace
    • GSA_NAMEgsa-helloapp
    • GSA_PROJECT:您的 Google Cloud 專案 ID

    範例:

    kubectl annotate serviceaccount ksa-helloapp \
      --namespace hello-namespace \
      iam.gke.io/gcp-service-account=gsa-helloapp@my-gcp-project.iam.gserviceaccount.com

將範例應用程式部署至叢集

您已透過必要的服務和驗證設定 GKE 和 Spanner,現在可以部署範例應用程式 hello-app-cloud-spanner

  1. 將範例應用程式從 GitHub 存放區複製到 Cloud Shell:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git
    
  2. 按一下終端機視窗工具列上的「開啟編輯器」程式碼編輯器按鈕,啟動 Cloud Shell 編輯器。

    詳情請參閱「Cloud Shell 編輯器介面總覽」。

  3. 開啟 Cloud Shell 編輯器的 Explorer 窗格,然後瀏覽至 kubernetes-engine-samples/databases/hello-app-cloud-spanner/k8s 目錄。

  4. 開啟 deployment.yaml 檔案,然後將 <KSA_NAME> 替換為 Kubernetes 服務帳戶名稱 ksa-helloapp,更新 serviceAccountName 欄位。

    編輯 YAML,更新 KSA_NAME。
    圖 1. 在部署檔案中更新 Kubernetes 服務帳戶名稱。
  5. 關閉 Cloud Shell 編輯器,然後返回 Cloud Shell 終端機。

  6. 在 Cloud Shell 終端機中,前往 hello-app-cloud-spanner 目錄:

    cd kubernetes-engine-samples/databases/hello-app-cloud-spanner
    
  7. 部署應用程式:

    kubectl apply -f k8s/deployment.yaml -n=NAMESPACE
    

    NAMESPACE 替換為 hello-namespace

  8. 等待應用程式以 STATUS 部署為 Running

    kubectl get pods -n=NAMESPACE --watch
    

    NAMESPACE 替換為 hello-namespace

    輸出結果會與下列內容相似:

    NAME                                       READY   STATUS              RESTARTS   AGE
    hello-app-cloud-spanner-765c9b8779-lfcrc   0/1     ContainerCreating   0          87s
    hello-app-cloud-spanner-765c9b8779-lfcrc   1/1     Running             0          3m15s
    
  9. 按下鍵盤上的 Ctrl+C 鍵,返回命令提示字元,執行其他指令。

將範例應用程式公開發布到網際網路

如要從叢集外部公開發布 Kubernetes Service,請建立類型為 LoadBalancer 的 Service。這種類型的 Service 會為 Pod 產生外部負載平衡器 IP 位址,可透過網際網路存取。

  1. 部署負載平衡器:

    kubectl apply -f k8s/service.yaml -n=NAMESPACE
    

    NAMESPACE 替換為 hello-namespace

  2. 等待系統指派外部 IP 位址:

    kubectl get service -n=NAMESPACE --watch
    

    NAMESPACE 替換為 hello-namespace

  3. 指派完成後,請複製 EXTERNAL-IP (例如 203.0.113.0) 並在瀏覽器中開啟。系統會開啟網頁介面,顯示及管理玩家資料庫。

  4. 您可以使用應用程式 GUI 建立或刪除玩家記錄,並儲存在 Spanner 資料庫中。

    新增或刪除球員。
    圖 2. 在登錄檔中建立或刪除播放器。

    執行下列查詢,確認 Spanner 資料庫是否已更新您的項目:

    gcloud spanner databases execute-sql hello-database \
      --instance=hello-instance \
      --sql="SELECT * FROM Players LIMIT 10"
    

    輸出結果會與下列內容相似:

    PlayerUuid: a1f34bbf-929c-498d-8b16-39bbb29d70e3
    FirstName: John
    LastName: Smith
    BirthDate: 1997-07-12
    
    PlayerUuid: d634e157-96ea-45f2-be3f-fb907ced188e
    FirstName: Jane
    LastName: Doe
    BirthDate: 2013-07-12