本教程介绍如何将容器化 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 的以下收费组件:
- GKE 使用的 Compute Engine 实例
- 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.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
启用 API
Enable the Artifact Registry, Compute Engine, GKE, and IAM Service Account Credentials APIs.
设置 Cloud Shell
在本教程中,您将使用 Cloud Shell 运行 gcloud
和 kubectl
命令。Cloud Shell 是一种 shell 环境,用于管理托管在 Google Cloud 上的资源。它预安装有 Google Cloud CLI 和 kubectl 命令行工具。
In the Google Cloud console, activate Cloud Shell.
控制台下方的框架内会打开一个 Cloud Shell 会话。
在运行本教程中的命令之前,请确保将默认项目设置为您要在其中部署示例应用的项目 ID。如果尚未进行此项设置,请在 Cloud Shell 中运行以下命令:
gcloud config set project PROJECT_ID
将 PROJECT_ID
替换为您的项目 ID。
授予 IAM 角色
确保您的 Google Cloud 账号具有本教程所需的 IAM 角色。
Grant roles to your user account. Run the following command once for each of the following
IAM roles:
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_IDENTIFIER" --role=ROLE
- Replace
PROJECT_ID
with your project ID. -
Replace
USER_IDENTIFIER
with the identifier for your user account. For example,user:myemail@example.com
. - Replace
ROLE
with each individual role.
配置 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 \
--region=COMPUTE_REGION
替换以下内容:
CLUSTER_NAME
:hello-cluster
COMPUTE_REGION
:集群的 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 进行身份验证。
获取凭据以访问集群:
gcloud container clusters get-credentials CLUSTER_NAME \ --region=COMPUTE_REGION
请替换以下内容:
CLUSTER_NAME
:hello-cluster
COMPUTE_REGION
: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-helloapp
GSA_PROJECT
:您的 Google Cloud 项目 IDPROJECT_ID
:您的 Google Cloud 项目 IDNAMESPACE
:hello-namespace
KSA_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-helloapp
NAMESPACE
:hello-namespace
GSA_NAME
:gsa-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
。
将示例应用从 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
字段。关闭 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 数据库中。
运行以下查询以验证 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 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。
删除项目
为了避免产生费用,最简单的方法是删除您为本教程创建的项目。
Delete a Google Cloud project:
gcloud projects delete PROJECT_ID
如果您删除了项目,则表示您的清理已完成。如果您没有删除项目,您可以继续删除 GKE 和 Spanner 资源。
删除 GKE 资源
删除 Service。此命令将取消分配您为 Service 创建的 Google Cloud 负载均衡器:
kubectl delete service hello-app-cloud-spanner -n=NAMESPACE
将
NAMESPACE
替换为hello-namespace
。删除 GKE 集群。 此命令将删除构成集群的各项资源,如计算实例、磁盘和网络资源:
gcloud container clusters delete CLUSTER_NAME --region=COMPUTE_REGION
请替换以下内容:
CLUSTER_NAME
:hello-cluster
COMPUTE_REGION
:us-west1
删除 Spanner 资源
删除 Spanner 数据库:
gcloud spanner databases delete hello-database --instance=hello-instance
删除 Spanner 实例:
gcloud spanner instances delete hello-instance