使用 Service Directory 的服务注册表调用专用端点

您可以将 Service Directory 的服务注册与 Workflows 搭配使用,以将工作流执行中的 HTTP 调用定向到专用端点。这样一来,您就可以为工作流提供 Service Directory 服务名称。工作流执行会使用从服务注册表中检索到的信息来发送相应的 HTTP 请求,而不会流出到公共网络。

本文档介绍了如何将 Virtual Private Cloud (VPC) 网络中的虚拟机 (VM) 注册为 Service Directory 端点:

  • VPC 网络可为您的虚拟机实例提供连接,并允许您使用内部 IP 地址在 VPC 网络中创建专用端点。在实施 Identity and Access Management (IAM) 和 VPC Service Controls 时,通过专用网络向 VPC 网络资源发送 HTTP 调用。

  • Service Directory 是一个服务注册表,用于存储已注册的网络服务的相关信息,包括其名称、位置和属性。无论服务的基础架构如何,您都可以自动注册服务并捕获其详细信息。这样,您就可以大规模发现、发布和连接所有服务端点对应的服务。

下图简要展示了此过程:

使用来自 Service Directory 的信息向虚拟机实例上的端口号发送 HTTP 请求

概括来讲,您必须执行以下操作:

  1. 向 Cloud Workflows 服务代理授予权限,以便该服务代理可以查看 Service Directory 资源并使用 Service Directory 访问 VPC 网络。
  2. 创建 VPC 网络以提供网络功能。
  3. 创建 VPC 防火墙规则,以便允许或拒绝流量进出 VPC 网络中的虚拟机实例。
  4. 在 VPC 网络中创建虚拟机实例。Compute Engine 虚拟机实例是托管在 Google 基础设施上的虚拟机。术语“Compute Engine 实例”“虚拟机实例”和“虚拟机”是同义词,可互换使用。
  5. 在虚拟机上部署应用。您可以在虚拟机实例上运行应用,并确认流量是否按预期提供。
  6. 配置 Service Directory,以便工作流执行可以调用 Service Directory 端点。

  7. 创建并部署工作流。工作流中的 private_service_name 值指定了您在上一步中注册的 Service Directory 端点。

向 Cloud Workflows 服务代理授予权限

某些 Google Cloud 服务具有服务代理,让服务可以访问您的资源。如果 API 需要服务代理,则 Google 会在您激活并使用 API 后创建服务代理。

  1. 首次部署工作流时,系统会自动创建 Cloud Workflows 服务代理,其格式如下:

    service-PROJECT_NUMBER@gcp-sa-workflows.iam.gserviceaccount.com

    您可以使用以下命令在没有任何工作流的项目中手动创建服务账号:

    gcloud beta services identity create \
        --service=workflows.googleapis.com \
        --project=PROJECT_ID

    PROJECT_ID 替换为您的 Google Cloud项目 ID。

  2. 如需查看 Service Directory 资源,请向 Workflows 服务代理授予项目的 Service Directory Viewer 角色 (servicedirectory.viewer):

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:service-PROJECT_NUMBER@gcp-sa-workflows.iam.gserviceaccount.com \
        --role=roles/servicedirectory.viewer

    PROJECT_NUMBER 替换为您的 Google Cloud项目编号。您可以在 Google Cloud 控制台的欢迎页面上,或通过运行以下命令来查找项目编号:

    gcloud projects describe PROJECT_ID --format='value(projectNumber)'
  3. 如需使用 Service Directory 访问 VPC 网络,请向 Workflows 服务代理授予项目的 Private Service Connect Authorized Service 角色 (roles/servicedirectory.pscAuthorizedService):

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:service-PROJECT_NUMBER@gcp-sa-workflows.iam.gserviceaccount.com \
        --role=roles/servicedirectory.pscAuthorizedService

创建 VPC 网络

VPC 网络是物理网络的虚拟版本,在 Google 的生产网络内实现。可为 Compute Engine 虚拟机实例提供连接。

您可以创建自动模式或自定义模式 VPC 网络。您创建的每个新网络在同一项目内必须具有唯一的名称。

例如,以下命令会创建一个自动模式 VPC 网络:

gcloud compute networks create NETWORK_NAME \
    --subnet-mode=auto

NETWORK_NAME 替换为 VPC 网络的名称。

如需了解详情,请参阅创建和管理 VPC 网络

创建 VPC 防火墙规则

通过 VPC 防火墙规则,您可以根据端口号、标记或协议来允许或拒绝进出 VPC 网络中的虚拟机实例的流量。

VPC 防火墙规则是在网络级别定义的,仅会应用于在其中创建它们的网络;但是,您为规则选择的名称在项目中必须是唯一的。

例如,以下命令会为您之前创建的 VPC 网络创建防火墙规则。

