使用 ESPv2 为 Knative 服务设置 Cloud Endpoints OpenAPI

本页介绍了如何为 Knative serving 设置 Cloud Endpoints。Endpoints 使用 Extensible Service Proxy V2 (ESPv2) 作为 API 网关。如需为 Knative serving 提供 API 管理,请将预构建的 ESPv2 容器部署到在 GKE 集群上运行的 Knative serving

如此设置之后,ESPv2 会拦截向您服务发出的所有请求,并在调用服务之前执行任何必要的检查(如身份验证)。当服务响应时,ESPv2 会收集并报告遥测数据。

如需大致了解 Endpoints,请参阅 Endpoints 简介Endpoints 架构

任务列表

学习本教程时,请使用以下任务列表。完成本教程所需的所有任务

  1. 创建一个 Google Cloud 项目,如果您尚未部署自己的 Knative serving,请部署一个示例服务。请参阅准备工作

  2. 创建已启用 Knative serving 的 GKE 集群

  3. 部署示例 Knative serving 服务。

  4. 创建描述 Endpoints API 的 OpenAPI 文档,并配置到 Knative 服务的路由。请参阅配置 Endpoints

  5. 部署 OpenAPI 文档以创建托管式服务。 请参阅部署 Endpoints 配置

  6. 使用您的 Endpoints 服务配置构建新的 ESPv2 Docker 映像。请参阅构建新的 ESPv2 映像

  7. 部署新的 ESPv2 Knative serving 映像。请参阅部署 ESPv2 Cloud Run 映像

  8. 创建映射到 ESPv2 Knative serving 服务的网域

  9. 通过向 API 发送请求来测试配置。

  10. 跟踪您的服务的活动。 请参阅跟踪 API 活动

  11. 清理.

费用

在本文档中,您将使用 Google Cloud 的以下收费组件:

您可使用价格计算器根据您的预计使用情况来估算费用。 Google Cloud 新用户可能有资格申请免费试用

完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理

准备工作

  1. 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.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  5. Make sure that billing is enabled for your Google Cloud project.

  6. 请记下项目 ID,您稍后需要用到它。在本页面的其余部分,此项目 ID 称为 ESP_PROJECT_ID
  7. 下载并安装 Google Cloud SDK
  8. 如果要向已部署的示例服务发送请求,您需要安装 cURL

设置 gcloud 命令行

如需为 Anthos 的 Knative serving 设置 gcloud CLI,请执行以下操作:

  1. 确保 Google Cloud SDK 有权访问您的数据和服务。

    1. 登录。

      gcloud auth login

    2. 在打开的新浏览器标签页上,选择一个账号,该账号在您为将 ESPv2 部署到 Knative 服务而创建的 Google Cloud 项目中具有 EditorOwner 角色。

  2. 更新已安装的 gcloud 组件:

    gcloud components update
  3. 将平台设置为 gke 并将 gcloud 的默认项目设置为您刚创建的项目:

    gcloud config set run/platform gke 
    gcloud config set project ESP_PROJECT_ID

    ESP_PROJECT_ID 替换为您创建的项目的 ID。

  4. 为新集群设置所需的区域。您可以使用任何支持 GKE 的区域,例如:

    gcloud config set compute/zone ZONE

    ZONE 替换为您的区域。 例如,使用 us-central1-a。您可以使用 GKE 支持的任何区域。

  5. 为项目启用以下 API,需要使用它们来创建集群、构建容器以及将容器发布到 Artifact Registry:

    gcloud services enable container.googleapis.com artifactregistry.googleapis.com cloudbuild.googleapis.com

创建已启用 Knative serving 的 GKE 集群

如需创建集群并为其启用 Google Cloud 上的 Knative serving,请执行以下操作:

  1. 使用以下命令创建一个新集群:

    gcloud container clusters create CLUSTER_NAME \ 
      --addons=HttpLoadBalancing,CloudRun \ 
      --machine-type=n1-standard-4 \ 
      --num-nodes=3 \ 
      --enable-stackdriver-kubernetes

    CLUSTER_NAME 替换为您想要使用的集群名称。

    虽然这些说明未启用集群自动扩缩以根据需求调整集群大小,但是 Google Cloud 上的 Knative 服务会自动扩缩集群中的实例。

  2. 等待集群创建过程完成。在创建过程中,您应该会看到类似如下所示的消息:

    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.11.14.10-gke.27。记下集群版本,以便稍后在本文档中使用。

  3. 设置 gcloud 默认值以使用新的集群和集群位置,这样,您就无需在使用 gcloud CLI 时指定这些值:

    gcloud config set run/cluster CLUSTER_NAME
    gcloud config set run/cluster_location ZONE
  4. 使用以下命令查看有关新集群的详细信息:

    gcloud container clusters describe CLUSTER_NAME
  5. 使用以下命令为您的集群提取凭据:

    gcloud container clusters get-credentials CLUSTER_NAME

