使用互联网网络端点组设置外部后端

本文档介绍了如何使用互联网网络端点组 (NEG) 为 Cloud Service Mesh 配置外部后端。互联网 NEG 需要使用完全限定域名。本文档适用于对以下内容具有中高级熟悉程度的用户:

本设置指南为您提供了以下内容的基本说明:

  • 配置 Cloud Service Mesh 以将互联网 NEG 和未经身份验证的 TLS 用于出站流量
  • 将流量从您的服务网格路由到 Cloud Run 服务

准备工作

查看具有互联网网络端点组的 Cloud Service Mesh 概览。

在本指南中,示例配置假定:

  • 所有相关的 Compute Engine 资源(例如中间代理、Cloud Service Mesh 资源、Cloud DNS 区域和混合连接)都连接到默认的 Virtual Private Cloud (VPC) 网络。
  • 服务 example.com:443 在您的本地基础架构中运行。网域 example.com 由三个端点提供服务:10.0.0.10010.0.0.10110.0.0.102。存在可确保从 Envoy 代理连接到这些远程端点的路由。

生成的部署如下所示。

使用互联网 NEG 的示例设置。
使用互联网 NEG 的示例设置(点击可放大)

通过互联网 NEG 和使用 SNI 的 TLS 进行的流量路由

在您为出站流量使用 FQDN 和 TLS 配置使用互联网 NEG 的 Cloud Service Mesh 后,示例部署的行为如下图和流量的说明所示。

示例中的流量路由方式。
示例中的流量路由方式(点击可放大)

以下图例中的步骤与上图中的编号相对应。

步骤 说明
0 Envoy 通过 xDS 从 Cloud Service Mesh 接收 FQDN 后端配置。
0 在虚拟机中运行的 Envoy 不断查询配置的 FQDN 的 DNS。
1 用户应用发起请求。
2 请求的参数。
3 Envoy 代理拦截请求。此示例假定您使用 0.0.0.0 作为转发规则虚拟 IP 地址 (VIP)。当 0.0.0.0 是 VIP 时,Envoy 会拦截所有请求。请求路由仅基于第 7 层参数,而不考虑应用生成的原始请求中的目的地 IP 地址。
4 Envoy 选择健康的远程端点,并向根据客户端 TLS 政策获取的 SNI 执行 TLS 握手。
5 Envoy 将请求代理到远程端点。

它未显示在图中,但如果配置了健康检查,Envoy 就会持续对远程端点执行健康检查并将请求仅路由到健康状况良好的端点。

设置混合连接

本文档还假定已建立混合连接:

  • VPC 网络与本地服务或第三方公有云之间的混合连接是通过 Cloud VPN 或 Cloud Interconnect 建立的。
  • VPC 防火墙规则和路由已正确配置,以建立从 Envoy 到专用服务端点以及(可选)到本地 DNS 服务器的双向可达性。
  • 为了成功实现区域高可用性故障切换场景,启用了全局动态路由。如需了解详情,请参阅动态路由模式

设置 Cloud DNS 配置

使用以下命令为网域 (FQDN) example.com 设置 Cloud DNS 专用区域,其中具有指向 10.0.0.10010.0.0.10110.0.0.10210.0.0.103A 记录。

gcloud

  1. 创建 DNS 代管式专用区域并将其连接到默认网络:
    gcloud dns managed-zones create example-zone \
        --description=test \
        --dns-name=example.com \
        --networks=default \
        --visibility=private
    
  1. 将 DNS 记录添加到专用区域:
    gcloud dns record-sets transaction start \
        --zone=example-zone

    gcloud dns record-sets transaction add 10.0.0.100 10.0.0.101 10.0.0.102 10.0.0.103 \
        --name=example.com \
        --ttl=300 \
        --type=A \
        --zone=example-zone

    gcloud dns record-sets transaction execute \
        --zone=example-zone
    

使用互联网 FQDN NEG 配置 Cloud Service Mesh

在本部分中,您将使用互联网 FQDN NEG 配置 Cloud Service Mesh。

创建 NEG、健康检查和后端服务