gcloud compute firewall-rules create RULE_NAME \
    --network=projects/PROJECT_ID/global/networks/NETWORK_NAME \
    --direction=INGRESS \
    --action=ALLOW \
    --source-ranges=IP_ADDRESS_RANGE \
    --rules=all

替换以下内容:

  • RULE_NAME:防火墙规则的名称。

  • IP_ADDRESS_RANGE:一个或多个 IPv4 或 IPv6 地址范围。最佳实践是指定允许访问所需的特定 IP 地址范围。请注意以下几点:

    • Service Directory 的专用网络访问通道将 35.199.192.0/19 用作仅限内部使用的范围,其下一个跃点完全在 Google 网络内。如需了解详情,请参阅 Cloud DNS 和 Service Directory 的路径

    • 如果满足所有其他前提条件,则在来源范围中包含 35.235.240.0/20 允许使用 Identity-Aware Proxy (IAP) TCP 转发的 SSH 连接。如需了解详情,请参阅使用 IAP 进行 TCP 转发

    • 如果您使用 SSH-in-browser 工具从 Google Cloud 控制台内连接到 Compute Engine 虚拟机,则需要满足特定要求

  • --rules 标志值为 all 时,防火墙规则适用于所有协议和所有目标端口。您可以通过指定协议和端口来缩小范围。

  • (可选)您可以使用 --target-tags--target-service-accounts 标志来定义目标;否则,规则将应用于网络中的所有目标。

如需了解详情,请参阅使用 VPC 防火墙规则

在 VPC 网络中创建虚拟机实例

虚拟机实例包括 Google Kubernetes Engine (GKE) 集群、App Engine 柔性环境实例,以及 Compute Engine 虚拟机上构建的其他 Google Cloud 产品。为了支持专用网络访问,VPC 网络资源可以是虚拟机实例、Cloud Interconnect IP 地址或第 4 层内部负载均衡器。

Compute Engine 实例可以运行 Google 提供的 Linux 和 Windows Server 公开映像,也可以运行由您创建或从现有系统导入的私有自定义映像。您还可以部署 Docker 容器。

您可以使用一组预定义机器类型或创建自己的自定义机器类型,以选择实例的机器属性,例如虚拟 CPU 数量和内存容量。

例如,以下命令会通过公共映像创建一个 Linux 虚拟机实例,该实例的网络接口已附加到您之前创建的 VPC 网络。

  1. 创建并启动虚拟机实例:

    gcloud compute instances create VM_NAME \
        --image-family=debian-11 \
        --image-project=debian-cloud \
        --machine-type=e2-micro \
        --network-interface network=projects/PROJECT_ID/global/networks/NETWORK_NAME

    VM_NAME 替换为虚拟机名称。

  2. 如果系统提示您确认实例的可用区,请键入 y

    创建虚拟机实例后,记下返回的 INTERNAL_IP 地址。

  3. 在 Google Cloud 控制台中,前往虚拟机实例页面。

    进入“虚拟机实例”

  4. 名称列中,点击相应虚拟机实例的名称。

  5. 如果虚拟机正在运行,请点击 停止以停止虚拟机。

  6. 如需修改虚拟机,请点击 修改

  7. 网络 > 防火墙部分中,如需允许 HTTP 或 HTTPS 流量流向虚拟机,请选择允许 HTTP 流量允许 HTTPS 流量

    在此示例中,请选中允许 HTTP 流量复选框。

    Compute Engine 会向您的虚拟机添加一个网络标记,以将防火墙规则与该虚拟机相关联。然后,它会创建相应的入站防火墙规则,该规则允许 tcp:80 (HTTP) 或 tcp:443 (HTTPS) 上的所有传入流量。

  8. 要保存更改,请点击保存

  9. 如需重启虚拟机,请点击启动/恢复

如需了解详情,请参阅创建并启动虚拟机实例

在虚拟机上部署应用

如需测试网络配置并确认流量是否按预期提供,您可以在虚拟机上部署一个监听端口的基本应用。

例如,以下命令会创建一个监听端口 3000 的 Node.js Web 服务。

  1. 与虚拟机实例建立 SSH 连接

  2. 更新您的软件包代码库:

    sudo apt update
  3. 安装 NVMNode.jsnpm

    如需了解详情,请参阅设置 Node.js 开发环境

  4. 以交互方式创建 package.json 文件:

    npm init

    例如:

    {
    "name": "test",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
    "test": "hello"
    },
    "author": "",
    "license": "ISC"
    }
  5. 安装 Express,这是 Node.js 的 Web 应用框架:

    npm install express
  6. 为测试应用编写代码:

    vim app.js

    以下示例创建了一个应用,该应用会以文本“Hello, world!”响应对根路径 (/) 的 GET 请求。

    const express = require('express');
    const app = express();
    
    app.get('/', (req, res) => {
      res.status(200).send('Hello, world!').end();
    });
    
    app.listen(3000, () => {
      console.log('Sample app listening on port 3000.');
    });

    记下应用正在侦听的端口。为 Service Directory 服务配置端点时,必须使用相同的端口号。

  7. 确认应用正在监听端口 3000:

    node app.js