部署 Knative serving 示例容器

如需将“hello”Knative serving 示例容器部署到刚创建的集群,请执行以下操作:

  1. 转到 Cloud Run

  2. 点击创建服务

  3. 选择 Knative serving 作为开发平台。

  4. 在“可用集群”下拉菜单中,选择刚创建的集群。

  5. 使用 hello 名称作为服务名称。您可以使用其他名称,但如果这样做的话,以后请务必使用该名称。此处的说明假设您使用的是 hello 名称。

  6. 选择连接下的内部,确保该服务无法从外部访问。

  7. 点击下一步以转到服务创建表单的第二页:

  8. gcr.io/cloudrun/hello 指定为容器映像网址

  9. 点击创建以将映像部署到 Knative serving,然后等待部署完成。

    完成后,系统会显示修订版本屏幕。请注意,已部署服务的网址为:

    http://hello.default.svc.cluster.local

    创建内部服务时,GKE 会创建一个 DNS 名称,该名称只能解析从集群本身而不是外部请求发出的请求。您无法从集群外部访问此链接。如需了解详情,请参阅 Cloud Run 服务

  10. 要使用 cURL 验证您的服务是否正常运行,请设置从桌面到集群的隧道。要查看这些说明,请在修订版本屏幕上点击相应网址右侧的图标:

    “修订版本”屏幕。

  11. 此时,面板打开并显示您用于访问内部服务的两个命令。您必须在两个单独的终端窗口中运行这些命令,因为第一个命令设置第二个命令使用的端口转发。

    运行 cURL 命令时,您应该会在服务中看到以下形式的输出:

    <!doctype html>
    <html lang=en> 
    <head> 
    <meta charset=utf-8> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <title>Congratulations | Cloud Run</title> 
    ...

配置 Endpoints

您必须有一个基于 OpenAPI 规范 2.0 版的 OpenAPI 文档,该文档描述您的后端服务的表面以及任何身份验证要求。您还需要添加特定于 Google 的字段,其中包含每项服务的网址,以便 ESPv2 获得调用服务所需的信息。如果您刚接触 OpenAPI,请参阅 OpenAPI 概览了解详情。

设置 OpenAPI 规范的主机字段的简介

在 OpenAPI 规范的 host 字段中,指定用于访问 Knative serving 服务的 Endpoints 服务名称。Endpoints 服务名称采用域名形式:

API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog

由于 Endpoints 服务名称与域名对应,因此名称必须遵循以下规则:

  • 必须仅包含小写字母、数字、句点或短划线。
  • 不能以短划线开头。
  • 不得包含下划线。

例如:

hello-api.endpoints.ESP_PROJECT_ID.cloud.goog

创建 OpenAPI 规范

  1. 创建名为 openapi-run-anthos.yaml 的文本文件。

  2. 您的 Knative serving 后端服务在 openapi-run-anthos.yaml 文件顶部的 x-google-backend 定义中定义。例如:

    swagger: '2.0' 
    info:
      title: Cloud Endpoints + Cloud Run
      description: Sample API on Cloud Endpoints with a Cloud Run backend
      version: 1.0.0 
    host: API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog
    x-google-endpoints:
    - name: API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog
      target: "INGRESS-IP"
    schemes:
      - https
    produces:
      - application/json
    x-google-backend:
      address: http://hello.default.svc.cluster.local
      disable_auth: true
    paths:
      /hello:
        get:
          summary: Greet a user
          operationId: hello
          responses:
            '200':
              description: A successful response
              schema:
                type: string

    缩进对 YAML 格式而言非常重要。例如,host 字段必须与 info 处于同一级别。

  3. host 字段中,指定用于访问 Knative 服务的 Endpoints API 的域名,格式如下:

    API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog

    例如:

    hello-api.endpoints.ESP_PROJECT_ID.cloud.goog
  4. x-google-endpoints 扩展程序会在 cloud.goog 网域上为您的 Endpoints 服务注册 DNS 条目,格式如下:

    x-google-endpoints: 
      - name: "API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog"
      target: "IP_ADDRESS"

    IP_ADDRESS 是集群的 istio-ingress 服务的 IP 地址。要确定此 IP 地址,请执行以下操作:

    1. 前往 Google Cloud 控制台中的 Google Kubernetes Engine 页面:

      转到 Google Kubernetes Engine

    2. 点击左侧导航面板中的 Service 和 Ingress 以显示服务列表。

    3. 如果您的集群版本为 1.15.3-gke.19 或更高版本、1.14.3-gke.12 或更高版本、1.13.10-gke.8 或更高版本,请向下滚动至 istio-ingress 服务。对于所有其他集群版本,向下滚动至 istio-ingressgateway 服务。

    4. 复制负载平衡器旁边显示的外部 IP 地址(如果有),不带端口设置。例如,如果 IP 地址为 XX.XXX.XX.XXX:15020,请省略 :15020。请忽略列出的其他 IP 地址。

  5. x-google-backend 部分的 address 字段中,指定后端 Knative 服务器“hello”服务的内部 DNS 名称,并停用对此服务的身份验证。这是必要的操作,因为从 ESPv2 到 Knative 服务的调用在集群内部进行内部调用,因此不需要进行身份验证。

  6. 请记下 openapi-run-anthos.yaml 文件中 title 属性的值:

    title: Cloud Endpoints + Cloud Run 
  7. 在您部署配置后,title 属性的值会成为 Endpoints 服务的名称。

  8. 保存您的 OpenAPI 文档。

