使用 ESPv2 为 Knative serving 设置 Cloud Endpoints gRPC
本页介绍了如何为 Knative serving 设置 Cloud Endpoints。Endpoints 使用 Extensible Service Proxy V2 (ESPv2) 作为 API 网关。如需为 Knative serving 提供 API 管理,请将预构建的 ESPv2 容器部署到 GKE 集群上运行的 Knative serving。
如此设置之后,ESPv2 会拦截向您服务发出的所有请求,并在调用服务之前执行任何必要的检查(如身份验证)。当服务响应时,ESPv2 会收集并报告遥测数据。
如需大致了解 Endpoints,请参阅 Endpoints 简介和 Endpoints 架构。
任务列表
学习本教程时,请使用以下任务列表。完成本教程所需的所有任务。
创建一个 Google Cloud 项目,如果您尚未部署自己的 Knative serving,请部署示例服务。请参阅准备工作。
创建 GKE 集群,并启用 Knative serving。
部署 gRPC 示例 Knative serving 服务。
创建描述 Endpoints API 的 gRPC API 配置文档,并配置到 Knative serving 服务的路由。请参阅配置 Endpoints。
部署 gRPC API 配置文档以创建托管式服务。 请参阅部署 Endpoints 配置。
使用您的 Endpoints 服务配置构建新的 ESPv2 Docker 映像。请参阅构建新的 ESPv2 映像。
部署新的 ESPv2 Knative serving 映像。请参阅部署 ESPv2 Cloud Run 映像。
通过向 API 发送请求来测试配置。
跟踪您的服务的活动。 请参阅跟踪 API 活动。
清理.
费用
在本文档中,您将使用 Google Cloud 的以下收费组件:
您可使用价格计算器根据您的预计使用情况来估算费用。
完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理。
准备工作
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure 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.
-
Make sure that billing is enabled for your Google Cloud project.
- 请记下项目 ID,您稍后需要用到它。在本页面的其余部分,此项目 ID 称为 ESP_PROJECT_ID。
- 下载并安装 gcloud CLI。
设置 gcloud 命令行
如需为 Knative serving for Anthos 设置 gcloud CLI,请执行以下操作:
确保 gcloud CLI 有权访问您的数据和服务。
登录。
gcloud auth login
在打开的新浏览器标签页中,选择一个账号,该账号在您为将 ESPv2 部署到 Knative serving 而创建的 Google Cloud 项目中具有 Editor 或 Owner 角色。
更新已安装的
gcloud
组件:gcloud components update
将平台设置为
gke
并将gcloud
的默认项目设置为您刚创建的项目:gcloud config set run/platform gke
gcloud config set project ESP_PROJECT_ID
将 ESP_PROJECT_ID 替换为您创建的项目的 ID。
为新集群设置所需的区域。您可以使用任何支持 GKE 的区域,例如:
gcloud config set compute/zone ZONE
将 ZONE 替换为您的区域。 例如,使用
us-central1-a
。您可以使用 GKE 支持的任何区域。为项目启用以下 API,需要使用它们来创建集群、构建容器以及将容器发布到 Google Container Registry:
gcloud services enable container.googleapis.com containerregistry.googleapis.com cloudbuild.googleapis.com
创建启用了 Knative serving 的 GKE 集群
如需创建集群并为其启用 Knative serving on Google Cloud,请执行以下操作:
使用以下命令创建一个新集群:
gcloud container clusters create CLUSTER_NAME \ --addons=HttpLoadBalancing,CloudRun \ --machine-type=n1-standard-4 \ --num-nodes=3
将 CLUSTER_NAME 替换为您想要使用的集群名称。
虽然这些说明未启用集群自动扩缩功能来根据需求调整集群大小,但 Google Cloud 上的 Knative serving 会自动扩缩集群中的实例。
等待集群创建过程完成。在创建过程中,您应该会看到类似如下所示的消息:
Creating cluster CLUSTER_NAME...done. Created [https://container.googleapis.com/v1/projects/ESP_PROJECT_ID/zones/ZONE/clusters/CLUSTER_NAME].
输出还会在输出的
NODE_VERSION
列下显示集群版本。例如1.15.11-gke.1
或1.14.10-gke.27
。记下集群版本,以便稍后在本文档中使用。设置
gcloud
默认值以使用新的集群和集群位置,从而避免在使用 gcloud CLI 时指定默认值:gcloud config set run/cluster CLUSTER_NAME
gcloud config set run/cluster_location ZONE
使用以下命令查看有关新集群的详细信息:
gcloud container clusters describe CLUSTER_NAME
使用以下命令为您的集群提取凭据:
gcloud container clusters get-credentials CLUSTER_NAME
部署 gRPC Cloud Run 服务示例
如需将“grpc-bookstore”Cloud Run for Anthos 示例容器部署到刚创建的集群,请执行以下操作:
按照 gRPC Python 快速入门中的步骤安装 gRPC 和 gRPC 工具。
此 gRPC 服务器示例包含用于 Python“grpc-bookstore service”的预构建 Docker 映像:
gcr.io/endpointsv2/python-grpc-bookstore-server:2
。使用以下命令将“grpc-bookstore”部署到您的集群:gcloud run deploy GRPC_SERVICE \ --image=gcr.io/endpointsv2/python-grpc-bookstore-server:2 \ --platform=gke \ --connectivity=internal \ --use-http2
请注意,您应将此指定为内部服务,以免外部访问该服务。
将 GRPC_SERVICE 替换为您想要使用的服务名称。例如:
gcloud run deploy grpc-bookstore \ --image=gcr.io/endpointsv2/python-grpc-bookstore-server:2 \ --platform=gke \ --connectivity=internal \ --use-http2
完成后,系统会显示以下消息:
Service [grpc-bookstore] revision [grpc-bookstore-00001-nuk] has been deployed and is serving 100 percent of traffic at http://grpc-bookstore.default.svc.cluster.local
创建内部服务时,GKE 会创建一个 DNS 名称(在此示例中为
grpc-bookstore.default.svc.cluster.local
),该 IP 名称只能解析从集群本身而不是从外部请求发出的请求。您无法从集群外部访问此 DNS。如需了解详情,请参阅 Cloud Run 服务。要验证您的服务是否正常运行,请将具有相同 Docker 映像的 pod 部署到集群。该映像包含“grpc-bookstore”的 gRPC 客户端代码,可用于测试内部服务。
使用以下
kubectl
命令将 pod 部署到上面部署的同一集群:kubectl run grpc --generator=run-pod/v1 \ --image=gcr.io/endpointsv2/python-grpc-bookstore-server:2
此映像包含
bookstore_client.py
脚本,可用于从集群内发出客户端请求。注意:对于较新版本的
kubectl
,该命令可能会发出以下警告:Flag --generator has been deprecated, has no effect and will be removed in the future".
您可以忽略该警告。
获取上一步部署 Docker 映像时在集群中创建的“grpc-bookstore”pod 的名称:
kubectl get pods
您会在表单中看到输出:
NAME READY STATUS RESTARTS AGE grpc 1/1 Running 0 23h
其中
grp
是“grpc-bookstore”pod 的名称。确保 Pod 的 Status 处于Running状态,然后再继续操作。使用以下命令向“grpc-bookstore”服务发出客户端请求:
kubectl exec grpc -ti -- python3 bookstore_client.py \ --host grpc-bookstore.default.svc.cluster.local --port=80
此命令会在集群内部运行
bookstore_client.py
脚本,以向主机名grpc-bookstore.default.svc.cluster.local
上的“grpc-bookstore”服务发出 gRPC 请求。如果一切正常,您会看到以下形式的响应:
ListShelves: shelves { id: 1 theme: "Fiction" } shelves { id: 2 theme: "Fantasy" }
配置 Endpoints
您必须具有描述后端服务的表面和任何身份验证要求的 gRPC API 规范。
设置 gRPC API 规范的名称字段的简介
在 gRPC API 规范的 name
字段中,指定用于访问 Cloud Run for Anthos 服务的 Endpoints 服务名称。Endpoints 服务名称采用域名形式:
API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog
由于 Endpoints 服务名称与域名对应,因此名称必须遵循以下规则:
- 必须仅包含小写字母、数字、句点或短划线。
- 不能以短划线开头。
- 不得包含下划线。
例如:
grpc-boostore-api.endpoints.ESP_PROJECT_ID.cloud.goog
制定 gRPC API 规范
bookstore-grpc 示例包含需要在本地复制和配置的文件。
为 gRPC API 规范创建新目录,例如
my-anthos-grpc
。然后使用 cd 转到该目录。克隆将 gRPC 客户端代码托管到新目录的 git 代码库:
git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
切换您的工作目录:
cd python-docs-samples/endpoints/bookstore-grpc/
请注意,此目录包含 bookstore.proto 文件。此文件用于定义 Bookstore 服务的 API。
通过服务
.proto
文件创建一个独立的 protobuf 描述符文件:在工作目录下创建
generated_pb2
目录。使用
protoc
Protocol Buffers 编译器创建描述符文件api_descriptor.pb
。在包含bookstore.proto
的目录中运行以下命令:python3 -m grpc_tools.protoc \ --include_imports \ --include_source_info \ --proto_path=. \ --descriptor_set_out=api_descriptor.pb \ --python_out=generated_pb2 \ --grpc_python_out=generated_pb2 \ bookstore.proto
在前面的命令中,
--proto_path
设置为当前工作目录。在 gRPC 编译环境中,如果对.proto
输入文件使用其他目录,请更改--proto_path
,以便编译器搜索您保存了bookstore.proto
文件的目录。修改当前工作目录中的
api_config_anthos.yaml
文件(包含bookstore.proto
的同一目录)以向该文件添加以下内容:type: google.api.Service config_version: 3 # # Name of the service configuration. # name: API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog # # API title to appear in the user interface (Google Cloud console). # title: Bookstore gRPC API In Cloud Run Anthors apis: - name: endpoints.examples.bookstore.Bookstore # # Create a DNS record to map your service name to IP address # endpoints: - name: API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog target: IP_ADDRESS # # Specify the backend address to route to # backend: rules: - selector: "*" address: grpc://GRPC_SERVICE.default.svc.cluster.local disable_auth: true # # API usage restrictions. # usage: rules: # ListShelves methods can be called without an API Key. - selector: endpoints.examples.bookstore.Bookstore.ListShelves allow_unregistered_calls: true
缩进对 yaml 格式而言非常重要。
在
name
字段中,指定用于访问 Cloud Run for Anthos 服务的 Endpoints API 的域名,格式如下:API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog
例如:
grpc-bookstore-api.endpoints.ESP_PROJECT_ID.cloud.goog
endpoints
部分会在cloud.goog
网域上为您的 Endpoints 服务注册 DNS 条目,格式如下:endpoints: - name: API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog target: IP_ADDRESS
IP_ADDRESS 是集群的
istio-ingress
服务的 IP 地址。要确定此 IP 地址,请执行以下操作:前往 Cloud 控制台中的 Google Kubernetes Engine 页面:
点击左侧导航面板中的 Service 和 Ingress 以显示服务列表。
如果您的集群版本为
1.15.3-gke.19
或更高版本、1.14.3-gke.12
或更高版本、1.13.10-gke.8
或更高版本,请向下滚动至istio-ingress
服务。对于所有其他集群版本,向下滚动至istio-ingressgateway
服务。复制负载平衡器旁边显示的外部 IP 地址(如果有),不带端口设置。例如,如果 IP 地址为
XX.XXX.XX.XXX:15020
,请省略:15020
。请忽略列出的其他 IP 地址。
backend
部分中的address
字段指定采用 proto 方案grpc://
的 Cloud Run "grpc-bookstore" 服务的内部 DNS 名称,并停用此服务的身份验证:address: grpc://GRPC_SERVICE.default.svc.cluster.local disable_auth: true
例如:
address: grpc://grpc-bookstore.default.svc.cluster.local disable_auth: true
这是必要的操作,因为从 ESPv2 到 Cloud Run for Anthos 服务的调用在集群内部进行内部调用,因此不需要进行身份验证。
请记下
api_config_authos.yaml
文件中title
属性的值:title: Bookstore gRPC API In Cloud Run Anthos
在您部署配置后,
title
属性的值会成为 Endpoints 服务的名称。保存您的 gRPC API 文档。
如需了解 OpenAPI 文档中 Endpoints 所需的字段,请参阅配置 Endpoints。
部署 Endpoints 配置
要部署 Endpoints 配置,请使用 gcloud endpoints services deploy 命令。此命令使用 Service Management 创建一项托管式服务。
如需部署 Endpoints 配置,请执行以下操作:
确保您位于 gRPC 文档所在的目录中。
上传配置并创建托管式服务。
gcloud endpoints services deploy api_descriptor.pb api_config_anthos.yaml \ --project ESP_PROJECT_ID
这将创建一个新的 Endpoints 服务,其名称是您在
api_config_anthos.yaml
文件的name
字段中指定的名称。Endpoints 服务会根据您的 OpenAPI 文档进行配置。在创建和配置 Endpoints 服务时,Service Management 会向终端输出信息。部署完成后,系统将显示如下所示的消息:
Service Configuration [CONFIG_ID] uploaded for service [API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog]
CONFIG_ID 是部署创建的唯一 Endpoints 服务配置 ID。例如:
Service Configuration [2019-02-01r0] uploaded for service [grpc-bookstore-api.endpoints.ESP_PROJECT_ID.cloud.goog]
服务配置 ID 由日期戳后跟一个修订版本号组成。如果您在同一天再次部署
api_config_anthos.yaml
,则服务配置 ID 中的修订号会递增。您可以在以下位置查看服务配置和部署历史记录:Google Cloud 控制台页面。如果您收到错误消息,请参阅排查 Endpoints 配置部署问题。
检查所需服务
Endpoints 和 ESP 至少需要启用以下 Google 服务:姓名 | 标题 |
---|---|
servicemanagement.googleapis.com |
Service Management API |
servicecontrol.googleapis.com |
Service Control API |
endpoints.googleapis.com |
Google Cloud Endpoints |
在大多数情况下,gcloud endpoints services deploy
命令会启用这些必需的服务。但在以下情况下,gcloud
命令会成功完成,但不启用必需的服务:
您使用了 Terraform 之类的第三方应用,但未添加这些服务。
您将 Endpoints 配置部署到已明确停用这些服务的现有 Google Cloud 项目。
使用以下命令确认必需服务是否已启用:
gcloud services list
如果您没有看到列出的必需服务,请启用它们:
gcloud services enable servicemanagement.googleapis.comgcloud services enable servicecontrol.googleapis.com
gcloud services enable endpoints.googleapis.com
同时启用 Endpoints 服务:
gcloud services enable ENDPOINTS_SERVICE_NAME
要确定 ENDPOINTS_SERVICE_NAME,您可以执行以下任一操作:
部署 Endpoints 配置后,转到 Cloud 控制台中的端点页面。服务名称列下显示了可能的 ENDPOINTS_SERVICE_NAME 列表。
对于 OpenAPI,ENDPOINTS_SERVICE_NAME 是您在 OpenAPI 规范的
host
字段中指定的值。对于 gRPC,ENDPOINTS_SERVICE_NAME 是您在 gRPC Endpoints 配置的name
字段中指定的值。
如需详细了解 gcloud
命令,请参阅 gcloud
服务。
构建新的 ESPv2 Knative serving 映像
将 Endpoints 服务配置构建到新的 ESPv2 Docker 映像中。创建此映像后,您可以将其部署到您的集群。
如需将服务配置构建到新的 ESPv2 Docker 映像中,请执行以下操作:
将此脚本下载到安装了 gcloud CLI 的本地机器,并运行以下命令:
chmod +x gcloud_build_image
./gcloud_build_image -s API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog \ -c CONFIG_ID -p ESP_PROJECT_ID
该脚本使用
gcloud
命令下载服务配置,将服务配置构建到新的 ESPv2 映像中,然后将新映像上传到项目 Container Registry 中:脚本会自动使用最新版本的 ESPv2,由输出映像名称中的 ESP_VERSION 表示。输出映像将上传到:gcr.io/ESP_PROJECT_ID/endpoints-runtime-serverless:ESP_VERSION-API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog-CONFIG_ID
部署 ESPv2 Knative 服务映像
将 ESPv2 Knative serving 服务映像部署到您的集群:
使用新映像部署 ESPv2 Knative serving 服务:
gcloud run deploy ESP_V2_SERVICE_NAME \ --image="gcr.io/ESP_PROJECT_ID/endpoints-runtime-serverless:API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog-CONFIG_ID" \ --platform gke \ --use-http2 \ --project=ESP_PROJECT_ID
对于 ESP_PROJECT_ID,请指定要用于 ESPv2 服务的名称。在此示例中,将 ESP_V2_SERVICE_NAME 设置为
espv2
。如果要将 Endpoints 配置为使用其他 ESPv2 启动选项(例如启用 CORS),您可以在
ESPv2_ARGS
环境变量中传递参数:gcloud run deploy ESP_V2_SERVICE_NAME \ --image="gcr.io/ESP_PROJECT_ID/endpoints-runtime-serverless:API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog-CONFIG_ID" \ --set-env-vars=ESPv2_ARGS=--cors_preset=basic \ --platform gke --use-http2 \ --project ESP_PROJECT_ID
如需详细了解如何设置 ESPv2_ARGS 环境变量并获取更多相关示例(包括可用选项的列表以及如何指定多个选项的信息),请参阅 Extensible Service Proxy V2 标志。
创建映射到 ESPv2 Knative serving 服务的网域
要在发出请求时省略 host
标头,请为 ESPv2 服务添加网域映射:
选择管理自定义网域。
选择添加映射。
从下拉列表中选择添加服务网域映射。
在添加映射弹出窗口的选择要映射到的服务字段中,选择您的 ESPv2 服务。
在输入域名字段中,指定要用于通过 Endpoints 访问 Knative serving 服务的域名。例如,您应指定:
API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog
其中 API_NAME 是 Endpoints API 的名称。在此示例中,您可以使用“hello-api”:
grpc-bookstore-api.endpoints.ESP_PROJECT_ID.cloud.goog
点击继续。此时会显示映射的摘要。
选择完成以保存映射。
向 API 发送请求
要向示例 API 发送请求,您可以使用以 Python 编写的示例 gRPC 客户端。
确保您位于包含 gRPC 文档的目录中,例如
api_config_anthos.yaml
。安装依赖项:
pip3 install virtualenv
virtualenv env
source env/bin/activate
pip3 install -r requirements.txt
向示例 API 发送一个请求:
python3 bookstore_client.py --host API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog --port 80
例如:
python3 bookstore_client.py --host grpc-bookstore-api.endpoints.ESP_PROJECT_ID.cloud.goog --port 80
如果一切正常,您会看到以下形式的响应:
ListShelves: shelves { id: 1 theme: "Fiction" } shelves { id: 2 theme: "Fantasy" }
在 Endpoints > 服务页面中查看 API 的活动图表。
请求可能需要一些时间才能体现在图表中。
在“日志浏览器”页面中查看 API 的请求日志。
如果未获得成功响应,请参阅排查响应错误。
您刚刚在 Endpoints 中部署并测试了一个 API!
配置 Endpoints API 以使用 HTTPS
对于 Google Cloud 上的 Knative serving,自动 TLS 支持默认处于停用状态。因此,在此示例中,当您通过 ESPv2 访问 Endpoints API 时,您使用 HTTP 进行调用。
您可以配置 ESPv2 以支持使用 HTTPS 的请求。请注意,您可以在 ESPv2(外部服务,而不是“hello”内部后端服务)上配置 HTTPS 支持。
要通过 ESPv2 支持 HTTPS,您必须:
拥有域名。如果您没有网域,可以从 Google 或其他网域供应商获取一个。
为 ESPv2 服务创建网域映射,然后按照网域映射页面中的说明相应地更新 DNS 记录。
如果您是通过 Google Domains 获得的网域,请将其用作 DNS 服务器。否则,请使用 Cloud DNS 或您选择的 DNS 服务器。使用 Google Domains 中的网域是最简单的选择。
在 Endpoints OpenAPI 规范中:
将
name
字段设置为引用您的域名,而不是*.cloud.goog
。移除
endpoints
标记及其两个子属性。
如需了解完整说明和教程,请参阅启用 HTTPS 和自动 TLS 证书。
跟踪 API 活动
在 Endpoint 上查看 API 的活动图表 >服务 页面。
请求可能需要一些时间才能体现在图表中。
在“日志浏览器”页面上查看 API 的请求日志。
为 API 创建开发者门户
您可以使用 Cloud Endpoints 门户来创建开发者门户,一个可供您与示例 API 互动的网站。如需了解详情,请参阅 Cloud Endpoints 门户概览。
清理
为避免因本页中使用的资源导致您的 Google Cloud 账号产生费用,请按照以下步骤操作。
如需了解如何停止本教程使用的服务,请参阅删除 API 和 API 实例。