Compute Engine 提供了一系列部署选项。如需了解详情,请参阅为工作负载选择 Compute Engine 部署策略

配置 Service Directory

如需支持从工作流执行中调用专用端点,您必须设置 Service Directory 命名空间、在该命名空间中注册服务,并向该服务添加端点。

例如,以下命令会创建一个命名空间、一项服务和一个端点,用于指定虚拟机实例的 VPC 网络和内部 IP 地址。

  1. 创建命名空间:

    gcloud service-directory namespaces create NAMESPACE \
        --location=REGION

    替换以下内容:

    • NAMESPACE:命名空间的 ID 或命名空间的完全限定标识符。
    • REGION:包含命名空间的 Google Cloud 区域;例如 us-central1
  2. 创建服务:

    gcloud service-directory services create SERVICE \
        --namespace=NAMESPACE \
        --location=REGION

    SERVICE 替换为您要创建的服务的名称。

  3. 配置端点。

    gcloud service-directory endpoints create ENDPOINT \
        --namespace=NAMESPACE \
        --service=SERVICE \
        --network=projects/PROJECT_NUMBER/locations/global/networks/NETWORK_NAME \
        --port=PORT_NUMBER \
        --address=IP_ADDRESS \
        --location=REGION

    替换以下内容:

    • ENDPOINT:您要创建的端点的名称。
    • PORT_NUMBER:端点运行所在的端口;例如 3000
    • IP_ADDRESS:端点的 IPv6 或 IPv4 地址;这是您之前记下的内部 IP 地址。

如需了解详情,请参阅配置 Service Directory配置专用网络访问权限

创建和部署工作流

从 Workflows 调用专用端点是通过 HTTP 请求完成的。最常见的 HTTP 请求方法具有调用快捷方式(例如 http.gethttp.post),但您可以发出任何类型的 HTTP 请求,方法是将 call 字段设置为 http.request 并使用 method 字段指定请求类型。如需了解详情,请参阅发出 HTTP 请求

  1. 为工作流创建源代码文件:

    touch call-private-endpoint.JSON_OR_YAML

    JSON_OR_YAML 替换为 yamljson,具体取决于工作流的格式。

  2. 在文本编辑器中,将以下工作流(在本例中,该工作流使用 HTTP 协议作为 url 值)复制到您的源代码文件中:

    YAML

    main:
      steps:
        - checkHttp:
            call: http.get
            args:
              url: http://IP_ADDRESS
              private_service_name: "projects/PROJECT_ID/locations/REGION/namespaces/NAMESPACE/services/SERVICE"
            result: res
        - ret:
            return: ${res}

    JSON

    {
      "main": {
        "steps": [
          {
            "checkHttp": {
              "call": "http.get",
              "args": {
                "url": "http://IP_ADDRESS",
                "private_service_name": "projects/PROJECT_ID/locations/REGION/namespaces/NAMESPACE/services/SERVICE"
              },
              "result": "res"
            }
          },
          {
            "ret": {
              "return": "${res}"
            }
          }
        ]
      }
    }

    private_service_name 值必须是一个字符串,用于指定已注册的 Service Directory 服务名称,格式如下:

    projects/PROJECT_ID/locations/LOCATION/namespaces/NAMESPACE_NAME/services/SERVICE_NAME

  3. 部署工作流。为了进行测试,您可以将 Compute Engine 默认服务账号附加到工作流以代表其身份:

    gcloud workflows deploy call-private-endpoint \
        --source=call-private-endpoint.JSON_OR_YAML \
        --location=REGION \
        --service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com
  4. 执行工作流:

    gcloud workflows run call-private-endpoint \
        --location=REGION

    您应该会看到类似如下所示的结果:

    argument: 'null'
    duration: 0.650784403s
    endTime: '2023-06-09T18:19:52.570690079Z'
    name: projects/968807934019/locations/us-central1/workflows/call-private-endpoint/executions/4aac88d3-0b54-419b-b364-b6eb973cc932
    result: '{"body":"Hello, world!","code":200,"headers":{"Connection":"keep-alive","Content-Length":"21","Content-Type":"text/html;
    charset=utf-8","Date":"Fri, 09 Jun 2023 18:19:52 GMT","Etag":"W/\"15-NFaeBgdti+9S7zm5kAdSuGJQm6Q\"","Keep-Alive":"timeout=5","X-Powered-By":"Express"}}'
    startTime: '2023-06-09T18:19:51.919905676Z'
    state: SUCCEEDED

后续步骤