本教程介绍如何将容器化 Web 应用部署到 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 数据库。
使用图形界面部署名为
hello-app-cloud-spanner的示例 Web 应用。
下表展示了您需要在本教程中创建或使用的 Google Cloud 资源,以及用来标识这些资源的变量和为这些变量指定的值:
| 资源 | 变量 | 值 |
|---|---|---|
| Google Cloud 项目 ID | PROJECT_ID
|
创建项目时生成的项目 ID。
示例: |
| 计算区域 | COMPUTE_REGION |
要在其中创建 Spanner 实例和 GKE 集群的 Compute Engine 区域。建议选择最靠近您客户地理位置的区域,不过在本教程中,我们会使用 |
| Spanner 实例 | - | hello-instance |
| Spanner 数据库 | - | hello-database |
| GKE Autopilot 集群 | CLUSTER_NAME |
hello-cluster |
| Kubernetes 命名空间 | NAMESPACE |
hello-namespace |
| Kubernetes 服务账号 | KSA_NAME |
ksa-helloapp |
| IAM 服务账号 | GSA_NAME |
gsa-helloapp |
| IAM 服务账号的项目 ID | GSA_PROJECT |
您的 Google Cloud PROJECT_ID。 |
在本教程中,建议您创建新资源,以便在部署示例应用后轻松安全地删除这些资源。不过,如果您有任何现有命名空间、IAM 服务账号和 Kubernetes 服务账号,也可以使用它们。
费用
在本文档中,您将使用 Google Cloud的以下收费组件:
- Compute Engine instances used by GKE
- Spanner
- Cloud Load Balancing
如需根据您的预计使用情况来估算费用,请使用价格计算器。
完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理。
准备工作
请务必满足以下前提条件:
选择或创建项目
您可以使用现有项目,也可以为本教程创建一个新项目。
- 登录您的 Google Cloud 账号。如果您是 Google Cloud新手,请 创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
启用 API
启用 Artifact Registry API、Compute Engine API、GKE API 和 IAM Service Account Credentials API。
启用 API 所需的角色
如需启用 API,您需要拥有 Service Usage Admin IAM 角色 (roles/serviceusage.serviceUsageAdmin),该角色包含 serviceusage.services.enable 权限。了解如何授予角色。
设置 Cloud Shell
在本教程中,您将使用 Cloud Shell 运行 gcloud 和 kubectl 命令。Cloud Shell 是一种 shell 环境,用于管理在 Google Cloud上托管的资源。它预安装有 Google Cloud CLI 和 kubectl 命令行工具。
在 Google Cloud 控制台中,激活 Cloud Shell。
控制台下方的框架内会打开一个 Cloud Shell 会话。
在运行本教程中的命令之前,请确保将默认项目设置为您要在其中部署示例应用的项目 ID。如果尚未进行此项设置,请在 Cloud Shell 中运行以下命令:
gcloud config set project PROJECT_ID
将 PROJECT_ID 替换为您的项目 ID。
授予 IAM 角色
确保您的 Google Cloud 账号具有本教程所需的 IAM 角色。
向您的用户账号授予角色。对以下每个 IAM 角色运行以下命令一次:
roles/iam.serviceAccountAdmin, roles/serviceusage.serviceUsageConsumer, roles/iam.serviceAccountUser, roles/iam.securityAdmin, roles/spanner.admin, roles/container.admin
gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE
替换以下内容:
PROJECT_ID:您的项目 ID。USER_IDENTIFIER:您的用户 账号的标识符。例如,myemail@example.com。ROLE:您授予用户账号的 IAM 角色。
配置 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 集群并使用适用于 GKE 的工作负载身份联合以安全且易于管理的方式访问您的数据库。
创建一个名为 hello-cluster 的 Autopilot 集群。默认情况下,Autopilot 集群会启用适用于 GKE 的工作负载身份联合。
gcloud container clusters create-auto CLUSTER_NAME \
--location=CONTROL_PLANE_LOCATION
替换以下内容:
CLUSTER_NAME:hello-clusterCONTROL_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 的工作负载身份联合
在部署应用之前,配置您的集群以使用 Workload Identity Federation for GKE 向 Google Cloud 进行身份验证。
获取凭据以访问集群:
gcloud container clusters get-credentials CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION请替换以下内容:
CLUSTER_NAME:hello-clusterCONTROL_PLANE_LOCATION:us-west1
这会使用相应的凭据和端点信息更新
kubeconfig文件,以将kubectl指向您的集群。创建用于 Kubernetes 服务账号的命名空间。您还可以使用默认命名空间或任何现有命名空间。
kubectl create namespace NAMESPACE将
NAMESPACE替换为您要创建的新命名空间的名称,即hello-namespace。为您的应用创建 Kubernetes 服务账号:
kubectl create serviceaccount KSA_NAME \ --namespace NAMESPACE请替换以下内容:
KSA_NAME:ksa-helloapp,即您要创建的新 Kubernetes 服务账号的名称。NAMESPACE:hello-namespace
为您的应用创建 IAM 服务账号:
gcloud iam service-accounts create GSA_NAME \ --project=GSA_PROJECT请替换以下内容:
GSA_NAME:gsa-helloapp,即您要创建的新 IAM 服务账号的名称。GSA_PROJECT:您的 Google Cloud项目 ID。在本教程中,您将在要部署示例应用的 Google Cloud 项目中创建 IAM 服务账号。因此,您的GSA_PROJECT和Google CloudPROJECT_ID是相同的。
为您的 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 项目 IDGSA_NAME:gsa-helloapp
示例:
gcloud projects add-iam-policy-binding my-gcp-project \ --member "serviceAccount:gsa-helloapp@my-gcp-project.iam.gserviceaccount.com" \ --role "roles/spanner.admin"
通过在两个服务账号之间添加 IAM 政策绑定,允许 Kubernetes 服务账号模拟 IAM 服务账号。此绑定允许 Kubernertes 服务账号充当 IAM 服务账号,以便 Kubernetes 服务账号可以对 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_NAME:gsa-helloappGSA_PROJECT:您的 Google Cloud 项目 IDPROJECT_ID:您的 Google Cloud 项目 IDNAMESPACE:hello-namespaceKSA_NAME:ksa-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]"
使用 IAM 服务账号的电子邮件地址为 Kubernetes 服务账号添加注解。这样,您的示例应用便知道要用于访问 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_NAME:ksa-helloappNAMESPACE:hello-namespaceGSA_NAME:gsa-helloappGSA_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。
将示例应用从 GitHub 代码库克隆到 Cloud Shell:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git通过点击终端窗口工具栏上的
打开编辑器,启动 Cloud Shell Editor。如需了解详情,请参阅 Cloud Shell Editor 界面概览。
打开 Cloud Shell Editor 的探索器窗格,然后浏览到
kubernetes-engine-samples/databases/hello-app-cloud-spanner/k8s目录。打开
deployment.yaml文件,将<KSA_NAME>替换为 Kubernetes 服务账号的名称ksa-helloapp,以更新serviceAccountName字段。
图 1:在部署文件中更新 Kubernetes 服务账号名称。 关闭 Cloud Shell Editor,然后返回到 Cloud Shell 终端。
在 Cloud Shell 终端中,导航到
hello-app-cloud-spanner目录:cd kubernetes-engine-samples/databases/hello-app-cloud-spanner部署应用:
kubectl apply -f k8s/deployment.yaml -n=NAMESPACE将
NAMESPACE替换为hello-namespace。等待应用部署完毕,即
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按键盘上的 Ctrl+C 返回命令提示符,以便运行更多命令。
将示例应用公开发布到互联网
如需在集群外部公开 Kubernetes Service,请创建 LoadBalancer 类型的 Service。此类型的 Service 会为可通过互联网访问的 Pod 生成外部负载均衡器 IP 地址。
部署负载均衡器:
kubectl apply -f k8s/service.yaml -n=NAMESPACE将
NAMESPACE替换为hello-namespace。监视要分配的外部 IP 地址:
kubectl get service -n=NAMESPACE --watch将
NAMESPACE替换为hello-namespace。分配完成后,复制
EXTERNAL-IP(例如203.0.113.0)并在浏览器中将其打开。此时会打开一个网页界面,可在该界面显示和管理玩家数据库。您可以使用应用 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
清理
为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。
删除项目
为了避免产生费用,最简单的方法是删除您为本教程创建的项目。
删除 Google Cloud 项目:
gcloud projects delete PROJECT_ID
如果您删除了项目,则表示您的清理已完成。如果您没有删除项目,您可以继续删除 GKE 和 Spanner 资源。
删除 GKE 资源
删除服务。此操作将取消分配您为 Service 创建的 Google Cloud 负载均衡器:
kubectl delete service hello-app-cloud-spanner -n=NAMESPACE将
NAMESPACE替换为hello-namespace。删除 GKE 集群。 此命令将删除构成集群的各项资源,如计算实例、磁盘和网络资源:
gcloud container clusters delete CLUSTER_NAME --location=CONTROL_PLANE_LOCATION
删除 Spanner 资源
删除 Spanner 数据库:
gcloud spanner databases delete hello-database --instance=hello-instance删除 Spanner 实例:
gcloud spanner instances delete hello-instance