如需了解 OpenAPI 文档中 Endpoints 所需的字段,请参阅配置 Endpoints

部署 Endpoints 配置

要部署 Endpoints 配置,请使用 gcloud endpoints services deploy 命令。此命令使用 Service Management 创建一项托管式服务。

如需部署 Endpoints 配置,请执行以下操作:

  1. 确保您位于 OpenAPI 文档所在的目录中。

  2. 上传配置并创建托管式服务。

    gcloud endpoints services deploy openapi-run-anthos.yaml \ 
      --project ESP_PROJECT_ID

    这将创建一个新的 Endpoints 服务,其名称是您在 openapi-run-anthos.yaml 文件的 host 字段中指定的名称。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 [hello-api.endpoints.ESP_PROJECT_ID.cloud.goog] 

    服务配置 ID 由日期戳后跟一个修订版本号组成。如果您在同一天再次部署 openapi-run-anthos.yaml,则服务配置 ID 中的修订号会递增。您可以在 Google Cloud 控制台中的 Endpoints > 服务页面上查看服务配置和部署历史记录

    如果您收到错误消息,请参阅排查 Endpoints 配置部署问题

检查所需服务

Endpoints 和 ESP 至少需要启用以下 Google 服务:
姓名 标题
servicemanagement.googleapis.com Service Management API
servicecontrol.googleapis.com Service Control API

在大多数情况下,gcloud endpoints services deploy 命令会启用这些必需的服务。但在以下情况下,gcloud 命令会成功完成,但不启用必需的服务:

  • 您使用了 Terraform 之类的第三方应用,但未添加这些服务。

  • 您将 Endpoints 配置部署到已明确停用这些服务的现有 Google Cloud 项目。

使用以下命令确认必需服务是否已启用:

gcloud services list

如果您没有看到列出的必需服务,请启用它们:

gcloud services enable servicemanagement.googleapis.com
gcloud services enable servicecontrol.googleapis.com

同时启用 Endpoints 服务:

gcloud services enable ENDPOINTS_SERVICE_NAME

要确定 ENDPOINTS_SERVICE_NAME,您可以执行以下任一操作:

  • 部署 Endpoints 配置后,前往 Cloud 控制台中的 Endpoints 页面。服务名称列下显示了可能的 ENDPOINTS_SERVICE_NAME 列表。

  • 对于 OpenAPI,ENDPOINTS_SERVICE_NAME 是您在 OpenAPI 规范的 host 字段中指定的值。对于 gRPC,ENDPOINTS_SERVICE_NAME 是您在 gRPC Endpoints 配置的 name 字段中指定的值。

如需详细了解 gcloud 命令,请参阅 gcloud 服务

构建新的 ESPv2 Knative 服务映像

将 Endpoints 服务配置构建到新的 ESPv2 Docker 映像中。创建此映像后,您可以将其部署到您的集群。

如需将服务配置构建到新的 ESPv2 Docker 映像中,请执行以下操作:

  1. 将此脚本下载到安装了 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 serving 映像