gcloud

  1. 创建互联网 NEG:
    gcloud compute network-endpoint-groups create on-prem-service-a-neg \
        --global \
        --network-endpoint-type INTERNET_FQDN_PORT
    
  1. FQDN:Port 端点添加到互联网 NEG:
    gcloud compute network-endpoint-groups update on-prem-service-a-neg \
        --global \
        --add-endpoint=fqdn=example.com,port=443
    
  1. 创建全局健康检查:
    gcloud compute health-checks create http service-a-http-health-check \
        --global
    
  1. 创建名为 on-prem-service-a 的全局后端服务,并将健康检查与其关联:
    gcloud compute backend-services create on-prem-service-a \
        --global \
        --load-balancing-scheme=INTERNAL_SELF_MANAGED \
        --health-checks service-a-http-health-check
    
  1. 将名为 on-prem-service-a-neg 的 NEG 添加为后端服务的后端:
    gcloud compute backend-services add-backend on-prem-service-a \
        --global \
        --global-network-endpoint-group \
        --network-endpoint-group on-prem-service-a-neg
    

创建路由规则映射

网址映射、目标 HTTP 代理和转发规则构成路由规则映射,以便为网格中的流量提供路由信息。

此网址映射包含一条规则,规定将所有 HTTP 流量路由到 on-prem-service-a

gcloud

  1. 创建网址映射:
    gcloud compute url-maps create td-url-map \
        --default-service on-prem-service-a
    
  1. 创建目标 HTTP 代理并将网址映射与目标代理关联:
    gcloud compute target-http-proxies create td-proxy \
        --url-map td-url-map
    
  1. 使用 IP 地址 0.0.0.0 创建全局转发规则。这是一个特殊的 IP 地址,会导致数据平面忽略目标 IP 地址并仅根据请求的 HTTP 参数路由请求。
    gcloud compute forwarding-rules create td-forwarding-rule \
        --global \
        --load-balancing-scheme=INTERNAL_SELF_MANAGED \
        --address=0.0.0.0 \
        --target-http-proxy=td-proxy \
        --ports=443 \
        --network=default
    

配置未经身份验证的 TLS 和 HTTPS

(可选)如果要在 Envoy 代理和本地服务之间配置未经身份验证的 HTTPS,请按照以下说明操作。这些说明还演示了如何在 TLS 握手中配置 SNI。

客户端 TLS 政策指定客户端向特定服务发送出站请求时的客户端身份和身份验证机制。使用 securitySettings 字段将客户端 TLS 政策连接到后端服务资源。

gcloud

  1. 创建并导入客户端 TLS 政策;将 SNI 设置为您在 NEG 中配置的 FQDN:
    cat << EOF > client_unauthenticated_tls_policy.yaml
    name: "client_unauthenticated_tls_policy"
    sni: "example.com"
    EOF

    gcloud beta network-security client-tls-policies import client_unauthenticated_tls_policy \
        --source=client_unauthenticated_tls_policy.yaml \
        --location=global
    
  1. 如果您已在上一部分中使用后端服务配置 HTTP 健康检查,请从后端服务中分离健康检查:
    gcloud compute backend-services update on-prem-service-a \
        --global \
        --no-health-checks
    
  1. 创建 HTTPS 健康检查:
    gcloud compute health-checks create https service-a-https-health-check \
        --global
    
  1. 将客户端 TLS 政策连接到您之前创建的后端服务:这将对从客户端到此后端服务的所有出站请求强制执行未经身份验证的 HTTPS:
    gcloud compute backend-services export on-prem-service-a \
        --global \
        --destination=on-prem-service-a.yaml

    cat << EOF >> on-prem-service-a.yaml
    securitySettings:
      clientTlsPolicy: projects/${PROJECT_ID}/locations/global/clientTlsPolicies/client_unauthenticated_tls_policy
    healthChecks:
      - projects/${PROJECT_ID}/global/healthChecks/service-a-https-health-check
    EOF

    gcloud compute backend-services import on-prem-service-a \
        --global \
        --source=on-prem-service-a.yaml
    

您可以使用互联网 FQDN NEG 将流量路由到可通过 FQDN 访问的任何服务,例如,DNS 可解析的外部服务和内部服务或者 Cloud Run 服务。

IP:Port NEG 迁移到 FQDN:Port NEG

NON_GCP_PRIVATE_IP_PORT NEG 要求您将服务端点作为静态 IP:PORT 对编程到 NEG 中,而 INTERNET_FQDN_NEG 允许使用 DNS 动态地解析端点。您可以按照以下步骤为本地服务端点设置 DNS 记录并配置 Cloud Service Mesh,以迁移到互联网 NEG:

  1. 为您的 FQDN 设置 DNS 记录。
  2. 使用 FQDN 创建新的互联网 NEG。
  3. 使用您在第 2 步中创建的互联网 NEG 作为后端来创建新的后端服务。将您在混合连接 NEG 后端服务中使用的健康检查与新后端服务相关联。验证新的远程端点是否运行状况良好。
  4. 通过替换包含混合连接 NEG 的旧后端,更新路由规则映射以引用新的后端服务。
  5. 如果您希望在生产部署中的实时迁移期间不发生任何停机,可以使用基于权重的流量。最初,配置新的后端服务以仅接收一小部分流量(例如 5%)。按照设置流量拆分的说明进行操作。
    1. 验证新的远程端点能否正确处理流量。
  6. 如果您使用基于权重的流量拆分,请配置新的后端服务以接收 100% 的流量。此步骤会排空旧后端服务。
  7. 验证新的后端在处理流量时没有出现任何问题,然后删除旧的后端服务。

问题排查

要解决部署问题,请按照本部分中的说明操作。如果利用此信息无法解决您的问题,请参阅排查使用 Envoy 的部署的问题

本地端点未收到流量

如果端点未收到流量,请确保该端点通过了健康检查,并且来自 Envoy 客户端的 DNS 查询始终返回其 IP 地址。

Envoy 使用 strict_dns 模式来管理连接。它可以在所有运行状况良好的已解析端点之间平衡流量。在 strict_dns 模式下,端点的解析顺序无关紧要,但 Envoy 会排空发送到返回的 IP 地址列表中不再存在的任何端点的流量。

当请求到达本地服务器时,HTTP 主机标头与 FQDN 不匹配

请考虑一个示例,其中网域 example.com 解析为 10.0.0.1(转发规则的 IP 地址),网域 altostrat.com 解析为 10.0.0.100(您的本地服务端点)。您希望将流量发送到在 NEG 中配置的 altostrat.com 网域。

Compute Engine 或 GKE 中的应用可能会将 HTTP Host 标头设置为 example.com (Host: example.com),其会被转发到本地端点。如果您使用的是 HTTPS,Envoy 会在 TLS 握手期间将 SNI 设置为 altostrat.com。Envoy 从客户端 TLS 政策资源获取 SNI。

如果此冲突导致在处理或路由到达本地端点的请求时出现问题,则一种解决方法是将 Host 标头重新写入到 altostrat.com (Host: altostrat.com)。这可以通过使用网址重写在 Cloud Service Mesh 中或在具有标头重写功能的远程端点上完成。

另一个更简单的解决方法是将 Host 标头设置为 altostrat.com (Host: altostrat.com),并使用特殊地址 0.0.0.0 作为转发规则的 IP 地址。

Envoy 返回许多 5xx 错误

如果 Envy 返回过多的 5xx 错误,请执行以下操作:

  • 检查 Envoy 日志以区分响应是否来自后端(本地后端),以及出现 5xx 错误的原因。
  • 确保 DNS 查询成功,且没有 SERVFAILNXDOMAIN 错误。
  • 确保所有远程端点均已通过健康检查。
  • 如果未配置健康检查,请确保可以从 Envoy 访问所有端点。检查 Google Cloud 端和本地端的防火墙规则和路由。

无法通过公共互联网从服务网格访问外部服务

您可以使用 Cloud Service Mesh 中的 FQDN 后端将流量发送到位于公共互联网上的服务。您必须首先在 Envoy 客户端和外部服务之间建立互联网连接。如果您在连接到外部服务期间收到 502 错误,请执行以下操作:

  • 确保您配置了正确的路由(尤其是默认路由 0.0.0.0/0)和防火墙规则。
  • 确保 DNS 查询成功,且没有 SERVFAILNXDOMAIN 错误。
  • 如果 Envoy 代理在没有外部 IP 地址的 Compute Engine 虚拟机上运行,或者在专用 GKE 集群中运行,您需要配置 Cloud NAT 或其他方式以建立出站互联网连接。

如果错误仍然存在或出现其他 5xx 错误,请检查 Envoy 日志以缩小错误来源的范围。

无法从服务网格访问无服务器服务

您可以使用 Cloud Service Mesh 中的 FQDN 后端将流量发送到无服务器(Cloud Run、Cloud Run 函数和 App Engine)服务。如果 Envoy 代理在没有外部 IP 地址的 Compute Engine 虚拟机上运行,或者在专用 GKE 集群中运行,您需要在子网上配置专用 Google 访问通道才能访问 Google API 和服务。

后续步骤