将 ESPv2 Knative serving 服务映像部署到您的集群:

  1. 使用新映像部署 ESPv2 Knative serving 服务:

    gcloud run deploy ESP_V2_SERVICE_NAME \ 
      --image="gcr.io/ESP_PROJECT_ID/endpoints-runtime-serverless:ESP_VERSION-API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog-CONFIG_ID" \ 
      --platform gke \ 
      --project=ESP_PROJECT_ID

    对于 ESP_PROJECT_ID,请指定要用于 ESPv2 服务的名称。在此示例中,将 ESP_V2_SERVICE_NAME 设置为 espv2

  2. 如果要将 Endpoints 配置为使用其他 ESPv2 启动选项(例如启用 CORS),您可以在 ESPv2_ARGS 环境变量中传递参数:

    gcloud run deploy ESP_V2_SERVICE_NAME \
      --image="gcr.io/ESP_PROJECT_ID/endpoints-runtime-serverless:ESP_VERSION-API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog-CONFIG_ID" \ 
      --set-env-vars=ESPv2_ARGS=--cors_preset=basic \ 
      --platform gke \ 
      --project ESP_PROJECT_ID

    如需详细了解如何设置 ESPv2_ARGS 环境变量并获取更多相关示例(包括可用选项的列表以及如何指定多个选项的信息),请参阅 Extensible Service Proxy V2 标志

ESPv2 服务部署为外部服务,这意味着您可以使用以下形式的 cURL 命令访问该服务:

curl -H "Host: espv2.default.example.com" http://IP_ADDRESS

其中,IP_ADDRESS 是集群的 istio-ingress 服务的 IP 地址。

如需查看此 c网址 命令,请点击已部署的 ESPv2 Knative 服务的修订版本屏幕上的 ESPv2 网址右侧的 IMAGE 图标。

您现在可以通过 ESPv2 服务对 Endpoints 服务进行 API 调用。例如,要向路径为 /hello 的 Endpoints 服务发出请求,您可以采用以下形式发出请求:

curl -H "Host: espv2.default.example.com" http://IP_ADDRESS/hello

但是,在向 Endpoints 服务发送的每个请求中指定 host 标头并不简单。在下一部分中,您将设置网域映射,以便更轻松地通过 ESPv2 调用 Endpoint 服务。

创建映射到 ESPv2 Knative serving 服务的网域

要在发出请求时省略 host 标头,请为 ESPv2 服务添加网域映射:

  1. 转到 Cloud Run

  2. 选择管理自定义网域

  3. 选择添加映射

  4. 从下拉列表中选择添加服务网域映射

  5. 添加映射弹出窗口的选择要映射到的服务字段中,选择您的 ESPv2 服务。

  6. 输入域名字段中,指定要用于通过 Endpoints 访问 Knative serving 服务的域名。例如,您应指定:

    API_NAME.endpoints.ESP_PROJECT_ID.cloud.goog

    其中 API_NAME 是 Endpoints API 的名称。在本例中,您可以使用“hello-api”:

    hello-api.endpoints.ESP_PROJECT_ID.cloud.goog

  7. 点击继续。此时会显示映射的摘要。

  8. 选择完成以保存映射。

向 API 发送请求

使用 cURL 向您的 API 发送 HTTP 请求:

curl -X GET "http://hello-api.endpoints.ESP_PROJECT_ID.cloud.goog/hello"

如果未成功收到响应,请参阅排查响应错误

配置 Endpoints API 以使用 HTTPS

Google Cloud 上的 Knative serving 默认停用自动 TLS 支持。因此,在此示例中,当您通过 ESPv2 访问 Endpoints API 时,您使用 HTTP 进行调用。

您可以配置 ESPv2 以支持使用 HTTPS 的请求。请注意,您可以在 ESPv2(外部服务,而不是“hello”内部后端服务)上配置 HTTPS 支持。

若要通过 ESPv2 支持 HTTPS,您必须:

  1. 拥有域名。如果您没有网域,可以从 Cloud Domains 或其他网域供应商获取一个。

  2. 为 ESPv2 服务创建网域映射,然后按照网域映射页面中的说明相应地更新 DNS 记录。

    如果您是通过 Cloud Domains 获得的网域,请使用 Cloud DNS 或您选择的 DNS 服务器。使用 Cloud Domains 中的网域是最简单的选择。

  3. 在 Endpoints OpenAPI 规范中:

    1. host 字段设置为引用您的域名,而不是*.cloud.goog

    2. 移除 x-google-endpoints 标记及其两个子属性。

如需了解完整说明和教程,请参阅启用 HTTPS 和自动 TLS 证书

跟踪 API 活动

  1. 在 Google Cloud 控制台中,依次前往 Endpoints > Service 页面,查看 API 的活动图表。

    查看 Endpoints 活动图表

    请求可能需要一些时间才能体现在图表中。

  2. 在“日志浏览器”页面上查看 API 的请求日志。查看 Endpoints 请求日志

为 API 创建开发者门户

您可以使用 Cloud Endpoints 门户来创建开发者门户,一个可供您与示例 API 互动的网站。如需了解详情,请参阅 Cloud Endpoints 门户概览

清理

为避免因本页中使用的资源导致您的 Google Cloud 账号产生费用,请按照以下步骤操作。

如需了解如何停止本教程使用的服务,请参阅删除 API 和 API 实例

后续步骤